Bmp Bild wird nicht angezeigt
-
Hallo,
ich wollte ein Bmp Bild in einem meiner Childwindows anzeigen lassen jedoch wird das Bild nicht angezeigt. Hier meine Codeschnipsel
Resources.rc
AbrechnungsBild BITMAP Wiese3.bmpund dann die Stelle an der es eingebunden werden soll
HBITMAP bmpbackground = (HBITMAP) LoadBitmap(InfoWindow,"AbrechnungsBild"); HBRUSH background = CreatePatternBrush(bmpbackground); //da sollte es eigentlich geladen werden //und hier füge ich es in Background mit ein InfoWindowClass.hbrBackground = background;jedoch wird das bild einfach nicht in das Fenster geladen, kann mir einer sagen was falsch sein könnte.? Denn das Laden des Bildes hat bei anderen Programmen eigentlich immer geklappt, nur jetzt nicht

-
Jo. Hab's ausgetestet. Da musst du mit MAKEINTRESOURCE und der Ressourcen - Nummer ran, nicht mit dem Namen der Bitmap ("Abrechnungsbild"). Und selbst wenn, dann müsste es eigtl. "Wiese3.bmp" heißen.
Also in deinem Fall so:
HBITMAP bmpbackground = LoadBitmap(InfoWindow, MAKEINTRESOURCE (AbrechnungsBild));Ansonsten hoffe ich, dass bei dir InfoWindow gleich der hInstance ist, die du in deiner WinMain von Windows als Parameter übergeben bekommst. (übergeben biiiiih ^^) :p
Guten Rutsch ins neue Jahr ! :xmas2:
Greetings, Xzi-bit
-
also InfoWindow is in meinem Fall der Handle zu dem Childwindow in welchem das Bild reingeladen werden soll. Ich hab mir mal den Code von einem Kumpel angeschaut, jedoch steht bei ihm haargenau das selbe wie bei mir, aber es klappt in meinem Fall nicht
keine ahnung warum
-
Handle zu dem Childwindow in welchem das Bild reingeladen werden soll
Wieso denn das HANDLE zum ChildWindow ? Du musst der Funktion das HANDLE zum Modul übergeben, von deren Ressourcen die Bitmap geladen werden soll !
Ich gehe ja wohl hoffentlich richtig in der Annahme, dass du deine "InfoWindowClass" einige Zeilen später mit RegisterClass()/RegisterClassEx() registrierst, oder ?
Naja, guck mal - deine Hauptfunktion WinMain sieht doch wohl ungefähr so aus:
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { //Code... }Und im Parameter hInstance dieser Funktion bekommst du von Windows das HANDLE auf dein Exemodul übergeben, dass du dann weniger später einfach der LoadBitmap() Funktion übergibst:
HBITMAP bmpbackground = LoadBitmap(hInstance, MAKEINTRESOURCE (AbrechnungsBild));
-
öhmmm naja dieses InfoWindow ist ein komplett eigenes neues fenster, und da soll das Bild reingeladen werden. daher sage ich ja das InfoWindow, is ein Child von meinem hauptfenster und in das child soll das bild rein.
p.s. naklar registriere ich das Teil:D
-
Oh, okay.
Na dann würde ich mal sagen:Übergib mal der LoadBitmap() die hInstance und dann wie folgt:
Mit RegisterClass() würdest du ja in dem Fall für ALLE Fenster deiner Fensterklasse diesen Hintergrund registrieren. Da du aber nur für ein Fenster, nämlich dein Child-Window, einen anderen Hintergrund haben willst, dann nimm doch einfach SetClassLong her und ändere somit nur für das Child-Window im speziellen den Hintergrund:
http://msdn2.microsoft.com/en-us/library/ms633588(VS.85).aspx
also z.B.:
SetClassLong (hChildWindow, GCL_HBRBACKGROUND, (HBRUSH) background);Sollte eigentlich funktionieren. Wie das dein Kumpel anderenfalls gemacht hat - keine Ahnung.

-
also ich poste mal alles, weil ich komme nicht zurecht
int CallInfoWindow(HINSTANCE InfoWindow ,HWND Parent ) { RECT ScreenCoords; if(!SystemParametersInfo(SPI_GETWORKAREA,NULL,&ScreenCoords,NULL) ) { MessageBox(NULL,"Ein Fehler ist aufgetreten","Fehler",MB_ICONWARNING | MB_OK | MB_DEFBUTTON1); ScreenCoords.right = 1024; ScreenCoords.bottom = 768; } /* declares Window for NoticeWindow */ HWND Info = NULL; HBITMAP bmpbackground = (HBITMAP) LoadBitmap(InfoWindow,"AbrechnungsBild"); HBRUSH background = CreatePatternBrush(bmpbackground); SetClassLong (Parent, GCL_HBRBACKGROUND, (HBRUSH)background); MSG WindowMsg; WNDCLASS InfoWindowClass; InfoWindowClass.cbClsExtra = 0; InfoWindowClass.cbWndExtra = 0; InfoWindowClass.hbrBackground = background; InfoWindowClass.hCursor = LoadCursor(NULL,IDC_ARROW); InfoWindowClass.hIcon = 0; InfoWindowClass.hInstance = InfoWindow; InfoWindowClass.lpfnWndProc = InfoProcedure; InfoWindowClass.lpszClassName = "Info"; InfoWindowClass.lpszMenuName = 0; InfoWindowClass.style = CS_HREDRAW | CS_VREDRAW ; RegisterClass(&InfoWindowClass); /*Create Window*/ Info = CreateWindowEx(WS_EX_CLIENTEDGE, "Info", //Name der Fensterklasse "Abrechnungsplaner-Info", //Titel welcher beim Aufruf in der Oberen Leiste erscheint WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX, (ScreenCoords.right/2) - (500/2), (ScreenCoords.bottom/2) - (300/2), 320, 131, Parent, NULL, InfoWindow, NULL); ShowWindow(Info,SW_SHOWNORMAL); UpdateWindow(Info); while( GetMessage(&WindowMsg,NULL,0,0) ) { TranslateMessage(&WindowMsg); DispatchMessage(&WindowMsg); } return (int)WindowMsg.wParam; }so und in diesem window soll das Bild geladen werden,
nur es klappt einfahc nicht, sorry für mein unverständnis xzibit

-
Erstmal Rückgabewerte prüfen, speziell von LoadBitmap() und CreatePatternBrush().
SetClassLong() besser vermeiden:
msdn schrieb:
Use the SetClassLong function with care. For example, it is possible to change the background color for a class by using SetClassLong, but this change does not immediately repaint all windows belonging to the class.
Merkwürdig kommt mir auch vor:
Du erzeugst da ein Fenster, welches du an ein Fenster mit Handle "Parent" dran hängst: Hat der Parent keine MessageLoop? Falls ja: Warum dann zwei?
-
sorry für mein unverständnis xzibit
So ham wer alle mal angefangen, da gibts nix zu entschuldigen.
Guckst du hier:
HBITMAP hBitmap_Bckgrnd; HBRUSH hBrush_Bckgrnd; int CallInfoWindow (HINSTANCE hInst_InfoWindow, HWND hParent) { RECT rcScreen; MSG WindowMsg; if( !SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcScreen, NULL) ) { MessageBox (NULL, "Ein Fehler ist aufgetreten", "Fehler", MB_ICONWARNING | MB_OK); rcScreen.right = 1024; rcScreen.bottom = 768; } //Child-Window erstellen (hInfo) HWND hInfo = CreateWindowEx(WS_EX_CLIENTEDGE, "Info", //Name der Fensterklasse "Abrechnungsplaner-Info", //Titel welcher beim Aufruf in der Oberen Leiste erscheint WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_CHILD, //WS_CHILD für Child-Window !, deine Parameter WS_MINIMIZEBOX und (rcScreen.right/2) - (500/2), //WS_DLGFRAME widersprachen sich übrigens. (rcScreen.bottom/2) - (300/2), 320, 131, hParent, NULL, hInst_InfoWindow, NULL); /* Die Variable 'AbrechnungsBild' in der folgenden LoadBitmap()entspricht dabei derjenigen aus deiner Datei Resources.rc ! Also musst du erst mal den Wert deiner 'AbrechnungsBild' aus deiner Resources.rc herausfinden (steht wahrscheinlich in der Resources.h oder direkt in der Resources.rc) und anschließend mit z.B. '#define AbrechnungsBild <Wert>' in dieser Quelltextdatei bekannt machen. (Methode NR I) Oder: du sagst in deiner Resources.rc folgendes: '20 BITMAP Wiese3.bmp' anstatt 'AbrechnungsBild BITMAP Wiese3.bmp' (schreibst also gleich den absoluten Wert hin - da kannst dir einen schönen Wert aussuchen, bei mir 20) und schreibst dann außerdem anstatt der nächsten Zeile hier: HBITMAP hBitmap_Bckgrnd = (HBITMAP) LoadBitmap(hInst_InfoWindow, MAKEINTRESOURCE (20)); Das würde natürlich auch gehen. (Methode NR II) */ //Bitmap und Pinsel anfordern hBitmap_Bckgrnd = LoadBitmap (hInst_InfoWindow, MAKEINTRESOURCE (AbrechnungsBild)); hBrush_Bckgrnd = CreatePatternBrush(hBitmap_Bckgrnd); //Wir ändern nur für das ChildWindow (hInfo) den Hintergrund SetClassLong (hInfo, GCL_HBRBACKGROUND, (HBRUSH)hBrush_Bckgrnd); //Fenster anzeigen ShowWindow (hInfo, SW_SHOWNORMAL); UpdateWindow (hInfo); return (int) WindowMsg.wParam; }Ich hab deine Variablennamen etwas abgeändert und die Reihenfolge a bisserl umgeändert. Lass dich davon aber net aus der Ruhe bringen. Meiner Meinung nach isses so halt übersichtlicher. Aber das bleibt dir überlassen. Kannst deine Variablennamen ja jederzeit wieder ändern. Jetzt hoffe ich nur, dass dein Proggi jetzt zum Laufen kommt.
Ach ja, noch was:
Ich hab den Code mit der WNDCLASS und der RegisterClass() komplett rausgenommen.
Für den Fall, dass du bereits eine WNDCLASS für dein 'hParent' erzeugt hast (was ich mal stark annehme). Deshalb brauchste da jetzt nicht noch mal extra eine Fensterklasse erzeugen. Die Nachrichten, die du erhältst, werden dann halt an die Fensterprozedur weitergegeben, die du bereits in der WNDCLASS für dein Elternfenster hParent angegeben hast.Greetings, Xzi-bit und Gut' Nacht für heut *gäähn* ^^
-
Hi, ich habe deinen Code mal überarbeitet. Hier hast du ein komplettes funktionsfähiges Programm! Ein paar Funktionen habe rausgenommen und nur das "nötigste" gepostet.
resource.h
#ifndef RESOURCE_H #define RESOURCE_H #define ID_BITMAP 123 #endifresource.rc
#include <windows.h> #include "resource.h" ID_BITMAP BITMAP "Wiese3.bmp"BackgroundBMPBrush.cpp
#include <windows.h> #include "resource.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK InfoProc (HWND, UINT, WPARAM, LPARAM) ; int CallInfoWindow(HINSTANCE, HWND) ; HINSTANCE hInstanceGlobal ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { hInstanceGlobal = hInstance ; static TCHAR szAppName[] = TEXT("MainWindow"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass (&wndclass)) { MessageBox(NULL, TEXT("Kein Unicode!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow (szAppName, TEXT("Main Window"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); ShowWindow (hwnd, iCmdShow); UpdateWindow(hwnd); while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rect; switch (message) { case WM_CREATE : CallInfoWindow (hInstanceGlobal, hWnd) ; return 0; case WM_DESTROY : PostQuitMessage(0); return 0; } return DefWindowProc (hWnd, message, wParam, lParam) ; } int CallInfoWindow(HINSTANCE InfoWindow, HWND Parent) { HWND Info = NULL; HBITMAP bmpbackground ; if ((bmpbackground = (HBITMAP) LoadBitmap(InfoWindow, MAKEINTRESOURCE(ID_BITMAP))) == NULL) MessageBox(NULL,"LoadBitmap", "Fehler", MB_ICONWARNING | MB_OK | MB_DEFBUTTON1); HBRUSH background; if ((background = CreatePatternBrush(bmpbackground)) == NULL) MessageBox(NULL,"CreatePatternBrush", "Fehler", MB_ICONWARNING | MB_OK | MB_DEFBUTTON1) ; MSG WindowMsg; WNDCLASS InfoWindowClass; InfoWindowClass.cbClsExtra = 0 ; InfoWindowClass.cbWndExtra = 0 ; InfoWindowClass.hbrBackground = background ; InfoWindowClass.hCursor = LoadCursor(NULL,IDC_ARROW); InfoWindowClass.hIcon = 0 ; InfoWindowClass.hInstance = InfoWindow; InfoWindowClass.lpfnWndProc = InfoProc; InfoWindowClass.lpszClassName = "Info"; InfoWindowClass.lpszMenuName = 0; InfoWindowClass.style = CS_HREDRAW | CS_VREDRAW ; RegisterClass(&InfoWindowClass); /*Create Window*/ Info = CreateWindowEx(WS_EX_CLIENTEDGE, "Info", //Name der Fensterklasse "Abrechnungsplaner-Info", //Titel welcher beim Aufruf in der Oberen Leiste erscheint WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, Parent, NULL, InfoWindow, NULL); ShowWindow(Info,SW_SHOWNORMAL); UpdateWindow(Info); while( GetMessage(&WindowMsg,NULL,0,0) ) { TranslateMessage(&WindowMsg); DispatchMessage(&WindowMsg); } return (int)WindowMsg.wParam; } LRESULT CALLBACK InfoProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rect; switch (message) { case WM_DESTROY : PostQuitMessage(0); return 0; } return DefWindowProc (hWnd, message, wParam, lParam) ; }MfG WilMen

-
Use the SetClassLong function with care. For example, it is possible to change the background color for a class by using SetClassLong, but this change does not immediately repaint all windows belonging to the class.
Das ist aber in dem Fall ja eigtl. egal. Das Fenster wird ja erst danach mit ShowWindow auf den Bildschirm gebracht. Mit den Parametern hat geeky natürlich Recht. Die sollten stimmen. Sonst wird da nix draus ^^
Jetzt kannst du dir natürlich aussuchen, welchen Code du nimmst.
Kommt drauf an, was du machen willst:Wenn du
a) Ein Child-Window haben willst, das direkt dem hParent untergeordnet ist und somit innerhalb des Elternfensters angezeigt wird, nimmst du meinen Code.
(hab ich übrigens auch noch mal überarbeitet, weil ich der Meinung bin, gleich zwei Message-Loops bringens nicht wirklich
)b) Ein Child-Window haben willst, das als eigenständiges Fenster auf dem Desktop erscheint und nach Schließen auch das Elternfenster wieder anzeigt, so nimmst du WilMen's Code.
(2 Message Loops, die meiner Meinung nach in einem Programm wenig zu suchen haben, aber dafür ist WilMen's Code ca. 10x so übersichtlich wie meiner und du musst ihn bloß noch laufen lassen)Krass oda ?

Wer bietet den besseren Code ? XD Ich komm mir schon vor wie beim Code-Contest haha. Und das noch umsonst :p Von wegen Windows ist besser, weil da kein OpenSource angeboten wird. Da kannste mal kucken ^^
zOmg mir gefällt der Thread hier.
Greetz an WilMen und geekyPS: Jungs, ich hoffe wir verwirren ihn nicht. Wir decken ihn ja geradezu ein mit Sourcecode ^^
-
Ja, is schon geil!

Hoffentlich geschieht uns dasselbe, wenn wir mal ne Frage haben.

EDIT: Stimmt, er schrieb ja, er möchte ein Child-Window. Ich vergaß also WS_CHILD
als Stilbit. Du hast das ja zum Glück schon gepostet.
MfG WilMen
-
LOL jungs ihr seit derbe gut drauf, danke für diese wahnsinnig geile erklärung und besonders "anfängerfreundliche "erklärung, bin euch sehr dankbar, so wer meldet sich jetzt noch freiwillig mir seine icq zu geben damit ich acuh mal so kleine fragen nebenbei stellen ohne immer einen thread hier aufmachen zu müssen :D:D *hoffnungsvollguck* :xmas1:
EDIT:leider muss ich sagen, das ich die version von wilmen genutzt habe, aber dort wurden die beiden if´s mit den exception geschmissen, d.h. er lädt irgendwie garnicht. ich hab langsam keine ahnung mehr warum
, entweder bin ich zu doof, oder es geht nicht 
EDIT2: kann mir noch jemand erklären was das SetClassLong macht ??
-
Firefighter schrieb:
EDIT2: kann mir noch jemand erklären was das SetClassLong macht ??
Hi, hast du dir die Beschreibung in der MSDN Library schon durchgelesen? Wenn nein, immer zuerst dort nachlesen.
http://msdn2.microsoft.com/en-us/library/ms633588(VS.85).aspxFirefighter schrieb:
EDIT:leider muss ich sagen, das ich die version von wilmen genutzt habe, aber dort wurden die beiden if´s mit den exception geschmissen, d.h. er lädt irgendwie garnicht. ich hab langsam keine ahnung mehr warum
, entweder bin ich zu doof, oder es geht nicht 
Was heißt hier leider?

Befindet sich das Bild (Wiese3.bmp) in dem Verzeichnis, in dem sich die CPP-Datei befindet? Wenn nein, verschiebe sie dahin.

MfG WilMen
-
hehe sorry, doch sie befindet sich in dem verzeichnis wo auch die cpp datei befindet, eigentlich habe ich es genauso gemacht wie mein freund das eine mal, er hat das auf die selbe art und weise hinbekommen, jedoch klappt es jetzt bei mir nich
-
Also ich habe den Code unter Visual C++ Express Edition kompiliert und ausgeführt und bei mir klappt es. Was für einen Compiler verwendest du?
MfG WilMen
-
ich nehme code::blocks, also fakt is, das er in die beiden if´s reingeht und auch die messagboxes schmeißt...daher is dort der fehler sicherlich