Benutzer mit den meisten Antworten
Bitmap Ressource als Hintergrundbild verwenden

Frage
-
Hallo,
ich hab ein kleines Problem bei folgendem Programm:
#include "stdafx.h"
#include <windows.h>
#include "resource.h"int _tmain(int argc, _TCHAR* argv[])
{
SystemParametersInfo(SPI_SETDESKWALLPAPER,0,MAKEINTRESOURCE(IDB_BITMAP1),SPIF_SENDCHANGE|SPIF_UPDATEINIFILE);
return 0;
}
Wenn ich diesen Code erhalte immer die Fehlermeldung:
Unbehandelte Ausnahme bei 0x7c9112b0 in hintergundbildrecoursse.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000065.
Die Fehlermeldung habe ich auch nochmal als Bild hochgeladen.
http://img66.imageshack.us/img66/7802/hintergrundbild.jpg
Bin für jede Hilfe dankbar.- Bearbeitet camelion3 Sonntag, 3. Mai 2009 20:46
Antworten
-
Hallo!
Das Problem ist das verwendete Argument MAKEINTRESOURCE(IDB_BITMAP1). Wenn als erster Parameter SPI_SETDESKWALLPAPER verwendet wird, dann interpretiert der SPI Aufruf das Argument als Pointer auf einen String. Der vom Makro MAKEINTRESOURCE zurueck gelieferte Wert zeigt als Pointer interpretiert mit Sicherheit ins Nirvana. Also am besten so:
SystemParametersInfo(SPI_SETDESKWALLPAPER,0,(LPVOID)"c:\\DWP.bmp",SPIF_SENDCHANGE|SPIF_UPDATEINIFILE);
oder so aehnlich.
- Als Antwort markiert Mathias Schiffer Samstag, 9. Mai 2009 06:09
-
Hallo camelion3,
das Basisproblem ist, dass sich die Funktion SystemParametersInfo bereits existiert und senerzeit nicht so programmiert wurde, wie Du es Dir heute wünschst. Du wirst dich also beim direkten Aufruf der Funktion schon noch an das halten müssen, was verfügbar ist und überdies die Aufrufkonventionen einhalten müssen:
SystemParametersInfo Function
http://msdn.microsoft.com/en-us/library/ms724947.aspx
Zum gesuchten Parameter SPI_SETDESKWALLPAPER steht da:
"To specify a wallpaper bitmap, set pvParam to point to a NULL-terminated string containing the full path to the bitmap file. Setting pvParam to "" removes the wallpaper. Setting pvParam to SETWALLPAPER_DEFAULT or NULL reverts to the default wallpaper."
Natürlich kannst Du eine Wrapper-Funktion schreiben, die Parameter nach Deinen Wünschen entgegen nimt. Wenn Du aber SystemParametersInfo aufrufen willst (z. B. auch in Deinem Wrapper), musst Du Dich an das halten, was die Funktion Dir anbietet.- Als Antwort markiert Mathias Schiffer Samstag, 9. Mai 2009 06:09
-
Hi!
Also ich habe mal ein bisschen in den üblichen Foren gestöbert und eine Funktion gefunden, die ein Bitmap speichert. Leider stecke ich jetzt auch fest, weil die Funktion ::LoadBitmap nicht funktioniert. GetLastError liefert invalide 1812 zurück, d. h. so viel wie "The specified image file did not contain a resource section.". Irgendjemand ne Idee? Hier ist mein SourceCode snippet:
#include "stdafx.h" #include <windows.h> #include "resource.h" #include <fstream> HINSTANCE hinst; BOOL SaveBitmap(HDC,HBITMAP,char*); int _tmain(int argc, _TCHAR* argv[]) { HBITMAP hBitmap; HWND hwndC = GetConsoleWindow() ; hinst = (HINSTANCE)GetWindowLong( hwndC, GWL_HINSTANCE ); hBitmap = ::LoadBitmap(hinst, MAKEINTRESOURCE(IDB_BITMAP1)); if(hBitmap == NULL) { wchar_t strOutput[1024]; DWORD dwLastError = ::GetLastError(); swprintf(strOutput, L"Can't obtain Bitmap Handle, last error was %d\n", dwLastError); OutputDebugString(strOutput); return 1; } HWND hWnd = ::GetDesktopWindow(); HDC hDtwDC = ::GetDC(hWnd); HDC hCompatibleDC = ::CreateCompatibleDC(hDtwDC); ::SaveBitmap(hCompatibleDC, hBitmap, "DWP.bmp"); SystemParametersInfo(SPI_SETDESKWALLPAPER,0,(LPVOID)"DWP.bmp",SPIF_SENDCHANGE|SPIF_UPDATEINIFILE); return 0; } BOOL SaveBitmap(HDC hDC,HBITMAP hBitmap,char* szPath) { OutputDebugString(L"Start SaveBitmap() "); DWORD error; FILE * fp= NULL; fp = fopen(szPath,"wb"); if(fp == NULL) { OutputDebugString(L"Error Unable to Create File "); return false; } BITMAP Bm; BITMAPINFO BitInfo; ZeroMemory(&BitInfo, sizeof(BITMAPINFO)); BitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); BitInfo.bmiHeader.biBitCount = 0; if(!::GetDIBits(hDC, hBitmap, 0, 0, NULL, &BitInfo, DIB_RGB_COLORS)) { OutputDebugString(L"Error GetDIBits Fail"); return (false); } Bm.bmHeight = BitInfo.bmiHeader.biHeight; Bm.bmWidth = BitInfo.bmiHeader.biWidth; BITMAPFILEHEADER BmHdr; BmHdr.bfType = 0x4d42; // 'BM' WINDOWS_BITMAP_SIGNATURE BmHdr.bfSize = (((3 * Bm.bmWidth + 3) & ~3) * Bm.bmHeight) + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); BmHdr.bfReserved1 = BmHdr.bfReserved2 = 0; BmHdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); BitInfo.bmiHeader.biCompression = 0; // Writing Bitmap File Header //// size_t size = fwrite(&BmHdr,sizeof(BITMAPFILEHEADER),1,fp); if(size < 1) { OutputDebugString(L"Error Header Write"); error = GetLastError(); } size = fwrite(&BitInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp); if(size < 1) { OutputDebugString(L"Error Write"); error = GetLastError(); } BYTE *pData = new BYTE[BitInfo.bmiHeader.biSizeImage + 5]; if(!::GetDIBits(hDC, hBitmap, 0, Bm.bmHeight, pData, &BitInfo, DIB_RGB_COLORS)) return (false); if(pData != NULL) fwrite(pData,1,BitInfo.bmiHeader.biSizeImage,fp); fclose(fp); delete (pData); return (true); }
Alle Antworten
-
Hallo!
Das Problem ist das verwendete Argument MAKEINTRESOURCE(IDB_BITMAP1). Wenn als erster Parameter SPI_SETDESKWALLPAPER verwendet wird, dann interpretiert der SPI Aufruf das Argument als Pointer auf einen String. Der vom Makro MAKEINTRESOURCE zurueck gelieferte Wert zeigt als Pointer interpretiert mit Sicherheit ins Nirvana. Also am besten so:
SystemParametersInfo(SPI_SETDESKWALLPAPER,0,(LPVOID)"c:\\DWP.bmp",SPIF_SENDCHANGE|SPIF_UPDATEINIFILE);
oder so aehnlich.
- Als Antwort markiert Mathias Schiffer Samstag, 9. Mai 2009 06:09
-
Hallo!
Das Problem ist das verwendete Argument MAKEINTRESOURCE(IDB_BITMAP1). Wenn als erster Parameter SPI_SETDESKWALLPAPER verwendet wird, dann interpretiert der SPI Aufruf das Argument als Pointer auf einen String. Der vom Makro MAKEINTRESOURCE zurueck gelieferte Wert zeigt als Pointer interpretiert mit Sicherheit ins Nirvana. Also am besten so:
SystemParametersInfo(SPI_SETDESKWALLPAPER,0,(LPVOID)"c:\\DWP.bmp",SPIF_SENDCHANGE|SPIF_UPDATEINIFILE);
oder so aehnlich.
Also das Problem hab ich jetzt verstanden, aber soweit ich das sehe und ausprobiert muss man für deinen Quellcode eine Bitmap Datei in einem x belibigen Verzeichnis liegen haben und ich will aber das die Bitmap schon in der exe vorhanden ist. Ich hab dann mal mit LoadBitmap() versucht das Programm läuft auch Fehlerfrei, aber es passiert irgendwie nichts. Ich denke mal es liegt daran das HBITMAP nicht als Variablentyp in der Funktion SystemParametersInfo() akzeptiert wird.
Hier der Quellcode
#include "stdafx.h"
#include <windows.h>
#include "resource.h"
HINSTANCE hinst;int _tmain(int argc, _TCHAR* argv[])
{
HBITMAP hBitmap;
hBitmap = LoadBitmap(hinst,MAKEINTRESOURCE(IDB_BITMAP1));
SystemParametersInfo(SPI_SETDESKWALLPAPER,0,(LPVOID)hBitmap,SPIF_SENDCHANGE|SPIF_UPDATEINIFILE);
return 0;
}
Bin für jede Hilfe dankbar. -
Hallo camelion3,
das Basisproblem ist, dass sich die Funktion SystemParametersInfo bereits existiert und senerzeit nicht so programmiert wurde, wie Du es Dir heute wünschst. Du wirst dich also beim direkten Aufruf der Funktion schon noch an das halten müssen, was verfügbar ist und überdies die Aufrufkonventionen einhalten müssen:
SystemParametersInfo Function
http://msdn.microsoft.com/en-us/library/ms724947.aspx
Zum gesuchten Parameter SPI_SETDESKWALLPAPER steht da:
"To specify a wallpaper bitmap, set pvParam to point to a NULL-terminated string containing the full path to the bitmap file. Setting pvParam to "" removes the wallpaper. Setting pvParam to SETWALLPAPER_DEFAULT or NULL reverts to the default wallpaper."
Natürlich kannst Du eine Wrapper-Funktion schreiben, die Parameter nach Deinen Wünschen entgegen nimt. Wenn Du aber SystemParametersInfo aufrufen willst (z. B. auch in Deinem Wrapper), musst Du Dich an das halten, was die Funktion Dir anbietet.- Als Antwort markiert Mathias Schiffer Samstag, 9. Mai 2009 06:09
-
Danke für die Antwort,
aber das mit der Wrapper Funktion ist ir dann doch etwas zu hoch, da ich noch nicht allzulange porgammiere.
Meine Frage ist jetzt ob es eine andere Funktion oder Möglichkeit gibt mein Vorhaben zu realisieren? Es wär auch nicht schlimm wenn sich die Datei erst in einen Ordner kopieren würde und dann von dort aus ganz normal mit der SystemParametersInfo() gestartet werden würde. Dazu müsste ich nur wissen wie man eine Resource entpacken kann.
Bin für jede Hilfe dankbar. -
Hi!
Also ich habe mal ein bisschen in den üblichen Foren gestöbert und eine Funktion gefunden, die ein Bitmap speichert. Leider stecke ich jetzt auch fest, weil die Funktion ::LoadBitmap nicht funktioniert. GetLastError liefert invalide 1812 zurück, d. h. so viel wie "The specified image file did not contain a resource section.". Irgendjemand ne Idee? Hier ist mein SourceCode snippet:
#include "stdafx.h" #include <windows.h> #include "resource.h" #include <fstream> HINSTANCE hinst; BOOL SaveBitmap(HDC,HBITMAP,char*); int _tmain(int argc, _TCHAR* argv[]) { HBITMAP hBitmap; HWND hwndC = GetConsoleWindow() ; hinst = (HINSTANCE)GetWindowLong( hwndC, GWL_HINSTANCE ); hBitmap = ::LoadBitmap(hinst, MAKEINTRESOURCE(IDB_BITMAP1)); if(hBitmap == NULL) { wchar_t strOutput[1024]; DWORD dwLastError = ::GetLastError(); swprintf(strOutput, L"Can't obtain Bitmap Handle, last error was %d\n", dwLastError); OutputDebugString(strOutput); return 1; } HWND hWnd = ::GetDesktopWindow(); HDC hDtwDC = ::GetDC(hWnd); HDC hCompatibleDC = ::CreateCompatibleDC(hDtwDC); ::SaveBitmap(hCompatibleDC, hBitmap, "DWP.bmp"); SystemParametersInfo(SPI_SETDESKWALLPAPER,0,(LPVOID)"DWP.bmp",SPIF_SENDCHANGE|SPIF_UPDATEINIFILE); return 0; } BOOL SaveBitmap(HDC hDC,HBITMAP hBitmap,char* szPath) { OutputDebugString(L"Start SaveBitmap() "); DWORD error; FILE * fp= NULL; fp = fopen(szPath,"wb"); if(fp == NULL) { OutputDebugString(L"Error Unable to Create File "); return false; } BITMAP Bm; BITMAPINFO BitInfo; ZeroMemory(&BitInfo, sizeof(BITMAPINFO)); BitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); BitInfo.bmiHeader.biBitCount = 0; if(!::GetDIBits(hDC, hBitmap, 0, 0, NULL, &BitInfo, DIB_RGB_COLORS)) { OutputDebugString(L"Error GetDIBits Fail"); return (false); } Bm.bmHeight = BitInfo.bmiHeader.biHeight; Bm.bmWidth = BitInfo.bmiHeader.biWidth; BITMAPFILEHEADER BmHdr; BmHdr.bfType = 0x4d42; // 'BM' WINDOWS_BITMAP_SIGNATURE BmHdr.bfSize = (((3 * Bm.bmWidth + 3) & ~3) * Bm.bmHeight) + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); BmHdr.bfReserved1 = BmHdr.bfReserved2 = 0; BmHdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); BitInfo.bmiHeader.biCompression = 0; // Writing Bitmap File Header //// size_t size = fwrite(&BmHdr,sizeof(BITMAPFILEHEADER),1,fp); if(size < 1) { OutputDebugString(L"Error Header Write"); error = GetLastError(); } size = fwrite(&BitInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp); if(size < 1) { OutputDebugString(L"Error Write"); error = GetLastError(); } BYTE *pData = new BYTE[BitInfo.bmiHeader.biSizeImage + 5]; if(!::GetDIBits(hDC, hBitmap, 0, Bm.bmHeight, pData, &BitInfo, DIB_RGB_COLORS)) return (false); if(pData != NULL) fwrite(pData,1,BitInfo.bmiHeader.biSizeImage,fp); fclose(fp); delete (pData); return (true); }
-
Hi,
vielen dank für deine Antwort tilly63.
Dein Programm funktionert super ich musste nur eine kleine Änderung vornehmen:
HWND hwndC = GetConsoleWindow() ;
Diese beiden Zeilen geben nicht das richtige Handle zurück.(Habe ka warum.)
hinst = (HINSTANCE)GetWindowLong( hwndC, GWL_HINSTANCE );
Stattdessen sollte man diesen Befehl verwenden :
hinst = GetModuleHandle(NULL);
und siehe da alles klappt wie es soll.
In diesem Sinne noch mal danke für deine Mühe.
MFG camelion3