The one and only 'WndProc' ?
-
Xzibit schrieb:
Morgen Zusammen,
jetzt mal ne blöde Frage von mir an der Stelle:
Wenn ich ein Fenster erstelle, so brauche ich dazu erst einmal eine Fensterklasse, die ich z.B. per RegisterClassEx registriere. Der WNDCLASSEX-Struktur übergebe ich dabei ja einen Zeiger auf meine eigene Fensterprozedur (WndProc), in der ich dann empfangene Nachrichten über einen switch-case Block auswerten und darauf reageren kann. Soweit klar.Wenn ich jetzt ein neues Steuerelement, sagen wir mal, einen Button auf dem gerade zuvor erstellten Fenster erstelle - dann handelt es sich dabei doch um ein eigenständiges Fenster (Child-Window), das in mein Fenster quasi eingepflanzt wurde. Hat dieser Button jetzt seine eigene 'WndProc' ? Oder werden auch die Nachrichten an den Button durch "meine" WndProc, gejagt ? (inklusive die Nachrichten für 'neu zeichnen', etc.)
Und wenn, dann ist doch 'Subclassing' nur bei fremden Applikationen sinnvoll, die man 'fernsteuern' will, oder ? Ich meine, wenn das Fenster bereits zu meiner Applikation gehört, dann habe ich doch sowieso Zugriff auf die WndProc.
Grüße, Xzi-bit
Nein so ist das nicht. Wenn du eine Fenster als Child definierst dann ist es eben das "Kind" deines Fensters und wenn du auf das Buttonfenster klickst dann wird die Windowsmessage WM_COMMAND versendet die wird aber an den Parenthandle also in deinem fall wahrscheinlich hWnd versendet. Dieses WM_COMMAND wird dann auch von der Botschaftsverarbeitung(WndProc) deines Fensters angenommen weil das Child ja alle Botschaften an sein ParentHandle sendet. Übrigens wenn du dann noch herausfinden auf welches Buttonfenster geklickt wurde: lParam übergibt dies.
Zusammenfassung: Ein Child sendet alle seinen empfangenen Botschaften an seinen Parent und damit an sein WndProc. Diese Botschaft lautet WM_COMMAND.
-
C-Chris schrieb:
Zusammenfassung: Ein Child sendet alle seinen empfangenen Botschaften an seinen Parent und damit an sein WndProc. Diese Botschaft lautet WM_COMMAND.
Nein, das ist quatsch! Ein Button wird beispielsweise durch die Nachricht WM_PAINT neugezeichnet. Diese Nachricht bekommt Dein Parent niemals zusehen (also die WM_PAIN-Nachrichten, die für den Button bestimmt sind. Solche, die das Neuzeichnen, des Parents selbst regeln, kommen selbstverständlich an, aber die haben ja nichts mit dem Button zu tun -ich wiederhole mich-). Eine gewissen Ausnahme bildet der Sonderfall 'WM_PARENTNOTIFY' (siehe: http://msdn2.microsoft.com/en-us/library/ms632638.aspx). Wobei dieses Style-Flag auch erst explizit gesetzt werden muss und auch dann nur für einen Bruchteil aller Fensternachrichten gilt. WM_COMMAND wird nur aufgrund bestimmter Benutzerereignisse gesendet (siehe MSDN).
Zusammenfassung: Jedes vordefinierte Control hat eine vom System definierte WndProc. Diese arbeitet für jeden Button die anfallenden Nachrichten nach einem Standard-Muster ab. Will man dieses Muster ändern, muss man subclassen (mal abgesehen, von den wenigen anderen Modifikationsmöglichkeiten wie WM_SETFONT).
Ergänzung: Besonder deutlich wird dieses Prinzip durch die Funktion DefWindowProc(...), die nicht bearbeitete Nachrichten eines Fenster ebenfalls durch eine Standard-Behandlung bearbeitet.
-
CodeFinder schrieb:
C-Chris schrieb:
Zusammenfassung: Ein Child sendet alle seinen empfangenen Botschaften an seinen Parent und damit an sein WndProc. Diese Botschaft lautet WM_COMMAND.
Nein, das ist quatsch! Ein Button wird beispielsweise durch die Nachricht WM_PAINT neugezeichnet. Diese Nachricht bekommt Dein Parent niemals zusehen (also die WM_PAIN-Nachrichten, die für den Button bestimmt sind. Solche, die das Neuzeichnen, des Parents selbst regeln, kommen selbstverständlich an, aber die haben ja nichts mit dem Button zu tun -ich wiederhole mich-). Eine gewissen Ausnahme bildet der Sonderfall 'WM_PARENTNOTIFY' (siehe: http://msdn2.microsoft.com/en-us/library/ms632638.aspx). Wobei dieses Style-Flag auch erst explizit gesetzt werden muss und auch dann nur für einen Bruchteil aller Fensternachrichten gilt. WM_COMMAND wird nur aufgrund bestimmter Benutzerereignisse gesendet (siehe MSDN).
Zusammenfassung: Jedes vordefinierte Control hat eine vom System definierte WndProc. Diese arbeitet für jeden Button die anfallenden Nachrichten nach einem Standard-Muster ab. Will man dieses Muster ändern, muss man subclassen (mal abgesehen, von den wenigen anderen Modifikationsmöglichkeiten wie WM_SETFONT).
Ergänzung: Besonder deutlich wird dieses Prinzip durch die Funktion DefWindowProc(...), die nicht bearbeitete Nachrichten eines Fenster ebenfalls durch eine Standard-Behandlung bearbeitet.
Aha.
Mobbing.
Aha.
Doch kein Mobbing.
-
Wenn jedes Childwindow seine eigne Meldungsverarbeitungschleife hat wie ist es dann möglich dass der Parent WM_COMMAND erhält? Du behauptest (was wahrscheinlich auch richtig) ist dass jedes Fenster seine eigne Botschaftsverarbeitung hat(eine von Windows generierte) aber wieso erhaltet den dann mein Hauptfenster dieses WM_COMMAND ???
-
Das Dialogfenster verarbeitet die Nachrichten (WM_KEYDOWN, WM_MOUSEMOVE und ähnliche) selber - als Resultat kann es durchaus eigene Nachrichten wie WM_COMMAND weiterschicken.
PS: Bitte nicht schreien, damit machst du dich nur unbeliebt.
-
japs, genau, bin direkt beleidigt #gg
stell dir vor ein button wuerde das klick nicht selber verarbeiten, muesste der parent dann sagen "zeichne dich gedrueckt, zeichne ein rahmen, blinke noch n bissl rum, zeichne nicht gedrueckt" #gg
jede aktion eines fensters {auch wenns nur ne mausbewegung darueber ist {da es dann neu gezeichnet werden muss} oder ein focus wechsel, behandelt jedes fenster fuer sich, und sended bei bedarf {zb bei einem klick} eine message an das parent
this->GetParent()->SendMessage(WM_CLICK, MyId, lParam); usw usw
-
C-Chris schrieb:
Wenn jedes Childwindow seine eigne Meldungsverarbeitungschleife hat wie ist es dann möglich dass der Parent WM_COMMAND erhält? Du behauptest (was wahrscheinlich auch richtig) ist dass jedes Fenster seine eigne Botschaftsverarbeitung hat(eine von Windows generierte) aber wieso erhaltet den dann mein Hauptfenster dieses WM_COMMAND ???
Weil zur Standardprozedur der ChildWindows eben der Befehl "SendMessage (hParent, WM_COMMAND)" (oder so ähnlich) gehört.
-
jedes fenster hat eigene prozedur
Jungs, jetzt mal ne' ganz andere Frage dazu:
Wenn schon jedes Fenster (Button, TreeView, Liste, etc.) eine eigene Prozedur hat, wie heißt denn die z.B. standardmäßig beim Button ?
Ich meine - wenn ich gerade keinen Bock darauf habe für MEIN Fenster eine Nachricht zu implementieren, so kann ich einfach DefWindowProc() aufrufen.
Aber wie heißt die Funktion unter Windows, die für meinen Button die Nachrichtenbehandlung standardmäßig durchführt ? Hat da jemand eine Ahnung von ?Greetings, Xzi-bit
-
Das "Pendant" zu DefWindowProc () heißt CallWindowProc (). Den "pPrevWndFunc" erhält man z.B. durch GetClassInfoEx (...,"BUTTON",...).
Der Einsatz dieser Funktionen ist aber nur sinnvoll wenn der Button gesub- oder superclassed wurde.
-
Ok, danke. Ich hab übrigens die zugehörigen internen Windows-Funktionsnamen gefunden. Die Windows-interne 'WndProc' für einen Button lautet 'ButtonWndProc', die für eine CheckListe 'CheckListWndProc', usw. usf.
Danke an Alle nochmals
Greetings, Xzi-bit
-
Mr Evil schrieb:
japs, genau, bin direkt beleidigt #gg
stell dir vor ein button wuerde das klick nicht selber verarbeiten, muesste der parent dann sagen "zeichne dich gedrueckt, zeichne ein rahmen, blinke noch n bissl rum, zeichne nicht gedrueckt" #gg
jede aktion eines fensters {auch wenns nur ne mausbewegung darueber ist {da es dann neu gezeichnet werden muss} oder ein focus wechsel, behandelt jedes fenster fuer sich, und sended bei bedarf {zb bei einem klick} eine message an das parent
this->GetParent()->SendMessage(WM_CLICK, MyId, lParam); usw usw
Tut mir direkt Leid. Habe es rückgäning gemacht.
-
CStoll schrieb:
Das Dialogfenster verarbeitet die Nachrichten (WM_KEYDOWN, WM_MOUSEMOVE und ähnliche) selber - als Resultat kann es durchaus eigene Nachrichten wie WM_COMMAND weiterschicken.
PS: Bitte nicht schreien, damit machst du dich nur unbeliebt.
Dann hat mein Buch wohl doch nicht gelogen. Dann ist das garkein so grosser "Quatsch".
Zum "schreien": Hat aufgehört-
-
Mr Evil schrieb:
jedes fenster hat eigene prozedur
fuer ein button zb ware im paint das zeichnen des textes, farbverlauf usw, das hast du in deiner main prozedur nicht da sich jedes fenster um sich selber kuemmert
subclassing lohnt sich immer dann wenn du an eine message willst welche nicht ans parent weiter geleitet wirdMr Evil hat ausserdem auch gesagt dass die Botschaften an den Parent weitergeleitet werden.