zeurx
asked on
BMP from dll to file
can someone tell me how i can get a bmp resource from the dll to the drive. This is for a desktop changer with a set of wallpapers included in the dll and the ability to select one from the disk. so all i need is a way to get bmp from dll to disk ex.c:\wallpaper.bmp
Open the DLL in Visual Studio as a resource. You can then export the bitmaps in the DLL.
1. Use FindResource or FindResourceEx to get a handle to that bitmap resource.
2. Use LoadResource to load it into memory as it is stored in the file.
3. Use LockResource to get a pointer to that memory block.
4. Write the memory block to file. You have two small things to keep in mind:
a.) Write 'B' and 'M' as the two first bytes of the file; these are the Windows Bitmap file signatures but aren't stored in the resource.
b.) The first 4 bytes of the memory block give you the size of the resource. These 4 bytes aren't to be written into the file.
2. Use LoadResource to load it into memory as it is stored in the file.
3. Use LockResource to get a pointer to that memory block.
4. Write the memory block to file. You have two small things to keep in mind:
a.) Write 'B' and 'M' as the two first bytes of the file; these are the Windows Bitmap file signatures but aren't stored in the resource.
b.) The first 4 bytes of the memory block give you the size of the resource. These 4 bytes aren't to be written into the file.
ASKER
on step 4, could u explane that somemore
a.) If you look into a .BMP file, the first two bytes are 'B' and 'M'. If you look into the bitmap resource, these two bytes are missing. So if you want to create a valid .BMP file, you have to write these two bytes yourself.
b.) If you look into the bitmap resource (to the memory pointed by the value you get from LockResource), the first 4 bytes are the size of the bitmap resource. You don't have to write these 4 bytes to the file, because .BMP files don't have this value. But this size value should be used for how many bytes do you have to write to the file.
char* bmpResource = LockResource (...)
DWORD size = 0;
memcpy (&size, bmpResource, sizeof (DWORD));
WriteToFile ("BM", 2);
WriteToFile (bmpResource + sizeof (DWORD)), size);
b.) If you look into the bitmap resource (to the memory pointed by the value you get from LockResource), the first 4 bytes are the size of the bitmap resource. You don't have to write these 4 bytes to the file, because .BMP files don't have this value. But this size value should be used for how many bytes do you have to write to the file.
char* bmpResource = LockResource (...)
DWORD size = 0;
memcpy (&size, bmpResource, sizeof (DWORD));
WriteToFile ("BM", 2);
WriteToFile (bmpResource + sizeof (DWORD)), size);
ASKER
would WriteToFile be the same as WriteFile or do i need to add a include?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
// Set File //
TCHAR WinDir[INFO_BUFFER_SIZE];
GetWindowsDirectory(WinDir ,sizeof(Wi nDir));
CString Wallpaper; Wallpaper.Format("%s",WinD ir);
CString sHeight; sHeight.Format("%i",height ); CString sWidth; sWidth.Format("%i",width);
Wallpaper += "\\Shadower-"+sWidth+"x"+s Height+".b mp";
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,lpFil e,RT_BITMA P);
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_CURREN T_USER);
Reg.SetKey("Control Panel\\Desktop",0);
Reg.WriteString("Wallpaper ",Wallpape r);
Reg.WriteString("Wallpaper Style","2" );
SystemParametersInfo(SPI_S ETDESKWALL PAPER,0,NU LL,SPIF_SE NDCHANGE|S PIF_UPDATE INIFILE);
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,1 024);
i get an error and when i go to debug it it shoots me the the .extract part. anyhelp
TCHAR WinDir[INFO_BUFFER_SIZE];
GetWindowsDirectory(WinDir
CString Wallpaper; Wallpaper.Format("%s",WinD
CString sHeight; sHeight.Format("%i",height
Wallpaper += "\\Shadower-"+sWidth+"x"+s
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
HRSRC hRes = FindResource(hModule,lpFil
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_CURREN
Reg.SetKey("Control Panel\\Desktop",0);
Reg.WriteString("Wallpaper
Reg.WriteString("Wallpaper
SystemParametersInfo(SPI_S
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,1
i get an error and when i go to debug it it shoots me the the .extract part. anyhelp
Which line gives you the error? And if you debug step-by-step, what's the result of each line? If anything fails, what's the GetLastError() value after the failure? Etc.
Btw, you should write WriteFile(hFile, bmpResource + sizeof(DWORD), Size, &written, NULL); instead.
And I think you can use LoadLibraryEx function with the LOAD_LIBRARY_AS_DATAFILE flag. It prevents the DLL from running it's startup code.
Btw, you should write WriteFile(hFile, bmpResource + sizeof(DWORD), Size, &written, NULL); instead.
And I think you can use LoadLibraryEx function with the LOAD_LIBRARY_AS_DATAFILE flag. It prevents the DLL from running it's startup code.
ASKER
NULL,LOAD_LIBRARY_AS_DATAF ILE give me an error C2036: 'LPVOID" : unknown size
ASKER
ok i found my real prob.
when i go to get the width of what file they want ex. 1024x768 it dosent add SHADOWBG_ in front of the 1024
LPTSTR lpsz = new TCHAR[size.GetLength()+1];
_tcscpy(lpsz, size);
LPCTSTR lpFile; lpFile = "SHADOWBG_"; lpFile =+ lpsz;
it will not add just override
when i go to get the width of what file they want ex. 1024x768 it dosent add SHADOWBG_ in front of the 1024
LPTSTR lpsz = new TCHAR[size.GetLength()+1];
_tcscpy(lpsz, size);
LPCTSTR lpFile; lpFile = "SHADOWBG_"; lpFile =+ lpsz;
it will not add just override
ASKER
ok i got it to get the LPCTSTR to get right now but when i copy to memory i get a error that kills the program.
LPVOID bmpResource = LockResource(hResLoad);
...
memcpy (&Size, bmpResource, sizeof (DWORD));
and i get the error
Just-In-Time Debugging
-------------------------- ---------- ---------- ---------- -
An exception 'System.NullReferenceExcep tion' has occurred in
Shadower.exe.
LPVOID bmpResource = LockResource(hResLoad);
...
memcpy (&Size, bmpResource, sizeof (DWORD));
and i get the error
Just-In-Time Debugging
--------------------------
An exception 'System.NullReferenceExcep
Shadower.exe.
ASKER
ok that all works now... just had to set memcpy's last arr to 0
but i cant open the file,
-------------------------- -
Paint
-------------------------- -
A sharing violation occurred while accessing E:\windows\Shadower-1024x7 68.bmp.
-------------------------- -
OK
-------------------------- -
is what i get when i try to open it in paint.
// Save to Bmp //
DWORD Size = 0;
memcpy (&Size, bmpResource, 0);
DWORD written = 0;
LPSTR Wall = (char *) (LPCTSTR) Wallpaper;
HANDLE hFile = CreateFile(Wall,
GENERIC_WRITE,// | GENERIC_READ,
0,//FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_READONLY,
NULL);
WriteFile(hFile, "BM", 2, &written, NULL);
WriteFile(hFile, bmpResource, Size, &written, NULL);
is my code
but i cant open the file,
--------------------------
Paint
--------------------------
A sharing violation occurred while accessing E:\windows\Shadower-1024x7
--------------------------
OK
--------------------------
is what i get when i try to open it in paint.
// Save to Bmp //
DWORD Size = 0;
memcpy (&Size, bmpResource, 0);
DWORD written = 0;
LPSTR Wall = (char *) (LPCTSTR) Wallpaper;
HANDLE hFile = CreateFile(Wall,
GENERIC_WRITE,// | GENERIC_READ,
0,//FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_READONLY,
NULL);
WriteFile(hFile, "BM", 2, &written, NULL);
WriteFile(hFile, bmpResource, Size, &written, NULL);
is my code
Well, the purpose of using a debugger is not only showing you which line crashes. You can check values of variables, too. In your case "bmpResource" seems to be NULL (as I thought you will take care of error checking). Now if you try to copy anything from NULL, it will crash.
And just think a little about setting memcpy's last parameter to zero. Now you copy zero bytes, e.g., nothing. Now how would "size" get initialized?
Now, for the heaven's sake, please use the "Step" and "Watch" functions of your debugger and check all the returned values beginning from FindResource. If any of the resource functions return NULL, modify your code so that you call GetLastError () after it and check the returned value.
And just think a little about setting memcpy's last parameter to zero. Now you copy zero bytes, e.g., nothing. Now how would "size" get initialized?
Now, for the heaven's sake, please use the "Step" and "Watch" functions of your debugger and check all the returned values beginning from FindResource. If any of the resource functions return NULL, modify your code so that you call GetLastError () after it and check the returned value.