Pointer auf WndProc



  • Ich versuche gerade, zu Übungszwecken (Methoden, Objekte und deren Freunde sind mir nicht so nahe...), die WinAPI-Funktionen in Klassen "abzufüllen". 🙂

    Ich habe nun aber ein kleines Problem geortet, das ich bisher nicht lösen konnte:

    Normalerweise gehört zu einem Fenster ja auch eine entsprechende Nachrichten-Funktion (WndProc). Bei der Registrierung der Fensterklasse wird diese Funktion in wc.lpfnWndProc mit einer Referenz definiert.

    wclpfnWndProc=WndProc;
    

    Nun ist bei mir diese Funktion in der selben Klasse enthalten wie auch die Funktion welche das Fenster registriert. Ich muss also einen Pointer auf diese Methode(WndProc) der Klasse(CFenster) angeben.
    Ich dachte das ginge so:

    wWndclass.lpfnWndProc=(WNDPROC)(&CFenster::WndProc);
    

    Leider läuft diese Tour aber nicht, was mache ich falsch?

    fenster.h:

    // * fenster.h * //
    
    #ifndef _WINDOWS_
    	#include <windows.h>
    #endif
    
    class CFenster
    {
    public:
    	bool bAborted;
    	HWND hHandle;
    	MSG mMsg;
    	WNDCLASS wWndclass;
    	struct{int iX;int iY;}sDimension,sPosition;
    
    	//Konstruktor
    	CMJ_Fenster(void)
    	{
    		this->sDimension.iX=100;
    		this->sDimension.iY=100;
    		this->sPosition.iX=0;
    		this->sPosition.iY=0;
    		this->bAborted=false;
    	}
    
    	LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
    	{
    		switch(message)
    		{
    			case WM_DESTROY : PostQuitMessage(0); this->Aborted=true; return 0;
    
    		}
    
    		return DefWindowProc(hWnd,message,wParam,lParam);
    	}
    
    	void FensterErstellen(void)
    	{
    
    		wWndclass.style		= CS_HREDRAW|CS_VREDRAW;
    		wWndclass.lpfnWndProc	= (WNDPROC)(&CFenster::WndProc);
    		wWndclass.cbClsExtra	= 0;
    		wWndclass.cbWndExtra	= 0;
    		wWndclass.hInstance	= 0;
    		wWndclass.hCursor	= LoadCursor(NULL,IDC_ARROW);
    		wWndclass.hIcon		= LoadIcon(NULL,IDI_APPLICATION);
    		wWndclass.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
    		wWndclass.lpszClassName	= TEXT("Testprogramm");
    		wWndclass.lpszMenuName	= NULL;
    		RegisterClass(&wWndclass);
    
    		hHandle=CreateWindow(	TEXT("Testprogramm"),
    					TEXT("Testprogramm"),
    					WS_OVERLAPPEDWINDOW,
    					CW_USEDEFAULT,
    					CW_USEDEFAULT,
    					CW_USEDEFAULT,
    					CW_USEDEFAULT,
    					NULL,
    					NULL,
    					0,
    					NULL);
    
    		ShowWindow(this->hHandle,SW_SHOWNORMAL);
    		UpdateWindow(this->hHandle);
    	}
    };
    

    main.cpp:

    #include "fenster.h"
    
    int main(void)
    {
    	CFenster Fenster1,Fenster2;
    
    	Fenster1.FensterErstellen();
    	Fenster2.FensterErstellen();
    
    	while(GetMessage(&Fenster1.mMsg,NULL,0,0)||GetMessage(&Fenster2.mMsg,NULL,0,0))
    	{
    		TranslateMessage(&Fenster1.mMsg);
    		DispatchMessage(&Fenster1.mMsg);
    		TranslateMessage(&Fenster2.mMsg);
    		DispatchMessage(&Fenster2.mMsg);
    
    		if(Fenster1.bAborted==true&&Fenster2.bAborted==true)
    			break;
    	}
    }
    


  • Suchfunktion



  • @Der_NUTzLoSe:
    Öhm gute Antwort. Nette kompetente Hilfe 😛



  • Naja...-Ich habe zumindest die Antwort jetzt raus:
    Die Nachrichten-Schleife muss offenbar immer static sein. Dummerweise ist in einer Methode, welche als static deklariert ist, jeweils kein This-Pointer verfügbar, aber auch der lässt sich nachbilden...

    fenster.h:

    #include <windows.h>
    
    class CFenster
    {
    public:
    	HWND hHandle;
    	WNDCLASS wWndclass;
    	MSG mMsg;
    	bool bDestroyed;
    
    	LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
    	{
    		switch(message)
    		{
    			case WM_DESTROY:
    			{
    				PostQuitMessage(0);
    				this->bDestroyed=true;
    				return 0;
    			}
    		}
    
    		return DefWindowProc(hWnd,message,wParam,lParam);
    	}
    
    	static LRESULT CALLBACK WndProc_static(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
    	{
    		if(message==WM_CREATE)
    		{
    			SetWindowLong(hWnd,GWL_USERDATA,(LONG)((LPCREATESTRUCT)lParam)->lpCreateParams);
    		}
    
    		CFenster *pThis=(CFenster*)GetWindowLong(hWnd,GWL_USERDATA);
    
    		if(pThis==0)
    		{
    			return DefWindowProc (hWnd,message,wParam,lParam);
    		}
    		else
    		{
    			return pThis->WndProc(hWnd,message,wParam,lParam);
    		}
    	}
    
    	void FensterErstellen(void)
    	{
    		wWndclass.style		= CS_HREDRAW|CS_VREDRAW;
    		wWndclass.lpfnWndProc	= WndProc_static;
    		wWndclass.cbClsExtra	= 0;
    		wWndclass.cbWndExtra	= 0;
    		wWndclass.hInstance	= 0;
    		wWndclass.hCursor	= LoadCursor(NULL,IDC_ARROW);
    		wWndclass.hIcon		= LoadIcon(NULL,IDI_APPLICATION);
    		wWndclass.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
    		wWndclass.lpszClassName	= TEXT("Name-der-Fensterklasse");
    		wWndclass.lpszMenuName	= NULL;
    		RegisterClass(&wWndclass);
    
    		hHandle=CreateWindow(	TEXT("Name-der-Fensterklasse"),
    					TEXT("Fenstertitel"),
    					WS_OVERLAPPEDWINDOW,
    					0,
    					0,
    					500,
    					500,
    					NULL,
    					NULL,
    					0,
    					this);
    
    		this->bDestroyed=false;
    
    		ShowWindow(this->hHandle,SW_SHOW);
    		UpdateWindow(this->hHandle);
    	}
    };
    

    main.cpp:

    #include "fenster.h"
    
    void main(void)
    {
    	CFenster MeinFenster;
    
    	MeinFenster.FensterErstellen();
    
    	while(!MeinFenster.bDestroyed)
    	{
    		if(PeekMessage(&MeinFenster.mMsg,NULL,0,0,PM_REMOVE))
    		{
    			TranslateMessage(&MeinFenster.mMsg);
    			DispatchMessage(&MeinFenster.mMsg);
    		}
    	}
    }
    

Anmelden zum Antworten