?
Solved

Export a resource

Posted on 2004-03-31
18
Medium Priority
?
283 Views
Last Modified: 2013-11-20
i have been trying to export a resource to a file for the past few weeks. When i try to run the exporting code in my dll it can not get the resource and returns a NULL error.

resource = bmp
bmp for wallpaper

<code>
    // Set File //
     
     TCHAR WinDir[INFO_BUFFER_SIZE];
     GetWindowsDirectory(WinDir,sizeof(WinDir));
     CString Wallpaper; Wallpaper.Format("%s",WinDir);
     CString sHeight; sHeight.Format("%i",height); CString sWidth; sWidth.Format("%i",width);
     Wallpaper += "\\Shadower-"+sWidth+"x"+sHeight+".bmp";
     AfxMessageBox(Wallpaper);
     // Get Resource //
     HMODULE hModule = LoadLibrary("Shadower.dll");
     CString size; size.Format("%i",width);
     LPCTSTR lpFile; lpFile = "SHADOWBG_"; lpFile =+ (char *) (LPCTSTR) size;
     AfxMessageBox(lpFile,MB_OK,NULL);
     HRSRC hRes = FindResource(hModule,lpFile,RT_BITMAP);
     HGLOBAL hResLoad = LoadResource(hModule,hRes);
     LPVOID bmpResource = LockResource(hResLoad);
     // Save to Bmp //
     DWORD Size = 0;
     memcpy (&Size, bmpResource, sizeof (DWORD));
     DWORD written = 0;
     LPSTR Wall = (char *) (LPCTSTR) Wallpaper;
     HANDLE hFile = CreateFile(Wall,
                                        GENERIC_WRITE,
                                        FILE_SHARE_READ,
                                        NULL,
                                        CREATE_ALWAYS,
                                        FILE_ATTRIBUTE_READONLY,
                                        NULL);
     WriteFile(hFile, "BM", 2, &written, NULL);
     WriteFile(hFile, bmpResource, Size, &written, NULL);
     UnlockResource(hResLoad);
     FreeLibrary(hModule);
     // Set Wallpaper //
     Reg.SetRootKey(HKEY_CURRENT_USER);
     Reg.SetKey("Control Panel\\Desktop",0);
     Reg.WriteString("Wallpaper",Wallpaper);
     Reg.WriteString("WallpaperStyle","2");
     SystemParametersInfo(SPI_SETDESKWALLPAPER,0,NULL,SPIF_SENDCHANGE|SPIF_UPDATEINIFILE);
when i run this code i get an error...
this is what i use to get to this function...
#include "..\dll\Wallpaper.h"
          CWallpaper Wallpaper;
          Wallpaper.ExtractBMP(768,1024);
</code>

Could someone look through this code and tell me what might be going wrong.
the resource name im trying to get is "SHADOWBG_1024" and i would like to make the numbers in that change with the screen size, i have the code for that thow.
0
Comment
Question by:zeurx
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 5
  • 4
18 Comments
 
LVL 16

Expert Comment

by:nonubik
ID: 10724294
Hi zerux,

You need to allocate the lpFile
Instead of
> LPCTSTR lpFile; lpFile = "SHADOWBG_"; lpFile =+ (char *) (LPCTSTR) size;
try
  char lpFile[MAX_PATH] = "SHADOWBG_"; lstrcat(lpFile, size.GetBuffer());

Where do you get the error?  hRes is NULL?
0
 
LVL 16

Expert Comment

by:nonubik
ID: 10724304
sorry, I misspelled yor nick, it's zeurx. my appologies
0
 

Author Comment

by:zeurx
ID: 10728318
i get the error in the CreateFile part
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:zeurx
ID: 10728322
and in Dissasembly
100062BB  mov         ebx,dword ptr [edi]
0
 
LVL 16

Expert Comment

by:nonubik
ID: 10730216
You said
>When i try to run the exporting code in my dll it can not get the resource and returns a NULL error.
and
>i get the error in the CreateFile part.
I don't get it. Who retunrs NULL? As long as I know CreateFile returns INVALID_HANDLE_VALUE (-1) on error. Do you have an access violation exception? Please give more details, some variable values during your error...
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 10730353
hm ... didn't test it yet, but maybe it's not possible to create a file as 'read-only' for 'write' access ...

IMO you should set the file to 'read-only' after you have written it ...

ZOPPO
0
 
LVL 16

Expert Comment

by:nonubik
ID: 10730383
Zoppo, it is possible. I've tested ;)
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 10730412
ok ... thanks :o)

ZOPPO
0
 

Author Comment

by:zeurx
ID: 10736477
ok i have changed my code to the following...

        // Set File //
      TCHAR WinDir[INFO_BUFFER_SIZE];
      GetWindowsDirectory(WinDir,sizeof(WinDir));
      CString Wallpaper; Wallpaper.Format("%s",WinDir);
      CString sHeight; sHeight.Format("%i",height); CString sWidth; sWidth.Format("%i",width);
      Wallpaper += "\\Shadower-"+sWidth+"x"+sHeight+".bmp";
      // Get Resource //
      HMODULE hModule = LoadLibraryEx("Shadower.dll",NULL,LOAD_LIBRARY_AS_DATAFILE);
      CString size; size.Format("%i",width);
      char lpFile[MAX_PATH] = "SHADOWBG_"; lstrcat(lpFile, size.GetBuffer());
      HRSRC hRes = FindResource(hModule,lpFile,RT_BITMAP);
      HGLOBAL hResLoad = LoadResource(hModule,hRes);
      LPVOID bmpResource = LockResource(hResLoad);
      // Save to Bmp //
      DWORD Size = *(DWORD *)bmpResource;
      DWORD written = 0;
      LPSTR Wall = (char *) (LPCTSTR) _T(Wallpaper);
      DeleteFile(Wallpaper);
      HANDLE hFile = CreateFile(Wall,
                                                GENERIC_WRITE,// | GENERIC_READ,
                                                FILE_SHARE_WRITE,//FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                                                NULL,
                                                CREATE_ALWAYS,
                                                FILE_ATTRIBUTE_NORMAL,
                                                NULL);
//      WriteFile(hFile, "BM", 2, &written, NULL);
      WriteFile(hFile, bmpResource, Size, &written, NULL);

      UnlockResource(hResLoad);
      FreeLibrary(hModule);
      WinExec("mspaint "+Wallpaper,SW_SHOW);
      // Set Wallpaper //
/*      Reg.SetRootKey(HKEY_CURRENT_USER);
      Reg.SetKey("Control Panel\\Desktop",0);
      Reg.WriteString("Wallpaper",Wallpaper);
      Reg.WriteString("WallpaperStyle","2");
      SystemParametersInfo(SPI_SETDESKWALLPAPER,0,NULL,SPIF_SENDCHANGE|SPIF_UPDATEINIFILE);*/

In this i delete a file (i might add code to is if the file exsits and delete if it does and i get the following error...

      DeleteFile(Wallpaper);

Unhandled exception at 0x100062b2 (Shadower.dll) in Shadower.exe: 0xC0000005: Access violation reading location 0x00000000.

and if i comment the line out i get...

      HANDLE hFile = CreateFile(Wall,
                                                GENERIC_WRITE,// | GENERIC_READ,
                                                FILE_SHARE_WRITE,//FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                                                NULL,
                                                CREATE_ALWAYS,
                                                FILE_ATTRIBUTE_NORMAL,
                                                NULL);

Unhandled exception at 0x100062bf (Shadower.dll) in Shadower.exe: 0xC0000005: Access violation reading location 0x00000000.

note the parts comment out!

it does not create a file at all.
0
 

Author Comment

by:zeurx
ID: 10736644
     LPVOID Text = _T("Test");
      DWORD Size = 4;
      DWORD written = 0;
      LPSTR File = _T("C:\\Test.file.txt");
      DeleteFile(File);
      HANDLE hFile = CreateFile(File,
                                                GENERIC_WRITE,// | GENERIC_READ,
                                                FILE_SHARE_WRITE,//FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                                                NULL,
                                                CREATE_ALWAYS,
                                                FILE_ATTRIBUTE_NORMAL,
                                                NULL);
      WriteFile(hFile, Text, Size, &written, NULL);
      CloseHandle(hFile);

This is a demo program that shows one part of shadower and this is to write test to the file c:\test.file.txt and IT WORKS!!! why dosent the other one write/create anything?
0
 

Author Comment

by:zeurx
ID: 10737479
Update:
      I can not find the resource/bmp with this code... anyone know why
0
 

Author Comment

by:zeurx
ID: 10737484
     // Get Resource //
      HMODULE hModule = LoadLibraryEx("Shadower.dll",NULL,LOAD_LIBRARY_AS_DATAFILE);
      CString size; size.Format("%i",width);
      char lpFile[MAX_PATH] = "SHADOWBG_"; lstrcat(lpFile, size.GetBuffer());
      HRSRC hRes = FindResource(hModule,"SHADOWBG_1024",RT_BITMAP);
      if (hRes == NULL)
            AfxMessageBox("Bitmap not found");
      HGLOBAL hResLoad = LoadResource(hModule,hRes);
      if (hResLoad == NULL)
            AfxMessageBox("Bitmap not loaded");
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 10755268
Hi again,

excuse me, but I think you should at first clean up a little bit of your code...

i.e. the lines
>     CString Wallpaper; Wallpaper.Format("%s",WinDir);
>     CString sHeight; sHeight.Format("%i",height); CString sWidth; sWidth.Format("%i",width);
>     Wallpaper += "\\Shadower-"+sWidth+"x"+sHeight+".bmp";
can easily be written as i.e.
>     CString Wallpaper;
>     Wallpaper.Format( "%s\\Shadower-%ix%i.bmp", WinDir, width, height );

lines:
 >    CString size; size.Format("%i",width);
 >    char lpFile[MAX_PATH] = "SHADOWBG_"; lstrcat(lpFile, size.GetBuffer());
could be written i.e. as
>     CString sName;
>     sName.Format( "SHADOWBG_%i", width );
 
those mixing up of 'CString's and 'char*' functions can lead to problems and aren't good to read


Further a problem IMO is that most unlikely the name of the resource is really something like
'SHADOWBG_1024' ... I guess that's the resource ID of the resource in the .dll, but the resource
ID is not a name. In the .dll's 'resource.h' file you'll find a '#define SHADOWBG_1024 <xyz>' where
<xyz> is a hex number ... this number is what you'll have to specify in FindResource to find the
resource.

In addition I'd suggest you to do a bit more checking on the return values, i.e. code like this
>     ...
>     HMODULE hModule = LoadLibraryEx("Shadower.dll",NULL,LOAD_LIBRARY_AS_DATAFILE);
>     ...
>     HRSRC hRes = FindResource(hModule,lpFile,RT_BITMAP);
>     HGLOBAL hResLoad = LoadResource(hModule,hRes);
>     LPVOID bmpResource = LockResource(hResLoad);
>     ...
would make me nervous ;o)

ZOPPO
0
 

Author Comment

by:zeurx
ID: 10761371
(MFC)
in HRSRC hRes = FindResource(hModule,sName,RT_BITMAP);
(ASM)
100075F3  call        dword ptr [__imp__FindResourceA@12 (10021254h)]
100075F9  mov         dword ptr [hRes],eax

reutrns eax = 00000000

than it calls the messagebox

any ideas or do i need to dig deeper and if so any seguestions on how to dig
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 10763411
Did you try to use the resource ID's number instead of the name?

I really guess that's the problem here ...

Search in the resource.h file of the shadower.dll for the ID 'SHADOWBG_1024'.

Use the number defined for this ID as sName as described in MSDN about FindResource ...

ZOPPO
0
 

Author Comment

by:zeurx
ID: 10768475
yes its "#30002" and then it writes the file but writes the wrong stuff and i do not know where it gets the stuff from now.

HRSRC hRes = FindResource("Shadower.dll","#3002",RT_BITMAP);

I also wonder if i can just save the bitmap because this code is in shadower and is very poor writen to call a resource that i sould be able to get another way that would be more efficent.  If you know how to open a bmp and save it that would also help.  I think that the code below should work but i have no access to vs right now so just of the top of my head.

BITMAP hRes; hRes.LoadBitmap(sName); hRes.SaveBitmap(Wallpaper);

would this code work or not... would this method work or not
0
 

Author Comment

by:zeurx
ID: 10771087
ok i have finaly got time to work on it and this is what i come up with.

1.
      // Set File //
      TCHAR WinDir[INFO_BUFFER_SIZE];
      GetWindowsDirectory(WinDir,sizeof(WinDir));
      CString Wallpaper;
      Wallpaper.Format("%s\\Shadower-%ix%i.bmp", WinDir, width, height);
      // Get Resource //
      CString sName;
      sName.Format("SHADOWBG_%i",width);
      CBitmap hRes;
      hRes.LoadBitmap(sName);
      HBITMAP hBmp;
      hBmp = hRes.operator HBITMAP();
      CImage hImg;
      hImg.Attach(hBmp);
      // Save Bitmap //
      DeleteFile(Wallpaper);
      HANDLE hFile = CreateFile(Wallpaper,
                                                GENERIC_WRITE,
                                                FILE_SHARE_WRITE,
                                                NULL,
                                                CREATE_ALWAYS,
                                                FILE_ATTRIBUTE_NORMAL,
                                                NULL);
      CloseHandle(hFile);
      hImg.Save(Wallpaper);
      hImg.Detach();

2.
      // Set File //
      
      TCHAR WinDir[INFO_BUFFER_SIZE];
      GetWindowsDirectory(WinDir,sizeof(WinDir));
      CString Wallpaper;
      Wallpaper.Format("%s\\Shadower-%ix%i.bmp", WinDir, width, height);
      // Get Resource //
      CString sName;
      sName.Format("SHADOWBG_%i",width);
      CBitmap hRes;
      hRes.LoadBitmap(sName);
      HBITMAP hBmp;
      hBmp = hRes.operator HBITMAP();
      CImage hImg;
      hImg.Attach(hBmp);
      // Save Bitmap //
      hImg.Save(Wallpaper);
      hImg.Detach();

but with this code it dosent load or save. dont know what, the bitmap because the file is 0kb
0
 
LVL 31

Accepted Solution

by:
Zoppo earned 135 total points
ID: 10772221
ok, I think the bitmap is empty ... the function CBitmap::LoadBitmap can be used to
either load a bitmap from a file (given a filename) or from resource from modul which
is actually set to load resources from.

Now, there I think are two ways:

1. Use LoadImage instead of LoadImage ... with this you can specify the module from
which the bitmap should be loaded

2. Set the current used resource handle to the HMODULE returned by LoadLibrary, load
the image with CBitmap::LoadBitmap() [here you really can pass the resource ID as
numeric value], and reset the resource handle (very important!).

To set the resource handle used you can use AfxSetResourceHandle(), i.e.

...
     HMODULE hModule = LoadLibraryEx("Shadower.dll",NULL,LOAD_LIBRARY_AS_DATAFILE);
     if ( NULL == hModule )
      return FALSE;
 
     HINSTANCE hPrevResourceHandle = AfxGetResourceHandle();
     AfxSetResourceHandle( (HINSTANCE)hModule );

     CBitmap bmp;
     BOOL bLoaded = bmp.LoadBitmap( 30002 );

     // you should reset the previous handle immediateley
     AfxSetResourceHandle( hPrevResourceHandle );

     if ( FALSE == bLoaded )
     {
       // do error handling here ...
       return FALSE;
     }

     // save bitmap here ...
...


ZOPPO
0

Featured Post

Learn how to optimize MySQL for your business need

With the increasing importance of apps & networks in both business & personal interconnections, perfor. has become one of the key metrics of successful communication. This ebook is a hands-on business-case-driven guide to understanding MySQL query parameter tuning & database perf

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…

718 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question