Fensterfunktionen in eine Klasse packen
-
Naja, das würde wohl gehen, aber was ist, wenn ich zu einer bereits behandelten Nachricht noch etwas hinzufügen will? In Deinem Fall beendet sich die abgeleitete WndProc sofort, nachdem die Nachricht verarbeitet wurde. Aber die Basisfunktion soll ja in jedem Fall immer mit aufgerufen werden. Nehmen wir an, ich möchte, bevor sich das Fenster schließt, noch eine Message-Box anzeigen. Dann wird WM_CLOSE sowohl in meiner abgeleiteten Funktion behandelt (Message-Box anzeigen), als auch in der Basisfunktion (Schließen durchführen). (Und ich will ja nicht den eigentlichen Schließvorgang komplett neu schreiben müssen, wenn ich zu WM_CLOSE einfach nur eine Aktion hinzufüge.)
Wie macht das eigentlich die MFC? Da ist es doch auch so, daß man jegliche Nachrichten abfangen kann und danach einfach die Nachrichtenfunktion der Basisklasse aufruft. (Es gibt sogar eine eigene, ableitbare WindowProc.) Und alle Funktionen sind void. Wie erkennt das Programm da, ob es in letzter Instanz noch die DefWindowProc aufrufen muß?
-
Ich wär's mal wieder. Ich hab jetzt ein neues Problem. Doch zuerst eine Frage: Wohin packt man den Aufruf, wenn man einen Button erstellen will? Gleich unter den Aufruf, der das Fenster erstellt hat oder in die WndProc unter WM_CREATE?
Mein Problem ist folgendes:#include <windows.h> class Window { public: Window () { //Das gleiche wie immer: Fenster registrieren //... window=CreateWindowEx (...); SetWindowLong (window, GWL_USERDATA, reinterpret_cast<LONG> (this)); } virtual int Start (int showCmd) { //... } protected: virtual bool WindowProc (UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { //Das hier funktioniert nicht: case WM_CREATE: button=CreateWindow ("Button", "Button", WS_CHILD|WS_VISIBLE, 0, 0, 100, 50, window, NULL, GetModuleHandle (NULL), NULL); break; //... } return true; } private: HWND window; /*static*/ HWND button; static LRESULT CALLBACK StaticWindowProc (HWND window, UINT message, WPARAM wParam, LPARAM lParam) { //Das hier würde funktionieren: /*if (message==WM_CREATE) button=CreateWindow ("Button", "Button", WS_CHILD|WS_VISIBLE, 0, 0, 100, 50, window, NULL, GetModuleHandle (NULL), NULL);*/ Window *thisWindow=reinterpret_cast<Window *> (GetWindowLong (window, GWL_USERDATA)); return thisWindow && thisWindow->WindowProc (message, wParam, lParam)?0: DefWindowProc (window, message, wParam, lParam); } }; /*HWND Window::button=NULL;*/ int WINAPI WinMain (HINSTANCE instance, HINSTANCE, LPSTR, int showCmd) { Window w; return w.Start (showCmd); }Wenn ich in den Button in der virtuellen WindowProc erstelle, funktioniert das nicht. Gehe ich direkt in die statische Funktion und mache das gleiche, funktioniert es. Wie kommt das? Die statische Funktion ruft doch die dynamische sowieso auf. Wenn ich es dagegen in den Konstruktor schreibe, funktioniert es wieder. Doch ich habe es so gelesen, als müsse es unter WM_CREATE stehen.
-
Schau dir den Ansatz mal an: http://turing.fh-landshut.de/~jamann/IMB/IMB.html
-
hola
haett da zu der klsse mal ne frage:
muss man nicht, wenn man mehrere von den window-klassen erstellt, jeweils einen neuen ClassName der RegisterClass uebergeben? ansonsten kann er die klasse ja nur einmal registrieren oder?
wenn man nun die klasse nur einmal registrieren kann, dann kann man auch den Style von einem Window nicht aendern, da sich die aenderung auf alle beziehen wuerde. stimmt das so ?Meep Meep
-
Jo clör.
Naja: Ein Objelt der Klasse entspricht halt einem Fenster.
-
gilt dann der ClassName nur fuer den jeweiligen process oder systemweit ?
ansonsten kanns doch mal vorkommen, das 2 unterschiedliche programme den gleichen ClassName benutzen.Meep Meep
-
Meep Meep schrieb:
gilt dann der ClassName nur fuer den jeweiligen process oder systemweit ?
ansonsten kanns doch mal vorkommen, das 2 unterschiedliche programme den gleichen ClassName benutzen.Meep Meep
systemweit<<
Jops, das kann passieren, es gibt aber auch UnregisterClass(...).
-
CodeFinder schrieb:
Meep Meep schrieb:
gilt dann der ClassName nur fuer den jeweiligen process oder systemweit ?
ansonsten kanns doch mal vorkommen, das 2 unterschiedliche programme den gleichen ClassName benutzen.Meep Meep
systemweit<<
Jops, das kann passieren, es gibt aber auch UnregisterClass(...).naja ob das so gut ist, wenn man eine fremde klasse unregistriert, nur weil sie den gleichen namen hat so wie mein ?
angenommen jemand verwendet mein programm und hat ein anderes bei sich laufen das den gleichen klassennamen hat. dann kann er mein programm einfach nicht verwenden?Meep Meep
-
Schau dir den Ansatz mal an: http://turing.fh-landshut.de/~jamann/IMB/IMB.html
Uff. Also, ich hatte eigentlich nicht vor, mich durch eine komplette Klassenbibliothek zu kämpfen. Mir ging es einfach nur darum, zu wissen, wieso ich in der eigentlichen statischen WndProc einen Button erzeugen kann, das aber nicht geht, wenn ich es in einer nicht-statischen Funktion mache und diese von der statischen aufrufen lasse.
Außerdem müßte ich wissen, ob es o.k. ist, in meinem Beispiel den Button im Konstruktor zu erzeugen oder ob das immer in der WndProc bei der Nachricht WM_CREATE geschehen muß.
-
NES-Spieler schrieb:
Außerdem müßte ich wissen, ob es o.k. ist, in meinem Beispiel den Button im Konstruktor zu erzeugen oder ob das immer in der WndProc bei der Nachricht WM_CREATE geschehen muß.
Kannst du auch im Konstruktor erstellen. Klar. Wenn zu dem Zeitpunkt ein gültiger Parent-Handle zur Verfügung steht.
-
Wieso wird das dann überhaupt in WM_CREATE erstellt und nicht (bei nicht-objekt-orientierter Programmierung) direkt in der WinMain?
-
Du kannst beies machen...aber denk daran das du in deiner WndProc meistens die Handle der Child-Wnd's brauchst...und globale Variablen sollte man vermeiden
.