Einfach nur ein leeres Fenster erzeugen? Wo ist mein Fehler?
-
Hallo,
ich habe jetzt den Schritt in die Windowsprogrammierung gewagt. Nur muss ich leider zugeben, dass das Ganze doch schwerer ist als ich es gedacht habe.
Wenn ich meinen Code ausführe, dann erscheint immer meine MessageBox "Fenster konnte nicht erzeugt werden". Ergo muss das Handle, was von der Funktion "CreateMainWindow" zurückgegeben wird gleich Null sein, aber warum? Wäre für antworten sehr dankbar...
ciao Peter
#include <windows.h> HWND CreateMainWindow(HINSTANCE hInstance); LRESULT CALLBACK MessageHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); HWND hWnd = 0; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { hWnd = CreateMainWindow(hInstance); if(hWnd == 0) { MessageBox(0,"Fenster konnte nicht erzeugt werden", "Fehler", MB_OK); return 0; } MSG msg; while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } HWND CreateMainWindow(HINSTANCE hInstance) { WNDCLASSEX wndClass; wndClass.cbSize = sizeof(WNDCLASSEX); wndClass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wndClass.lpfnWndProc = MessageHandler; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hInstance = hInstance; wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); wndClass.lpszClassName = "WindowClass"; wndClass.lpszMenuName = NULL; wndClass.hIcon = LoadIcon(NULL, IDI_WINLOGO); wndClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO); RegisterClassEx(&wndClass); return CreateWindowEx( NULL, "WindowClass", "Ein einfaches Fenster", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 400, 300, NULL, NULL, hInstance, NULL); } LRESULT CALLBACK MessageHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CREATE: return 0; break; case WM_LBUTTONDBLCLK: return 0; break; case WM_CLOSE: return 0; break; case WM_DESTROY: PostQuitMessage(0); return 0; break; } return DefWindowProc(hWnd,msg,wParam,lParam); }
-
return DefWindowProc(hWnd,msg,wParam,lParam);
hWnd==>hwnd
-
was schonmal nicht geht ist LoadIcon(NULL, IDI_WINLOGO)
wndClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINLOGO)); wndClass.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINLOGO));
fals es dann mit der Fenstererstellung immer noch nicht klappt, versuch mal
wndClass.lpfnWndProc = (WNDPROC)MessageHandler;
-
OK der zweite Beitrag hat funktioniert. Es lag tatsächlich daran, dass man hWnd durch hwnd ersetzen musste.
Ich weis jetzt nicht genau warum, aber ich vermute es liegt daran, dass die Parameter der Funktionen "DefWindowProc" und "CALLBACK" identisch sein müssen, ebend auch bei der Groß- und Kleinschreibung. Lieg ich da richtig?
Leider lässt sich mein Fenster nicht mit einem Klick auf das Kreuz schließen. Warum? Da muss doch noch irgendein Fehler bei der Verarbeitung der Nachrichten sein?
-
hWnd ist als globale Variable deklariert - hwnd ist der Parameter des WndProc. Da hWnd aber 0 ist wenn das WndProc erstmals aufgerufen wird, ist DefWindowProc() (und somit auch CreateWindowEx()) zum Scheitern verurteilt.
-
Peter1234 schrieb:
Ich weis jetzt nicht genau warum, aber ich vermute es liegt daran, dass die Parameter der Funktionen "DefWindowProc" und "CALLBACK" identisch sein müssen, ebend auch bei der Groß- und Kleinschreibung.
C und C++ sind case-sensitive, daran musst du dich gewöhnen. Normalerweile wirst du aber auch auf solche Fehler vom Compiler hingewiesen (fehlender Bezeichner). Bei dir waren das nun ganz blöde Umstände durch die ähnlich benannte Globale. Nun hast du auch schon mal einen guten Grund, um von globalen Variablen wegzugehen!
-
[quote="_matze"]
Peter1234 schrieb:
Nun hast du auch schon mal einen guten Grund, um von globalen Variablen wegzugehen!
oder einfach einen Präfix wie z.B. 'g_' benutzen: g_hWnd
-
Gut dashabe ich verstanden, aber warum lässt sich mein Fenster nicht schließen? Maximieren und minimieren geht problemlos...
-
Das "return 0" muß aus der case WM_CLOSE und der case WM_DESTROY raus.
-
returnnix schrieb:
Das "return 0" muß aus der case WM_CLOSE und der case WM_DESTROY raus.
Nein. Der WM_CLOSE muss raus. Der WM_DESTROY case muss drin bleiben, sonst wird die Nachrichtenschleife nicht beendet.
-
DestroyWindow() vergessen?