CallWindowProc () vs. Funktionszeiger
-
merker schrieb:
Besten Dank für die Antworten. In etwa geht es mir um das, was "........." geschrieben hat :
Wenn eine vordefinierte Fensterklasse (z.B. BUTTON, EDIT, ...) "gesuperclassed" wird, lässt sich dann die "lpfnWndProc" der Basisklasse auch via Funktionszeiger aufrufen ?
Nein! Tu es nicht... Das Problem ist, dass Du nicht weißt wann hier eine Struktur eingerichtet wird und kein direkter Funktionszeiger.
Aber warum willst Du das denn überhaupt? Nimm einefach immer CallWindowProc und gut ists...
-
Also hier die detailierte Begründung:
http://blog.m-ri.de/index.php/2007/10/19/warum-eigentlich-callwindowproc-aufrufen-wenn-man-einen-zeiger-auf-die-alte-wndproc-hat/
-
Ich verwende auch CallWindowProc() wenn ich ein Window-Prozedur gesubclasst habe.
Die Frage von Merker mit dem direkten Funktionsaufruf hatte ich mir auch schon gestellt, habe es aber bei der Standard-Vorgehensweise belassen.
Daher bin ich auf den Blog von Martin Richter gespannt, was für Seiteneffekte es hierbei geben kann.
Martin
P.S.: Sind Subclassing und Superclassing das gleiche gemeint?
-
Martin Richter schrieb:
Also hier die detailierte Begründung:
http://blog.m-ri.de/index.php/2007/10/19/warum-eigentlich-callwindowproc-aufrufen-wenn-man-einen-zeiger-auf-die-alte-wndproc-hat/@Martin: Perfekte Erklärung! Wieder was gelernt und den "Windows-Nebel" für "Normal"-Programmierer ein wenig gelichtet. You've got my 5!
Martin
-
Mmacher schrieb:
P.S.: Sind Subclassing und Superclassing das gleiche gemeint?
Schon wieder was für mein Blog!
Aber nein! Das ist schon erklärt in der MSDN:
http://msdn2.microsoft.com/en-us/library/ms633569.aspxAlso im Prinzip sind sie ähnlich. Aber doch vom Verfahren sehr unterschiedlich und damit auch von der Anwendung.
Superclassing: Man verwendet eine bestehende Fensterklasse und registriert basierend auf dieser eine eigene neue. Der Vorteil man bekommt auch die allererste Windows Nachricht mit (WM_CREATE etc.) Meistens handelt es sich bei dem Basis-Fenster eine Standardklasse (Edit, Button)
Der Weg dahin:
- GetClassInfo
- Eigene Daten eintragen, alte WndProc merken.
- RegisterClass mit neuer Klasse
- CreateWindowSubclassing: Das Fenster existiert bereits und man hängt sich in die bestehende Kette der Fensterprozeduren ein.
Subclassing wird manchmal auch einfach nur pauschal angewendet, weil man an einer bestimmten Nachricht grundsätzlich Interesse hat und diese abfangen möchte.
z.B. WM_CTLCOLOR... z.B. zentral behandeln, eigene Resizer Klasse bauen...HTH
-
Dann lässt sich die Funktionszeigervariante einsetzen, wenn man ganz sicher ist, dass es sich bei der "lpfnWndProc" auch um eine Adresse handelt, die "angesprungen" werden kann ?
Ich frage nur deshalb, weil diese Variante "offensichtlich" perfekt funktioniert. Aber "funzt doch !" ist leider kein ausreichendes Testverfahren.
-
Ich frage mich warum Di so scharf bist auf die Zeigervariante?
Ja, sicher, wenn Du:
1. Wirklich weißt, dass es ein Funktionszeiger ist geht es, aber wie willst Du das wissen? Evtl. haben die Strukturen auch einen Pseudo Thunk.
2. Musst Du in jedenfall im selben Thread sein und nicht auf die Idee kommen ohne SendMessage diesen Zeiger zu verwenden! Wenn Du an solch einen Schweinskram denken solltest.Allerdings bewegst Du Dich in Bereichen, die ich als unseriös und gefährlich ansehe. Wäre ich Dein Projektleiter würde ich Dir die Hammelbeine langziehen.
-
Meine Hammelbeine sind bereits so lang, dass ich immer runtergucken muss wenn jemand was von mir will.
Gut, (1.) ist akzeptiert, auch weil man sich nicht sicher sein kann, ob CallWindowProc () ev. mehr macht als "nur" die "lpfnWndProc" aufzurufen.
Zu (2.) nur soviel : Die Zeigervariante würde einen Api-Hook auf CallWindowProc () völlig wirkungslos machen.
Sowas ist kein "Schweinskram", ganz im Gegenteil sogar.
-
Es ist Schweinskram und bleibt es.
Weil zum Beispiel genug Maussoftware für die Features der Scrollmaus auch Hooks einsetzt. Dito andere Steuerungssoftware.
Was nützt es Dir wenn Du so Hooks umgehst? Andere Low Level Hooks kannst Du nicht austricksen wenn Du Spy Software damit umgehen willst
-
... und da fällt mir noch etwas ein.
Da eindeutig CallWindowProc verwendet werden soll, kann Microsoft jederzeit die Technik ändern und das was GWL_WNDPROC returniert zu etwas noch ganz anderem machen! Dein Programm würde in jedem Fall fürchterlich abrauchen...
An solchen Inkompatibilitäten kann niemand Interesse haben. Du nicht, Dein Chef nicht, Dein Kunde nicht...
Insbesondere Deine Hammelbeine nicht, die dann garantiert etwas länger gemacht werden, mögen sie auch noch so eine beträchtliche Länge haben...
-
Martin Richter schrieb:
Schon wieder was für mein Blog!
meinst du das mit dem Deppenapostroph (Martin’s Blog)??
-
richtig falsch schrieb:
Martin Richter schrieb:
Schon wieder was für mein Blog!
meinst du das mit dem Deppenapostroph (Martin’s Blog)??
reicht es nicht, ein top-winapi coder zu sein oder muss man auch noch perfekt deutsch können?
-
richtig falsch schrieb:
Martin Richter schrieb:
Schon wieder was für mein Blog!
meinst du das mit dem Deppenapostroph (Martin’s Blog)??
Genau! In diesem Fall stehe ich zu der englischen Schreibweise mit "Deppenapostroph" ... , ursprünglich hatte ich den Bog englisch angelegt, dann wäre die Schreibweise korrekt. Ich bin doch bei dem Titel geblieben nachdem ich mich doch für Deutsch als Blog-Sprache entschieden hatte...
Man muss mein Bog ja nicht lesen, wenn es so stört, dass einem davon schlecht wird.
Aber wer weiß, wenn man mich noch mal nett anfragt zu der Schreibweise und das Ganze auch nicht anonym macht. Kann ja sein, dass ich da mal was ändere...
-
Bzgl. des Deppenapostophes:
Siehe Wikipedia:
http://de.wikipedia.org/wiki/Apostrophitis#Der_englische_Genitiv_als_Ausnahme_im_DeutschenIn der überarbeiteten Fassung des Dudens (August 2006) wird bei Personennamen der Genitiv mit Apostroph geduldet. Der Sinn dieser neuen Schreibtoleranz wird derzeit diskutiert und regt die Presse zu Abhandlungen in Kommentaren und Glossen an.
Wenn es der Duden schon duldet!
-
Martin Richter schrieb:
Da eindeutig CallWindowProc verwendet werden soll, kann Microsoft jederzeit die Technik ändern und das was GWL_WNDPROC returniert zu etwas noch ganz anderem machen!
Dein Programm würde in jedem Fall fürchterlich abrauchen...
An solchen Inkompatibilitäten kann niemand Interesse haben. Du nicht, Dein Chef nicht, Dein Kunde nicht...Das Argument zieht auf den ersten Blick immer.
Gegeben sei aber mal folgender Code : (Sinn und Zweck des Codes ist nicht das Thema !)
#define STRICT #include <windows.h> typedef LRESULT (CALLBACK *typ_1) (HWND,UINT,WPARAM,LPARAM); //----------------------------------------------------------------------------- LRESULT CALLBACK WndProc ( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { //----------------------------------------------------------------------------- MessageBox (0,"WndProc","Hinweis",0); return 0; } //----------------------------------------------------------------------------- WINAPI WinMain ( HINSTANCE, HINSTANCE, LPSTR, int ) { //----------------------------------------------------------------------------- typ_1 meine_cwp = WndProc; CallWindowProc ((WNDPROC) WndProc,(HWND) 1,2,3,4); meine_cwp ((HWND) 1,2,3,4); return 0; }
CallWindowProc () und meine_cwp () bewirken genau das gleiche : Lediglich einen Aufruf von "WndProc" mit vier Parametern.
Sollte Microsoft vorhaben daran etwas zu ändern, dann würde das Auswirkungen auf sämtlichen Code haben, der "aufwärtskompatibel" geschrieben wurde.
Somit zieht das Argument nicht mehr ganz so stark.Es mag doch unwichtig sein ob die "WndProc" nun selbst implementiert oder vom Betriebssystem vorgegeben ist. Hauptsache, sie lässt sich mit vier Parametern (hwnd,msg,wparam,lparam) anspringen.
Die MSDN warnt davor, dass es sich bei der zurückgelieferten "WndProc" in einigen Fällen auch um die Adresse einer Struktur handeln kann.
Nur dann hätte doch die Zeigervariante abrauchende und hammelbeinverlängernde Auswirkungen ?
-
Martin Richter schrieb:
Wenn es der Duden schon duldet!
Das will gar nichts heißen :p
Dennoch, ich möchte dich hiermit freundlich und nicht anonym darauf aufmerksam machen, daß das Apostroph vor dem Genitiv-'s', zumindest im deutschsprachigen Kontext, nicht verwendet werden sollte
-
merker schrieb:
[Das Argument zieht auf den ersten Blick immer.
Gegeben sei aber mal folgender Code : (Sinn und Zweck des Codes ist nicht das Thema !)
#define STRICT #include <windows.h> typedef LRESULT (CALLBACK *typ_1) (HWND,UINT,WPARAM,LPARAM); //----------------------------------------------------------------------------- LRESULT CALLBACK WndProc ( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { //----------------------------------------------------------------------------- MessageBox (0,"WndProc","Hinweis",0); return 0; } //----------------------------------------------------------------------------- WINAPI WinMain ( HINSTANCE, HINSTANCE, LPSTR, int ) { //----------------------------------------------------------------------------- typ_1 meine_cwp = WndProc; CallWindowProc ((WNDPROC) WndProc,(HWND) 1,2,3,4); meine_cwp ((HWND) 1,2,3,4); return 0; }
CallWindowProc () und meine_cwp () bewirken genau das gleiche : Lediglich einen Aufruf von "WndProc" mit vier Parametern.
Sollte Microsoft vorhaben daran etwas zu ändern, dann würde das Auswirkungen auf sämtlichen Code haben, der "aufwärtskompatibel" geschrieben wurde.
Somit zieht das Argument nicht mehr ganz so stark.Der Aufruf, den Du hier machst ist irregulär. Erlaubt ist CallWndProc nur mit einer gültigen Fensterprozedur. Und das ist eine die Du mit GetClassInfo bekommst, oder mit GWL_WNDPROC.
Was Du hier machst ist gebastel!