2010-05-17 5 views
2

나는 사용자 지정 컨트롤 클래스를 만드는거야 내가 그것을 완벽하게 제어를 원하기 때문에, 나는 클래스를 등록하고 클래스의맞춤 컨트롤에 클래스 콜백을 사용 하시겠습니까?

LRESULT CALLBACK OGLTOOLBAR :: ToolProc (HWND, UINT, WPARAM, LPARAM)를 사용할

하지만 나를 보내지 않습니다.

내가하고 있어요 :

HWND OGLTOOLBAR::create(HWND parent,HINSTANCE hInst, int *toolWidthPtr) 
{ 
    if (toolhWnd != NULL) 
    { 
     return toolhWnd; 
    } 
    toolWidth = toolWidthPtr; 

    ZeroMemory(&rwc,sizeof(rwc)); 
    rwc.lpszClassName = TEXT("OGLTool"); 
    rwc.hbrBackground = GetSysColorBrush(COLOR_BTNSHADOW); 
    rwc.lpfnWndProc = (WNDPROC)ToolProc; 
    rwc.hCursor  = LoadCursor(0, IDC_ARROW); 

    RegisterClass(&rwc); 
    toolhWnd = CreateWindowEx(NULL, rwc.lpszClassName,NULL, 
     WS_CHILD | WS_VISIBLE, 
     0, 0, *toolWidth, 900, parent, 0, NULL, 0); 


    return toolhWnd; 

} 

이 일을 올바른 방법은 무엇입니까?

감사

컴파일러는 말합니다 : 오류 1 오류 C2440 : '형식 캐스트': 'WNDPROC'

답변

2

ToolProc이 정적 멤버가 아닌 경우 ToolProc을 정적이 아닌 함수로 만들려고한다고 가정 할 때 멤버 함수 포인터를 콜백으로 전달할 수 없습니다. 정적 멤버 함수를 만들고 사용할 수 있습니다. GetWindowLong/SetWindowLong 및 GWL_USERDATA 영역에서 현재 개체 (this)에 대한 포인터를 저장하고 개별 개체 데이터 멤버를 활용할 수있는 정적 개체 콜백 함수를 호출합니다. 당신이 다음

void OGLTOOLBAR::SetObjectToHWnd(HWND hWnd, LPARAM lParam) 
{ 
    LPCREATESTRUCT cs = reinterpret_cast<LPCREATESTRUCT>(lParam); 
    OGLTOOLBAR *pWnd = reinterpret_cast<OGLTOOLBAR*>(cs->lpCreateParams); 

    SetLastError(0); 

    if(!SetWindowLong(hWnd, GWL_USERDATA, reinterpret_cast<long>(pWnd)) 
     && GetLastError()) 
     //Do something about the error 
} 

OGLTOOLBAR *OGLTOOLBAR::GetObjectFromHWnd(HWND hWnd) 
{ 
    return reinterpret_cast<OGLTOOLBAR*>(GetWindowLong(hWnd,GWL_USERDATA)); 
} 

을 그리고 : ToolProc이 OGLTOOLBAR 클래스의 정적 멤버가 아닌 것을 가정

, 당신은 창 핸들에 개체의이 포인터를 묶어해야합니다, 당신은과 같이이 작업을 수행 할 수 있습니다 이 같은 정적의 WndProc (또는 ToolProc) 멤버 함수 :

LRESULT OGLTOOLBAR::StaticToolProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    if(uMsg == WM_NCCREATE) 
     SetObjectToHwnd(hWnd, lParam); 

    Window *pWnd = GetObjectFromWnd(hWnd); 

    if(pWnd) 
     return pWnd->ToolProc(hWnd, uMsg, wParam, lParam); 
    else 
     return DefWindowProc(hWnd, uMsg, wParam, lParam); 
} 

그리고 당신은 OGLTOOLBAR::createCreateWindow 함수를 호출 할 때 다음의 lpParam 인수로 reinterpret_cast<void*>(this) (마지막)를 전달합니다.

그리고 각 OGLTOOLBAR 개체에는 StaticToolProc 함수를 통해 각 인스턴스에 대해 호출 된 자체 ToolProc가 있습니다. 적어도이게 효과가 있다고 생각합니다.

+0

이 게시물이 나에게 얼마나 유용했는지 모르실 것입니다. –

0

정적 멤버가 ToolProc되는 '오버로드 된 함수'에서 변환 할 수 없습니다? 멤버 함수 포인터 또는 펑터를 함수 포인터로 전달할 수 없습니다. C API는 함수 포인터에서만 작동합니다.

일반적으로 "클라이언트 데이터"를 개체에 연결하여 트리거 될 때 콜백으로 전달되도록하는 방법이 있습니다. 이 정보를 사용하여 인스턴스 특정 데이터를 전달함으로써 정적 또는 전역 함수가 올바른 클래스의 멤버 변수를 호출 할 수 있습니다.

+0

실제로 GetWindowLongPtr/SetWindowLongPtr을 사용하여 인스턴스 개체에 대한 포인터를 보유합니다. 어떤 종류의 외부지도에 저장할 필요가 없습니다. 인덱스가 DWLP_USER로 설정됩니다. – jmucchiello

관련 문제