Winproc in Klasse
-
Hi
Genau so wie das Thema heißt gibst natürlich schon einen sehr ausführliches Thema im FAQ. Das hab ich mir auch durchgelesen und komm zum Schluß: Das geht nur sehr unschön. Entweder ich Pack eine eigentliche Winproc nicht in in meine Klasse oder misch mit Assembler rum. Ok schön.
Meine Frage dazu. Das muss doch noch irgendwie anders gehen (?). Wie macht es es denn die MFC, das ist auch eine Klassen-Oberfläche auf Winapi, und hier sind Klassen auch ableitbar, was mit der Assemblerlösung nicht geht?
Und ich muss zugeben ich versteh auch nicht so 100% das Grundproblem. Denn das eigentliche Problem ist ja das Windowclass einen Funktionspointer haben will, auf eine Funktion die so einen Returnwert hat:
return DefWindowProc (hwnd, message, wParam, lParam) ;
So wenn ich jetzt eine
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
in meine Klasse intergier, bringt er ja immer eine Fehlermeldung bei:
wndclass.lpfnWndProc = WndProc ;
Er kann den keinen passenden Typcast durchführen oder so. (egal ob die Winproc static ist oder nicht)
Ich hoff das ich jetzt nicht Sachen wiederhol die schon oft gesagt wurden. Dass das was ich da oben zeig nicht geht, ist mir schon länger bewußt, aber warum? Und das versteh ich auch nicht aus dem FAQ.
Was erwartet die Wndclass vom dem Funktionspointer?
Wenn man etwas Assembler einfügt, gehts ja dann, das hab ich auch geschafft. Aber mir ist noch nicht ganz klar warum so ja, aber so nicht. Was denkt sich die Winapi und der Compiler dabei?
Wo ist das Problem, das es nicht so einfach geht, wie man es so unbedarft erwarten könnte?Mir wäre amliebsten ich könnte eine schöne Klasse erschaffen, von der ich mir dann immer meine Fenster ableiten kann. Dann hab ich nämlich erstmal geschafft meinen Main-Quellcode klein zu halten, weil der ganze win32 schroot in ner Klassse versteckt ist. Und ich kann die Klasse immer wieder verwenden.
Vielen Dank für jegliche Erklärungsversuche
Grüße
Flow
-
<schleichwerbung>Meine WinAPI-Wrapper Klasse lässt sich ableiten... :)</werbung>
Dir ist wohl eine Eigenschaft von Funktionszeigern auch Methoden nicht ganz klar. Wenn du eine Methode in einer Klasse hast (nicht static), dann kannst du doch in dieser Funktion auf die Element-Variablen der Klasse zugreifen. Was meinst du, wie der Compiler das macht?
Die Funktion hast du zwar so definiert:class Foo { public: LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); };
Der Compilter macht daraus aber sowas (Pseudocode):
class Foo { public: LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, Foo*const this); };
Diese Funktion sieht aber definitiv nicht so aus, wie die WinAPI sie erwartet.
Dewegen klappt das so nicht.Wenn du die Funktion dagegen static deklarierst, sagst du dem Compiler: "Bitte lieber Compiler, lass den this-Zeiger weg."
Dann sieht die Funktion so aus wie die WinAPI sie erwartet. Allerdings kannst du jetzt logischerweise nicht mehr auf die Elementvariablen zugreifen.Wenn man aber die WndProc in der Klasse haben will, will man normalerweise auch auf die Elementvariablen zugreifen können. Das ist aber nur über die in der FAQ genannten Umwege möglich (es gibt sicher weitere).
-
-
Danke.
Allerdings habe ich inzwischen schon ein paar Bugs gefunden. Das ist nicht die neueste Version. Die hab ich noch nicht hochgeladen.
Diese Wrapper sind auch eher als Denkanstoß oder Beispiel gedacht. Es ist nur eine Möglichkeit von vielen.
-
Hi
Nochmal eine Frage, wenn gestattet. Soweit wie hier beschrieben is mir des jetzt auch klar. Vielen Dank soweit. Aber was erreicht man jetzt genau mit dem Assemlber code? Knipst man da dem Funktionspointer den this-pointer in der Argumenten liste ab, oder wie darf ich mir das vorstellen? Also was macht da Assembler, was c/c++ nicht kann?
Vielen Dank
Flow
-
Der Assemblercode aus dem Beitrag ist vollkommen schrott. Damit kannste noch nicht mal ein zweites Fenster erstellen.
-
Also...
in den globalen Bereich setzt du die Funtion
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
und in deiner Fensterklasse eine Funktion welche etwa so heisst:
LRESULT MessageFunktionMeinerKlasse( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
Nun leitest du die Nachrichten von der globalen Funktion zu der Instanz deines
Fensters.Das sollte funktionieren und ist die mir einfachste bekannte Art.