2 Probleme
-
Da mein alter Thread anscheinend gelöscht wurde, mach ich jetzt mal einen neuen auf.
Also momentan habe ich jetzt eine Fensterklasse, die fürs erste so aussieht:class Application { public: HINSTANCE hInstance; // Application Instance LPWSTR className; // Application ClassName }; class WindowInitGL { public: Application application; // Application Klasse wchar_t title[100]; // Window Title int width; // Width int height; // Height int bpp; // Bits Per Pixel bool fullscreen; // fullscreen flag }; class WindowGL { public: //Keys keys; // Tasten aktionen bool keyDown [256]; // Speichert true/false für jede Taste HWND hWnd; // Fenster Handle HDC hDC; // Device Context HGLRC hRC; // Rendering Context WindowInitGL init; // Fenster Initialisierung bool visible; // Fenster sichtbar? bool active; // Ist Fenster aktiv? bool readSettings(void); // Settings lesen und Speichern bool LoadTexturesGL(void); // Texturen laden bool CreateWindowGL(void); // Fenster erzeugen GLvoid KillWindowGL(GLvoid); // Fenster zerstören bool InitGL(GLvoid); // Fenster Initialisieren GLvoid ReshapeGL(GLsizei width, GLsizei height); GLvoid DrawGL(GLvoid); // Fenster zeichnen int TranslateMsg(UINT msg, LPARAM lParam, WPARAM wParam); // System Msg verarbeiten bool ProgramIsLooping(void); // Programm läuft noch void TerminateApplication(void); // Application beenden private: bool programloop; };Dann erstelle ich mit
WindiwGL* mainwindow = new WindowGL;eine Instanz und möchte sie so löschen:
delete Mainwindow;Das ganze funktioniert zwar, und der Debugger meckert nicht, aber immer wenn ich das Programm schließe, also die Klasseninstanz gelöscht wird ertönt der Windows XP Fehlerton bei mir. Aber das wars eigentlich auch an Fehler die auftreten.
Jetzt möchte ich natürlich nicht, dass immer ein Fehlerton kommt. Kann mir da wer weiterhelfen?Und dann habe ich noch eine zweite Frage. Bisher habe ich die Systemnachrichten immer ganz normal im Code bearbeitet. Jetzt wollte ich dafür in der WindowGL Class eine Funktion schreiben, die ich dann so aufrufe:
mainwindow->TranslateMsg(uMsg, lParam, wParam);Die Funktion TranslateMsg sieht dann so aus:
int WindowGL::TranslateMsg(UINT msg, LPARAM lParam, WPARAM wParam) { switch (msg) { // Überprüfe auf Fensternachrichten case WM_CREATE: // Fenster wird erstellet { CREATESTRUCT* creation = reinterpret_cast<CREATESTRUCT*>(lParam); this = reinterpret_cast<WindowGL*>(creation->lpCreateParams); SetWindowLong(hWnd, GWL_USERDATA, reinterpret_cast<long>(this)); } return 0; case WM_ACTIVATE: // Wenn Aktivierungs-Nachricht reinkommt if (!HIWORD(wParam)) { // Überprüfe Minimierungs-Status active = true; // Programm ist aktiv } else { active = false; // Programm ist nicht länger aktiv } return 0; // Kehre zurück zur Nachrichten-Schleife case WM_SYSCOMMAND: switch (wParam) { case SC_SCREENSAVE: // versucht der Screensaver sich zu starten? case SC_MONITORPOWER: // versucht der Monitor in den Energiesparmodus zu gehen? return 0; // verhindere das } break; case WM_CLOSE: PostMessage(hWnd, 0, 0, 0); TerminateApplication(); // Sende eine Beenden-Nachricht return 0; case WM_KEYDOWN: // Taste wurde gedrückt if ((wParam >= 0) && (wParam <= 255)) { // Ist wParam gültig keyDown[wParam] = true; // gedrückte Taste ist true return 0; } break; case WM_KEYUP: // Taste wurde losgelassen if ((wParam >= 0) && (wParam <= 255)) { // Ist wParam gültug keyDown[wParam] = false; // gedrückte Taste ist false return 0; } break; case WM_SIZE: // Size Message switch (wParam) // Evaluate Size Action { case SIZE_MINIMIZED: // Fenster wurde minimiert visible = false; // visible ist flase return 0; case SIZE_MAXIMIZED: // Fenster wurde maximiert visible = true; // visible ist true ReshapeGL(LOWORD (lParam), HIWORD (lParam)); // Reshape Window - LoWord = Width, HiWord = Height return 0; } break; } };Jetzt weiß ich, dass bei WM_CREATE "this" kein L-Wert ist, und da liegt auch das Problem. Denn bisher habe ich die Nachrichten so abgearbeitet:
switch (uMsg) { // Überprüfe auf Fensternachrichten case WM_CREATE: // Fenster wird erstellet { CREATESTRUCT* creation = reinterpret_cast<CREATESTRUCT*>(lParam); mainwindow = reinterpret_cast<WindowGL*>(creation->lpCreateParams); SetWindowLong(hWnd, GWL_USERDATA, reinterpret_cast<long>(mainwindow)); } return 0; case WM_ACTIVATE: // Wenn Aktivierungs-Nachricht reinkommt if (!HIWORD(wParam)) { // Überprüfe Minimierungs-Status mainwindow->active = true; // Programm ist aktiv } else { mainwindow->active = false; // Programm ist nicht länger aktiv } return 0; // Kehre zurück zur Nachrichten-Schleife case WM_SYSCOMMAND: switch (wParam) { case SC_SCREENSAVE: // versucht der Screensaver sich zu starten? case SC_MONITORPOWER: // versucht der Monitor in den Energiesparmodus zu gehen? return 0; // verhindere das } break; case WM_CLOSE: mainwindow->TerminateApplication(); // Sende eine Beenden-Nachricht return 0; case WM_KEYDOWN: // Taste wurde gedrückt if ((wParam >= 0) && (wParam <= 255)) { // Ist wParam gültig mainwindow->keys.keyDown[wParam] = true; // gedrückte Taste ist true return 0; } break; case WM_KEYUP: // Taste wurde losgelassen if ((wParam >= 0) && (wParam <= 255)) { // Ist wParam gültug mainwindow->keys.keyDown[wParam] = false; // gedrückte Taste ist false return 0; } break; case WM_SIZE: // Size Message switch (wParam) // Evaluate Size Action { case SIZE_MINIMIZED: // Fenster wurde minimiert mainwindow->visible = false; // visible ist flase return 0; case SIZE_MAXIMIZED: // Fenster wurde maximiert mainwindow->visible = true; // visible ist true mainwindow->ReshapeGL(LOWORD (lParam), HIWORD (lParam)); // Reshape Window - LoWord = Width, HiWord = Height return 0; } break; }Wie kann ich es jetzt realiesen, dass TranslateMsg() auch das Fenster korrekt erzeugt. An WM_CREATE wird ein this von WindowGL weitergegeben.
Danke schonmal für eure Hilfe.
-
Das gehört ins WinAPI Forum.
-
Zur ersten Frage:
Zeig mal bitte deine CreateWindowGL, InitGL und KillWindowGL Implementierung.
So kann man da schlecht den Fehler finden.Zur zweiten Frage.
Das mit dem this = ... geht natürlich nicht.
Da kannst du nur jeden member einzeln zuweisen, bzw. das ganze in eine Init-Methode kapseln.Den reinterpret_cast find ich übrigens sehr brutal. Geht das nicht auch anders? Hab zwar weniger Ahnung von der Windows API aber, sind diese Messages dafür da um ganze Objekte mit zu übergeben?
-
Naja der Thread gehört halb ins WinApi Forum

Sollen die Moderatoren entscheiden, wo er hingehört.Zum ersten Problem:
Ich habe mal die komplette WindowGL.cpp bei pastebin gepostet. Die Position der Kommentare ist zwar ziemlich verhunzt, aber ganz weglassen wollte ich sie jetzt auch nicht.
http://pastebin.com/mgf41EfBZum zweiten Problem:
Ich finde die reinterpret_casts auch sehr brutal, aber so hat es funktioniert.
Ich habe die Methode aus dem NeHe Tutorial, allerdings hätte ich nichts dagegen, das Fenster irgendwie anders zu erstellen, hauptsache es funktioniert. Wenn da jemand ein paar Tipps hätte, wäre ich sehr dankbar.
-
Kommt dein seltsamer Ton beim delete (Aufruf Destructor den du ja nicht definiert hast) oder beim KillWindowGL? Kannst das doch einfach mal durchdebuggen um die genaue Stelle zu finden. Hast du das schonmal gemacht?
-
Das ich den Ton nicht schon vorher gehört habe, lag anscheinend daran, dass ich meine Boxen nie an hatte. Ich habe gerade nochmal nachgeschaut und den Ton erzuegen diese beiden MessageBoxen, die sofort wieder verschwinden:
if (hDC && !ReleaseDC(hWnd,hDC)) { // Können wir DC freigeben? MessageBox(NULL, _T("Freigabe des Device Kontext gescheitert."), _T("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION); hDC = NULL; // Setze DC auf NULL } if (hWnd && !DestroyWindow(hWnd)) { // Können wir das Fenster zerstören? MessageBox(NULL, _T("Zerstören des Fenster-Handle gescheitert."), _T("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION); hWnd = NULL; // Setze hWnd auf NULL }Also der Device Kontext und der Fenster Handle können nicht freigegeben werden.
Und da habe ich direkt noch eine Frage: Wie schaffe ich es, dass die MessageBox solange da bleibt, bis ich OK gedrückt habe?
Mit if(MessageBox(....) == IDOK) klappt es nicht.
-
So, ich habe jetzt nochmal ein bisschen in der MSDN rumgestöbert, und dann GetLastError() ausprobiert. Das ist anscheinend die einzige Möglichkeit, irgendwas herauszufinden. Aber GetLastError() gibt immer den Wert 3435973836 zurück. Und damit kann man wenig anstellen.
Falls es noch relevant ist: Der Wert "unused" von hWnd ändert sich immer im Laufe des Programms. Aber Google sagt, der Wert ist irrelevant.
-
Warum gehen die MessageBoxen sofort wieder zu?
Warum musst du gleich eine MessageBox öffnen?
Was genau scheitert denn, so dass die If-Bedingungen erfüllt sind.
Normalerweise müsste das ja klappen. Ist HDC richtig initialisiert wurden bevor du es zerstörst?
Liegt es an ReleaseDC oder DestroyWindow?
Hast du vor dem ReleaseDC die Funktionen GetWindowDC oder GetDC aufgerufen?
Welche Zahl gibt ReleaceDC zurück?
Wenn du das DC mit CreateDC erzeugt hast darfst du es nicht mit ReleaseDC freigeben, sondern musst DeleteDC verwenden.
Außerdem muss ReleaseDC im selben Thread aufgerufen werden, in dem auch GetDC aufgerufen wurde. Das selbe gilt für CreateWindow und DestroyWindow.Das würde ich jetzt erstmal versuchen rauszufinden.
-
Und debugge das nochmal durch und guck mal wann die Box aufgeht und wieder zu.
Ich vermute, dass ein anderer Thread dein Hauptfenster zerstört und dadurch die MessageBox keinen Owner mehr hat. Setze entweder mal den ersten Parameter auf hWnd oder versuchs mal mit dem zusätzlichem Style MB_TASKMODAL oder MB_SYSTEMMODAL.
-
Sehen tut man die MessageBox garnicht. Wenn man bis zur Zeiler der MB debuggt, erscheint noch nichts, und wenn man bis zur Zeile danach debuggt hört man nur den Ton. Als ersten Parameter hWnd zu benutzen erscheint mir sinnlos, da ja genau dieser zerstört werden soll. MB_TASKMODAL oder MB_SYSTEMMODAL haben auch keinen Effekt, dass die MB's länger offen bleiben.
-
Kann ein Moderator den Thread mal ins WinApi Forum verschieben?
Wäre nett
-
Dieser Thread wurde von Moderator/in volkard aus dem Forum C++ 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.
-
So, ich habe jetzt noch bemerkt, dass wen ich die ganzen Nachrichten normal abarbeite, ohne Funktion, wie ich es eine seite vorher schon gepostet habe, funktioniert alles einwandfrei.
Allerdings war mein Ziel genau der gegenteil. Und zwar, dass ich mit der Funktion TranslateMsg alle Nachrichten korrekt abarbeiten kann. Auch WM_CREATE. Kann mir da jemand ein paar Tipps geben?