Problem mit Umleiten von einer FrameWndProc nach anderer FrameWndProc



  • Hallo! Ich will die WndProc so umleiten, dass ich Zugang zu Objektdaten habe, also this soll übergeben werden.

    class frame {
    protected:
    		HINSTANCE hInstance;
    		HWND hFrame, hClient;
    public:
    	frame(HINSTANCE h)
    	:hInstance(h), hFrame(0), hClient(0) {
            WNDCLASS wndclass;
    	wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    	wndclass.lpfnWndProc   = FakeFrameWndProc;
    	wndclass.cbClsExtra    = 0;
    	wndclass.cbWndExtra    = 0;
    	wndclass.hInstance     = hInstance;
    	wndclass.hIcon         = LoadIcon(0, /*...*/);
    	wndclass.hCursor       = LoadCursor(0, IDC_ARROW);
    	wndclass.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE + 1);
    	wndclass.lpszMenuName  = /*...*/;
    	wndclass.lpszClassName = /*...*/;
    
            hFrame = CreateWindow(/*...*/, /*...*/,
    				WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
    				CW_USEDEFAULT, CW_USEDEFAULT,
    				CW_USEDEFAULT, CW_USEDEFAULT,
    				0, 0, hInstance, this);
    }
    
            virtual LRESULT CALLBACK FrameWndProc(HWND, UINT, WPARAM, LPARAM) = 0;
    
    	static LRESULT CALLBACK FakeFrameWndProc(HWND h, UINT m, WPARAM w, LPARAM l) {
    			static frame* pf;
    			if(WM_CREATE == m)
    				pf = (frame*)(l);
    			return pf->FrameWndProc(h, m, w, l);
    		}
    

    Jetzt überlade ich die reelle FrameWndProc, so dass return pf->FrameWndProc(h, m, w, l); Sinn macht:

    class application: public frame {
    public:
    	application(HINSTANCE h)
    			:frame(h) {}
    
    	LRESULT CALLBACK FrameWndProc(HWND, UINT, WPARAM, LPARAM)
    {/* hier ist die Implementation der FrameWndProc MIT ZUGANG ZU DATEN VON application, bzw. frame */}
    };
    

    Problem: Die fake Prozedur arbeitet nicht korrekt:

    static LRESULT CALLBACK FakeFrameWndProc(HWND h, UINT m, WPARAM w, LPARAM l) {
    			static frame* pf;
    			if(WM_CREATE == m)
    				pf = (frame*)(l);
    			return pf->FrameWndProc(h, m, w, l); // pf bleibt 0
    		}
    

    In MSDN steht folgendes:

    lpParam
    [in] Pointer to a value to be passed to the window through the CREATESTRUCT structure (lpCreateParams member) pointed to by the lParam param of the WM_CREATE message. This message is sent to the created window by this function before it returns.

    Also, sollte WM_CREATE die erste Meldung sein. Trotzdem bleibt pf gleich 0. Warum? 😕



  • Ist meine Frage so schwierig, dass niemand hier sie beantworten kann? Ich dachte sie sind Profis 👎



  • WM_CREATE ist nicht die erste Nachricht die ein Fenster bekommt.



  • Schau Dir doch einfach mal an wie das andere Frameworks wie wxwidgedts, WTL oder MFC machen... dann wirst Du die ganze Problematik verstehen...
    Die MFC setzt um CreateWindow z.B. einen Hook um auch wirklich "alle" Messages zu bekommen...



  • -.- schrieb:

    WM_CREATE ist nicht die erste Nachricht die ein Fenster bekommt.

    Dann welche?



  • WM_NCCREATE, WM_NCCALCSIZE

    Und siehe auch Doku zu "CBTProc":

    It is possible to send messages to the newly created window, although it has not yet received WM_NCCREATE or WM_CREATE messages.

    Es kann sozusagen jede beliebige Nachricht ankommen, wenn sie Dir geschickt wird...



  • Hmmmm... komisch!
    Dann soll ich lieber globale Variablen benutzen, oder?



  • Die MFC nutzt um das "CreateWindow" herum ein CBTProc-Hook (Thread-Spezifisch, also TLS).



  • Jochen Kalmbach schrieb:

    Die MFC nutzt um das "CreateWindow" herum ein CBTProc-Hook (Thread-Spezifisch, also TLS).

    und setzt darin dann die passende WndProc...


Anmelden zum Antworten