Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 285
  • Last Modified:

Export a resource

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
zeurx
Asked:
zeurx
  • 9
  • 5
  • 4
1 Solution
 
nonubikCommented:
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
 
nonubikCommented:
sorry, I misspelled yor nick, it's zeurx. my appologies
0
 
zeurxAuthor Commented:
i get the error in the CreateFile part
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
zeurxAuthor Commented:
and in Dissasembly
100062BB  mov         ebx,dword ptr [edi]
0
 
nonubikCommented:
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
 
ZoppoCommented:
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
 
nonubikCommented:
Zoppo, it is possible. I've tested ;)
0
 
ZoppoCommented:
ok ... thanks :o)

ZOPPO
0
 
zeurxAuthor Commented:
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
 
zeurxAuthor Commented:
     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
 
zeurxAuthor Commented:
Update:
      I can not find the resource/bmp with this code... anyone know why
0
 
zeurxAuthor Commented:
     // 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
 
ZoppoCommented:
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
 
zeurxAuthor Commented:
(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
 
ZoppoCommented:
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
 
zeurxAuthor Commented:
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
 
zeurxAuthor Commented:
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
 
ZoppoCommented:
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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 9
  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now