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) ); } //WindowProcFehlermeldung:
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.htmlDas 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
funktionierenWenn 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