2017-12-29 32 views
0

Ich habe die typische Lösung angenommen Sie es, um herauszufinden, die WNDPROC als Objektmethode zu verwenden, aber es sieht aus wie die WM_DESTROY Nachricht nicht an die eigene WNDPROC der gesendet wird, Objektfenster und das Programm erledigt nicht nach dem Schließen des Fensters beenden.WM_DESTROY nicht nach innen eingewickelt WndProc genannt

Mein Fenster Klasse sieht wie folgt aus (irrelevant Code entfernt):

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; 
} 

Und nun eine Klasse, die die statische WNDPROC hält, die bei der Erstellung zugeordnet

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

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

und Umsetzung

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); 
} 

Die Nachricht WM_CLOSE wird ebenfalls nicht abgefangen. Ich verstehe wirklich nicht, warum diese Nachrichten nicht auf

geben werden
+1

Die Logik der ersten if-Anweisung in MyApp :: WndProc ist der falsche Weg. –

+0

Sorry und danke. Jedenfalls war das nicht der Grund. Das Problem besteht weiterhin – bMain

+0

sind diese Fensterdialogbox? * nach dem Schließen des Fensters * - kann das Fenster einfach verdeckt, aber nicht zerstört werden? – RbMm

Antwort

3

Sie setzen die lpParam Parameter von CreateWindowEx()-nullptr, so myWindow ist immer nullptr in MyApp::WndProc(), so MyWindow::WndProc() nie aufgerufen. Sie müssen this statt nullptr übergeben.

Sie führen auch keine Fehlerprüfung durch, um sicherzustellen, dass RegisterClassExW() und CreateWindowEx() erfolgreich sind, bevor Sie ShowWindow()/UpdateWindow() aufrufen.

Verwenden Sie auch SetWindowSubclass() anstelle von (Get|Set)WindowLongPtr(GWLP_USERDATA). Siehe Subclassing Controls auf MSDN und Raymond Chens Blogartikel unter Safer Subclassing.

+0

Danke. Ich dachte 'SetWindowSubclass()' war nur für untergeordnete Fenster/Steuerelemente, nicht für Hauptfenster. Ich werde das ändern – bMain