Subclassing



  • Hallo,

    ich versuche gerade einen Button zu subclassen (sagt man so?), aber irgendwo ist wohl der Wurm drin. Die ButtonProc wird nicht aufgerufen.
    Vielleicht sieht ja jemand wo mein Fehler ist 🙂

    Hier mal der Code:

    #include <windows.h>
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM) ;
    LRESULT CALLBACK ButtonProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
    
    static LONG PrevWndProc;
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        PSTR szCmdLine, int iCmdShow)
    {
    	HWND     hwnd ;
    	MSG      msg ;
    	WNDCLASS wndclass ;
    
    	wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
    	wndclass.lpfnWndProc   = WndProc ;
    	wndclass.cbClsExtra    = 0 ;
    	wndclass.cbWndExtra    = 0 ;
    	wndclass.hInstance     = hInstance ;
    	wndclass.hIcon         = NULL ;
    	wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
    	wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
    	wndclass.lpszMenuName  = NULL;
    	wndclass.lpszClassName = "Test" ;
    
    	if (!RegisterClass (&wndclass))
    	{    
    		return 0 ;
    	}
    
    	hwnd = CreateWindow ("Test", "Test",
                             WS_OVERLAPPEDWINDOW,
                             CW_USEDEFAULT, CW_USEDEFAULT,
                             400, 250,
                             NULL, NULL, hInstance, NULL) ;
    
    	ShowWindow (hwnd, iCmdShow) ;
    	UpdateWindow (hwnd) ;
    
    	while (GetMessage (&msg, NULL, 0, 0))
    	{
    		TranslateMessage (&msg) ;
    		DispatchMessage (&msg) ;
    	}
    	return msg.wParam ;
    }
    
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        static HWND hButton;
    
    	switch (message)
    	{
            case WM_CREATE:
            {
                hButton = CreateWindow ("BUTTON", "Test", 
                                        WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
                                        20, 20, 100, 40,
                                        hwnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
    
                PrevWndProc = SetWindowLong(hButton, GWL_WNDPROC, (LONG)ButtonProc); 
                return 0;
            }
    
    		case WM_DESTROY :
    		{
                SetWindowLong(hButton, GWL_WNDPROC, PrevWndProc);
    			PostQuitMessage (0) ;
    			return 0;
    		}
    	}
    	return DefWindowProc (hwnd, message, wParam, lParam) ;
    }
    
    LRESULT CALLBACK ButtonProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch (msg)
        {
            case WM_COMMAND:
            {
                if (HIWORD(wParam) == BN_CLICKED)
                {
                    MessageBox(0, "Test", "Clicked", MB_OK);
                }
            }
            break;
        }
    
        return CallWindowProc((WNDPROC)PrevWndProc, hWnd, msg, wParam, lParam);
    }
    

    Danke.



  • Du könntest mal schauen, ob SetWindowLong überhaupt erfolgreich ist.



  • luxx schrieb:

    Die ButtonProc wird nicht aufgerufen.

    Bist du dir da wirklich sicher? Oder wird nur keine MessageBox ausgegeben?



  • Ok, ihr habt recht 🙂
    Die ButtonProc wird aufgerufen, aber es kommt nie ein WM_COMMAND.

    Wenn ich die Abfrage in der WndProc mache, dann erscheint die MessageBox.



  • BN_CLICKED bekommst du als Benachrichtigung an das Parent, also nicht in der ButtonProc selbst. Dort musst du wohl direkt die Nachrichten wie WM_LBUTTONDOWN & Co. abfangen...


Anmelden zum Antworten