WM_DESTROY没有在包装的WndProc中调用

时间:2017-12-29 22:49:56

标签: c++ winapi window wrapper wndproc

我采用了你在那里找到的典型解决方案,以便使用WNDPROC作为对象方法,但看起来WM_DESTROY消息不会发送到对象窗口自己的{{1关闭窗口后程序不会退出。

我的窗口类看起来像这样(删除了不相关的代码):

WNDPROC

现在是一个包含静态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;
}

和实施

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

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

也未捕获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); } 消息。我真的不明白为什么不传递这些消息

1 个答案:

答案 0 :(得分:3)

您要将lpParam的{​​{1}}参数设置为CreateWindowEx(),因此nullptr中的myWindow始终为nullptr,因此{{1}永远不会被调用。您需要传递MyApp::WndProc()而不是MyWindow::WndProc()

在调用this / nullptr之前,您还没有进行任何错误检查以确保RegisterClassExW()CreateWindowEx()成功。

另外,请考虑使用SetWindowSubclass()代替ShowWindow()。请参阅MSDN上的Subclassing Controls和关于Safer Subclassing的Raymond Chen博客文章。