Ein erstes Fenster



  • Hallo,

    lerne C++ mit Hilfe des Buches "C++ für Spieleprogrammierer"
    Dort fand ich ein Beispielcode für ein WindowsFenster, nur
    irgendwas lief schief.

    //C++ für Spieleprogrammierer
    //Listing 10.1
    //Ein Windows-Grundgerüst
    //
    #include <Windows.h>
    
    //Prototyp der Callback-Funktion
    LRESULT CALLBACK WindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    
    //Hauptprogramm
    //
    int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpcmdline, int ncmdshow)
    {
    	WNDCLASSEX	windowclass;	//Struktur für Fenstereigenschaften
    	HWND		hWnd;			//Fenster-Handle
    	MSG			message;		//Nachricht
    
    	//Der Klassen-Name des Fensters ist frei wählbar
    	const char szClassName[] = "Erstes Fenster";
    
    	//Struktur mit gewünschten Eigenschaften füllen
    	//
    
    	//Größe der Struktur zwischenspeichern
    	windowclass.cbSize = sizeof (WNDCLASSEX);
    
    	//Fenster soll beim Verschieben neu gezeichnet werden
    	windowclass.style = CS_HREDRAW | CS_VREDRAW;
    
    	//Zeiger auf Callback-Funktion
    	windowclass.lpfnWndProc = WindowProc;
    
    	//Keine erweiterten Einstellungen
    	windowclass.cbClsExtra = 0;
    	windowclass.cbWndExtra = 0;
    
    	//Instanz speichern
    	windowclass.hInstance = hInst;
    
    	//Icons und Cursor festlegen
    	windowclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    	windowclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    	windowclass.hCursor = LoadCursor (NULL, IDC_ARROW);
    
    	//Hintergrundfarbe festlegen
    	windowclass.hbrBackground = (HBRUSH) COLOR_BACKGROUND+1;
    
    	//Ein Menü brauchen wir nicht
    	windowclass.lpszMenuName = NULL;
    
    	//Fensterklasse regestrieren
    	if (!RegisterClassEx (&windowclass) )
    		return (0);
    
    	//Das Fenster erzeugen
    	hWnd = CreateWindowEx	(NULL,
    							szClassName,
    							"Das erste Fenster!",
    							WS_OVERLAPPEDWINDOW | WS_VISIBLE,
    							100, 100, 
    							300, 250,
    							NULL,
    							NULL,
    							hInst,
    							NULL);
    
    	//Prüfen ob alles glatt ging
    	if (hWnd == NULL)
    		return (0);
    
    	//Der "Herzschlag des Programms.
    	//Hier werden alle Nachrichten abgeholt,
    	//übersetzt und weitergeleitet.
    	while (GetMessage (&message, NULL, 0, 0) )
    	{
    		TranslateMessage (&message);
    		DispatchMessage (&message);
    
    	}
    
    	//Programm beenden
    	return (int) (message.wParam);
    
    }//WinMain
    
    //Callback-Funktion zur Nachrichtenverarbeitung
    //
    LRESULT CALLBACK WindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	//Messages auswerten
    	switch (message)
    	{
    		//Fenster schließen? (auch alt +F4)
    		case WM_DESTROY:
    			{
    				//Nachricht zum Beenden schicken
    				PostQuitMessage (0);
    				return (0);
    
    			}
    
    			//Wurde eine Taste gedrückt?
    		case WM_KEYDOWN:
    			{
    				//Ja, also je nach Taste verzweigen
    				switch (wParam)
    				{
    					//Wurde "Escape" gedrückt?
    				case VK_ESCAPE:
    					{
    						//Ja, also Nachricht zum Beenden schicken
    						PostQuitMessage (0);
    						return (0);
    
    					}
    				}
    			} break;
    	}
    
    	//Die Nachricht wurde nicht von uns verarbeitet, also 
    	//von Windows verarbeiten lassen.
    	return (DefWindowProc (hWnd, message, wParam, lParam) );
    
    } //WindowProc
    

    Fehlermeldung:
    1>c:\users\lybrial\documents\visual studio 2010\projects\grundlagen windows programmierung\grundlagen windows programmierung\ein erstes fenster.cpp(65): error C2664: 'CreateWindowExW' : cannot convert parameter 2 from 'const char [15]' to 'LPCWSTR'
    1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast



  • Probier mal: Du brauchst hier wchar_t[], und nicht char[]. Das heißt:

    hWnd = CreateWindowEx(..., L"Das erste Fenster!", ...);
    


  • Versteh nur Bahnhof 😉



  • Mein Satz ist zugegebenermaßen ein klein wenig verstümmelt.
    Nichtsdestoweniger: Zweiter Hit bei Google für "wchar_t": http://www.imb-jena.de/~gmueller/kurse/c_c++/c_wchar.html

    Das sollte alles klarstellen.



  • Heißt das ich muss die
    stddef.h
    header einbinden und dann
    einfach nen L vor meinem Text platzieren?

    Sorry aber ich hab keine Ahnung von dieser Header,
    wie ich schon schrieb, war das ein Beispiel aus
    einem Buch. Und laut dem Buch sollte es auch so
    funktionieren

    Wenn ichs so probiere, kommt diese Fehlermeldung:

    1>c:\users\lybrial\documents\visual studio 2010\projects\grundlagen windows programmierung\grundlagen windows programmierung\ein erstes fenster.cpp(20): error C2440: 'initializing' : cannot convert from 'const wchar_t [15]' to 'const char []'
    1> There is no context in which this conversion is possible
    1>c:\users\lybrial\documents\visual studio 2010\projects\grundlagen windows programmierung\grundlagen windows programmierung\ein erstes fenster.cpp(66): error C2664: 'CreateWindowExW' : cannot convert parameter 2 from 'const char []' to 'LPCWSTR'
    1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast



  • Der Header ist in C++ nicht mehr nötig, afaik.
    Ich merke aber gerade, dass ich den falschen Parameter verantwortlich gemacht habe.
    Es geht ja um szClassName. Dann solltest du natürlich dessen Datentyp entsprechend abändern (const wchar_t*).
    Wie gesagt, wchar_t* ist, wenn mich meine bescheidenen WinAPI-Kenntnisse nicht im Stich lassen, der Typ für Strings in der Windows-Programmierung.
    Aber eigentlich gehört das gar nicht einmal in dieses Unterforum.



  • Hmmm....
    Wenn ich das ganze jetzt wie du sagtest in const wchar_t
    ändere, kommt zwar keine Fehlermeldung mehr, aber es
    passiert auch weiter überhaupt nichts, es bleibt alles
    wie es ist, ohne irgendeine Ausgabe, ab und zu stürtzt
    sogar das Programm ab.



  • "ab und zu"? Ein wenig vage.

    Apropos vage: Sorry, dass das hier nicht die nützlichsten Tipps sind. Ich konnte mich nur noch dunkel erinnern, auch einmal vor diesem "Problem" gestanden zu haben, und dachte, dass ein führendes L vor allen Stringliteralen und die Konsequente Verwendung von wchar_t (resp. LPCWSTR) wäre die einfache Lösung.
    Ich habe auch gerade kein Windows da, um es testen zu können. Insofern wäre ich kompetenteren Leuten sehr verbunden, hier Abhilfe zu leisten.



  • Ok "ab und zu" mal konkreter definiert xD:
    Manchmal stürtzt es ab, nachdem ich das zweite mal
    Compilieren lasse, manchmal nach dem dritten mal,
    machmal nach dem vierten mal.

    😉



  • Wann, also an welcher Stelle im Programm, stürzt es denn ab? Was meinst du mit "4tes Mal kompilieren"?



  • Naja, ich habs öfter versucht zu compilieren und an welcher
    Stelle es abstürtzt kann ich nicht sagen, da ja wie ich schon
    sagte, nichts passiert, alle Fenster bleiben weiß und wenn es
    abstürtzt, bekomme ich von Windows lediglich die Meldung,
    das das Programm nicht mehr reagiert.



  • Ist dir der Unterschied zwischen "Programm ausführen" und "Programm kompilieren" klar?



  • Beim Compilieren wird der Code in die "Computersprache"
    übersetzt und beim ausführen wird dieses Programm, das
    in die "Computersprache" übersetzt wurde eben ausgeführt?



  • Wie meinst du dann, dass du das Programm "öfter versuchst zu kompilieren"? Kompilierst du das Programm mehrmals hintereinander und testest es jedes Mal, und manchmal stürzt es ab und manchmal nicht?
    Werden die Fenster denn mit richtigem Titel etc. angezeigt?



  • Ahja dann hab ich das tatsächlich verwechselt, d. h. ich hab es
    mehrmals ausgeführt. Das Fenster das ich versuche zu erstellen
    wird nicht angezeigt. Wie gesagt, es passiert nichts.



  • //Der Klassen-Name des Fensters ist frei wählbar
        const char szClassName[] = "Erstes Fenster";
    

    das hier ist falsch - besagt die Fehlermeldung.
    ->

    //Der Klassen-Name des Fensters ist frei wählbar
        const wchar_t szClassName[] = "Erstes Fenster";
    

    char umfasst nur den einfachen ascii-zeichensatz
    wchar_t umfasst den gesamten unicode-zeichensatz - und der wird windowsintern wohl auch seit ein paar versionen verwendet.

    beim nächsten mal nutze doch bitte die cpp-tags anstatt der code-tags
    des weiteren sollte dir ganz schnell klar werden, dass das ins winapi-forum gehört - im C++ forum hat so etwas nichts zu suchen.

    wenn es nach der änderung oben noch immer nicht klappt, poste noch mal deinen code, so wie ihn du hast und die exakte fehlermeldung.

    für die fehlermeldung nimmst du am besten code-tags und für den code wie gesagt die c++-tags.

    bb


Anmelden zum Antworten