2017-12-29 50 views
0

WNDPROC을 오브젝트 메소드로 사용하기 위해 알아 낸 일반적인 솔루션을 채택했지만 WM_DESTROY 메시지가 오브젝트 창 자신의 WNDPROC으로 전송되지 않고 프로그램이 수행하는 것처럼 보입니다 창을 닫은 후에 종료하지 마십시오. 창조WM_DESTROY가 랩핑 된 WndProc 내부에서 호출되지 않았습니다

class MyApp 
{ 
public: 
    static HINSTANCE Instance; 
    static int WindowsCount; 

    MyApp(); 
    static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 
}; 

및 구현

에 할당 된 정적 WNDPROC를 보유하고

class MyWindow : MyApp 
{ 
public: 
    MyWindow(); 
    void Create(void); 
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 
private: 
    HWND _hWnd; 
}; 

void MyWindow::Create() 
{ 
    // Here I register my class and call CreateWindowEx 
    // Everything works fine so far 

    // Part of the code where I assign the static WNDPROC 
    WNDCLASSEXW wcex; 

    wcex.cbSize = sizeof(WNDCLASSEX); 
    wcex.style = CS_HREDRAW | CS_VREDRAW; 
    wcex.lpfnWndProc = MyApp::WndProc; 
    wcex.cbClsExtra = 0; 
    wcex.cbWndExtra = 0; 
    wcex.hInstance = this->Instance; 
    wcex.hIcon = LoadIcon(this->Instance, MAKEINTRESOURCE(32512)); 
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); 
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 
    wcex.lpszMenuName = NULL; 
    wcex.lpszClassName = "MyWindowClass"; 
    wcex.hIconSm = LoadIcon(this->Instance, MAKEINTRESOURCE(32512)); 

    RegisterClassExW(&wcex); 

    this->_hWnd = CreateWindowExW(
     WS_EX_TOOLWINDOW | WS_EX_TOOLWINDOW, 
     wcex.lpszClassName, 
     "Window Title", 
     WS_POPUP, 
     10, 10, 
     600, 400, 
     nullptr, 
     nullptr, 
     this->Instance, 
     nullptr 
    ); 

    ShowWindow(this->_hWnd, SW_SHOW); 
    UpdateWindow(this->_hWnd); 
} 

LRESULT CALLBACK MyWindow::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
    switch (msg) 
    { 
    case WM_CREATE: 
    { 
     // If I place a MessageBox here, it shows up 
    } 
    break; 
    case WM_DESTROY: 
     // It never gets to this point 

     // Decrease windows count 
     this->WindowsCount--; 

     PostQuitMessage(0); 
     break; 
    break; 
    default: 
     return DefWindowProc(hWnd, msg, wParam, lParam); 
    } 
    return 0; 
} 

그리고 지금 클래스 :

내 창 클래스는이 (제거 관련이없는 코드)처럼 보인다

LRESULT CALLBACK MyApp::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
    // Window object 
    MyWindow* myWindow = NULL; 

    if (msg == WM_CREATE) { 
     myWindow = reinterpret_cast<MyWindow *>(((LPCREATESTRUCT)lParam)->lpCreateParams); 
     SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)myWindow); 
    } 
    else { 
     myWindow = reinterpret_cast<MyWindow *>(GetWindowLongPtr(hWnd, GWLP_USERDATA)); 
    } 

    // If window not identified, identify now 
    if (myWindow) { 
     return myWindow->WndProc(hWnd, msg, wParam, lParam); 
    } 

    // Call window object's processor 
    return DefWindowProc(hWnd, msg, wParam, lParam); 
} 

WM_CLOSE 메시지도 감지되지 않습니다. 이러한 메시지는

+1

MyApp :: WndProc의 첫 번째 if 문의 논리가 잘못된 방향입니다. –

+0

죄송합니다. 감사합니다. 어쨌든, 그 이유가 아니 었습니다. 이 문제는 계속 발생합니다 – bMain

+0

이 대화 상자입니까? * 창을 닫은 후에 * - 단순히 숨겨 지지만 파괴되지 않은 창일 수 있습니까? – RbMm

답변

3

당신은 nullptrCreateWindowEx()lpParam 매개 변수를 설정하는 전달되지 않는 이유를 정말 그렇게 myWindowMyApp::WndProc() 항상 nullptr 따라서 MyWindow::WndProc()가 호출되지 않습니다이다, 이해가 안 돼요. nullptr 대신 this을 전달해야합니다.

CreateWindowEx()을 확인하기 위해 오류가 발생하지 않았으므로 ShowWindow()/UpdateWindow()을 호출하십시오.

또한 (Get|Set)WindowLongPtr(GWLP_USERDATA) 대신 SetWindowSubclass()을 사용하는 것이 좋습니다. MSDN의 Subclassing ControlsSafer Subclassing의 Raymond Chen 블로그 기사를 참조하십시오.

+0

감사합니다. 나는'SetWindowSubclass()'가 자식 윈도우/컨트롤에만, 메인 윈도우에는 없다고 생각했다. 나는 그것을 그것으로 바꿀 것이다. – bMain