我查看了许多关于该主题的教程和帖子,他们都说我在this函数中传递了类实例指针(CreateWindowEx()),然后在发送WM_NCCREATE消息时将其存储在窗口过程函数中。我猜这是因为WM_NCCREATE应该是自创建窗口以来发送到窗口过程的第一条消息。

一些问题/说明:

  • 通过调试,我知道WM_GETMINMAXINFO实际上是WM_NCCREATE之前(至少在我的机器上)之前发送的第一条消息。这是否意味着我应该听此消息而不是WM_NCCREATE
  • 根据this的热门文章,每个人在收到SetWindowLongPtr()消息后都调用WM_NCCREATE的原因是


  • 我试图做到这一点(即在SetWindowLongPtr()之后调用CreateWindowEx())。事实证明还不错。该应用程序运行正常。以下是我的代码,请告诉我这种方法是否有问题。
    void GLWin32::CreateWindow(...)
    {
        ...
    
        _hwnd = CreateWindowEx(NULL, _wndclassex.lpszClassName, title.c_str(), WS_OVERLAPPEDWINDOW, x, y, width, height, NULL, NULL, _hinstance, NULL);
        SetWindowLongPtr(_hwnd, GWL_USERDATA, reinterpret_cast<LONG_PTR>(this));
    
        ...
    }
    
    //static window procedure for all instances of this class
    LRESULT CALLBACK GLWin32::_msgRouter(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
    {
        LONG l = GetWindowLongPtr(hwnd, GWLP_USERDATA);
        GLWin32* thisPtr = reinterpret_cast<GLWin32*>(l);
    
        if (thisPtr)
            return thisPtr->_winProc(msg, wparam, lparam);
        else
            return DefWindowProc(hwnd, msg, wparam, lparam);
    }
    
    LRESULT GLWin32::_winProc(UINT msg, WPARAM wparam, LPARAM lparam)
    {
        switch (msg)
        {
        case WM_CLOSE:
        {
            PostQuitMessage(0);
            return 0;
        }
        }
    
        return DefWindowProc(_hwnd, msg, wparam, lparam);
    }
    

    为什么不使用我的方法代替popular approach

    最佳答案

    这种方法的问题在于,如果您想在处理任何窗口创建消息(包括在创建过程中发送的“普通”消息)时使用实例,则将无法访问该实例。

    假设您要在处理WM_CREATE(典型情况)时创建一个按钮,并且要将按钮文本设置为某个实例成员值。您想要类似的东西:

    LRESULT GLWin32::_winProc(UINT msg, WPARAM wparam, LPARAM lparam)
    {
        switch (msg)
        {
        case WM_CREATE:
        {
            CreateWindow("BUTTON", this->buttonText, WS_VISIBLE | WS_CHILD,
              10, 10, 50, 30, this->hwnd, NULL, this->hInstance, NULL);
            return 0;
        }
        }
    
        return DefWindowProc(_hwnd, msg, wparam, lparam);
    }
    

    问题是,当处理WM_CREATE时(在CreateWindowEx返回之前),尚未调用SetWindowLongPtr且缺少实例指针,因此根本没有调用_winProc

    09-20 00:58