Solved

Export a resource

Posted on 2004-03-31
18
278 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
  • 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
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 

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 45 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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
MFC Dialog 9 51
VB.NET how to use the Vertical ScrollBar 5 114
firstChar challenge 13 121
Message not shown 5 67
This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
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.

821 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