2014-02-08 5 views
-2

현재 Win32와 C++를 배우며 첫 번째 응용 프로그램을 마쳤습니다. 이제 코드를 기능적 스타일에서 OOP로 변환하려고합니다.부모 클래스가있는 파생 클래스의 함수에 대한 포인터

#include <Windows.h> 

class BaseWindow { 
    public: 
    BaseWindow(); 
    virtual LRESULT CALLBACK WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) abstract; 
    bool Register(); 
}; 

BaseWindow::BaseWindow() {} 

bool BaseWindow::Register() { 
    WNDCLASSEXW wnd = {0}; 
    wnd.lpfnWndProc = &BaseWindow::WndProc; // Error | How to point to the derived class's WndProc 
    // Some other properties 
    return RegisterClassExW(&wnd) != NULL; 
} 



class MainWindow : BaseWindow { 
    using BaseWindow::Register; 

    public: 
    MainWindow(); 
    bool Register(); 
    LRESULT CALLBACK WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 
}; 

MainWindow::MainWindow() : BaseWindow() {} 

LRESULT CALLBACK MainWindow::WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { 
    // Handling messages 
} 

어떻게 결합 할 수있는 파생 클래스의 WndProc 부모 클래스의 wnd.lpfnWndProcBaseWindow::Register에에 : 여기 단축 내 코드의 버전은 무엇입니까?

+3

질문이 있습니까? 그리고 등록 된'WndProc'은'static'이거나 클래스에 독립적 인 외부 함수가 될 필요가 있습니다. 간단한 멤버 함수를 등록 된 wndproc 콜백으로 사용할 수 없습니다. – WhozCraig

+0

고맙습니다. 나는 그것을 몰랐다. 'lpfnWndProc'을 클래스의 멤버에 바인드 할 방법이없는가요? – Cubinator73

+0

있지만, 그것은 반드시 (적어도 초보자가 아닌) 사소한 것은 아닙니다. 그것을하는 한 가지 방법은 [여기에서 볼 수 있습니다] (http://stackoverflow.com/questions/17382174/why-cant-i-bind-to-winproc/17634960#17634960). 일반적으로 Windows API의 CreateWindow 생성 매개 변수의 일부로 객체 포인터를 제공 한 다음 나중에 메시지를 전달할 때 사용할 수 있도록 해당 포인터를 윈도우 인스턴스의 윈도우 외 바이트 내에 저장합니다. 해당 링크를 읽으십시오. 그것의 (imho) 이상, 그러나 그것은 편도입니다. – WhozCraig

답변

1

비 정적 클래스 메서드를 윈도우 프로 시저 콜백으로 사용할 수 없습니다. 매개 변수 목록은 숨겨진 포인터로 인해 호환되지 않습니다. 당신이 대신해야 할 것은 :

  1. BaseWindow에서 RegisterClassEx()에 등록 된 실제 메시지 콜백과 같은 정적 메소드를 정의하고 메시지를 처리하기위한 별도의 가상 메서드를 정의합니다. BaseWindow 가상 메서드 호출 DefWindowProc() 호출 구현 및 가상 메서드를 재정의하는 자식 처리되지 않은 메시지에 대한 기본 메서드를 호출해야합니다.

  2. lpCreateParamCreateWindow/Ex() 인 개체의 this 포인터를 전달하십시오. WM_NCCREATE 메시지 핸들러에서

  3. 메시지에서 lpCreateParam 값을 검색하고 하나 SetWindowLongPtr(GWL_USERDATA) 또는 SetProp()는 다음 BaseWindow* 포인터에 값을 입력 캐스트 및 가상 메소드를 호출하는 데 사용할 사용하여 HWND에 할당합니다.

  4. 후속 메시지의 경우 GetWindowLongPtr(GWL_USERDATA) 또는 GetProp()을 사용하여 HWND에서 BaseWindow* 포인터를 검색하고이를 사용하여 가상 메서드를 호출합니다.