Fenster öffnen Tutorial Problem



  • Hallo,

    ich arbeite gerade ein Video-Tutorial durch und dort habe ich folgenden Code geschrieben, der ein Fenster öffnen soll. Nur leider funktioniert es nicht. Das Programm geht an und sofort wieder aus. Wo liegt der Fehler? Und es gibt doch bestimmt auch eine einfachere Möglichkeit, Fenster zu erstellen, oder? Das kann doch nicht immer so umfangreich sein oO

    #include <windows.h>
    #include <iostream>
    
    LPCSTR szClassName = {"MyClassEx"};
    LPCSTR szTitle = {"Grafik-Tutorial"};
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow){
    
    	WNDCLASSEX WndClassEx;
    	HWND hWnd;
    	MSG	 msg;
    	// Registrierung
    
    	WndClassEx.cbSize			= sizeof( WndClassEx );
    	WndClassEx.style			= NULL;
    	WndClassEx.lpfnWndProc		= WndProc; //Wichtig!
    	WndClassEx.cbClsExtra		= NULL;
    	WndClassEx.cbWndExtra		= NULL;
    	WndClassEx.hInstance		= hInstance;
    	WndClassEx.hIcon			= NULL;
    	WndClassEx.hCursor			= NULL;
    	WndClassEx.hbrBackground	= (HBRUSH) ( COLOR_BACKGROUND + 1 );
    	WndClassEx.lpszMenuName		= NULL;
    	WndClassEx.lpszClassName	= szClassName;
    	WndClassEx.hIconSm			= NULL;
    
    	RegisterClassEx( &WndClassEx );
    
    	// Fenster erstellen
    
    	hWnd = CreateWindowEx( WS_EX_CLIENTEDGE,
    					   	 szClassName,
    					 	 szTitle,
    						 WS_OVERLAPPEDWINDOW,
    						 CW_USEDEFAULT,
    						 CW_USEDEFAULT,
    						 CW_USEDEFAULT,
    						 CW_USEDEFAULT,
    						 NULL,
    						 NULL,
    						 hInstance,
    						 NULL );
    
    	ShowWindow( hWnd, iCmdShow );
    
    	while ( GetMessage( &msg, hWnd, NULL, NULL ) < -1 ) {
    		TranslateMessage( &msg );
    		DispatchMessage( &msg ); // "dispatch" = verschicken
    
    	};
    
    	return 0;
    };
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
    		switch( msg ){
    		case WM_QUIT: // Programm Ende
    			MessageBox( NULL, "Programm wurde beendet.", "Programm beendet", MB_OK );
    			break;
    		case WM_DESTROY: // Fenster Ende
    			PostQuitMessage(0);
    			break;
    		default:
    			return DefWindowProc( hWnd, msg, wParam, lParam ); // alle anderen Nachrichten werden default behandelt
    			break;
    		};
    	};// sogenannte Callback-Funktion
    

    Danke,

    Grüße,

    Thilo



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x und C++11) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • mach das "< -1" in der Schleifenbedingung weg, das brauchst du nicht.

    1. gibt GetMessage einen BOOL zurück und
    2. ist FALSE als 0 und TRUE als (-1) definiert...
    Merkst du was?
    Der Rückgabewert ist NIE kleiner als -1...
    Also wird die Schleife direkt übersprungen.

    PS.:
    WM_QUIT wird dein Fenster nie empfangen...
    das kann also da weg.
    WM_QUIT wird direkt durch GetMessage bearbeitet, welches dann FALSE liefert,
    wodurch die Hauptschleife verlassen wird.
    Deine MessageBox kannst du also einfach in die WinMain hinter die Schleife packen.



  • Danke, mit

    while ( GetMessage( &msg, hWnd, NULL, NULL ) > NULL ) {
    

    geht es. Ist es denn immer so kompliziert, Fenster zu erstellen, oder wird das noch einfacher, wenn ich mich mehr eingearbeitet habe?



  • Wann bitte hab ich geschrieben, du sollst "> NULL" schreiben...
    1. ist NULL nur in C++ als 0 definiert (in C ist es (void*)0) und
    2. sollte es auch eher für Zeiger verwendet werden...
    3. wird wenn schon mit TRUE oder FALSE verglichen, alles andere ist an dieser Stelle eine Vergewaltigung der Semantik...

    Im Übrigen reicht ein einfaches

    while (GetMessage(&msg, NULL, 0, 0))
    

    da wird implizit geprüft, ob der Ausdruck zu true evaluiert.

    Und ja, es wird einfacher, aber verabschiede dich von Video Tutorials, die sind meistens nicht so pralle...
    Schau dir lieber mal den Petzold an
    Das Buch ist zwar schon älter, aber immer noch ein Standardwerk zu Windows API und es gibt bis heute nichts vergleichbares...

    Wenn dir die WinAPI zu kompiliziert ist, kannst du aber auch ein Framework wie Qt, wxWidgets, GTK+, FLTK, ... (gibt sehr viele :p) verwenden, die sind nebenbei auch noch plattformunabhängig (du kannst damit also auch für Linux programmieren ;))



  • DrakoXP schrieb:

    Im Übrigen reicht ein einfaches

    while (GetMessage(&msg, NULL, 0, 0))
    

    das ist nicht ganz Korrekt:

    msdn schrieb:

    BOOL bRet;
    while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
    {
    if (bRet == -1)
    {
    // handle the error and possibly exit
    }
    else
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    }

    :schland:



  • DrakoXP schrieb:

    3. wird wenn schon mit TRUE oder FALSE verglichen, alles andere ist an dieser Stelle eine Vergewaltigung der Semantik...

    Im Übrigen reicht ein einfaches

    while (GetMessage(&msg, NULL, 0, 0))
    

    Ich würde sagen "Doppelfehler":

    Because the return value can be nonzero, zero, or -1, avoid code like this:

    while (GetMessage( lpMsg, hWnd, 0, 0)) ...

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms644936(v=vs.85).aspx

    Im übrigen ist GetMessage() ein Systemaufruf und hat mit C++ nicht viel zu tun ...


Anmelden zum Antworten