windows - 将Win32封装在一个类中——在CreateWindow中传递类指针

标签 windows winapi

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

几个问题/注意事项:

  1. 通过调试,我了解到实际上 WM_GETMINMAXINFO 是第一条发送的消息, WM_NCCREATE 之前(至少在我的机器上是这样).这是否意味着我应该监听此消息而不是 WM_NCCREATE

  2. 根据 this热门文章,大家之所以在收到消息WM_NCCREATE后调用SetWindowLongPtr()是因为

    If the value does not exist by the time WM_NCCREATE is called then, by some mysterious Windows behavior that I still don't understand, the value never gets inserted.

我试图做到这一点(即,在 CreateWindowEx() 之后调用 SetWindowLongPtr())。事实证明很好。应用程序运行正常。下面是我的代码,请告诉我这种方法是否有问题。

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 根本没有被调用。

关于windows - 将Win32封装在一个类中——在CreateWindow中传递类指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34500027/

相关文章:

.net - 使用 WiX 安装程序复制 Visual Studio COM 注册

windows - Windows中的中断处理

java - 采用另一个进程的子窗口

reactjs - 是否有可能使React-Electron Standalone应用程序始终保持领先地位?

c++ - Windows 上的写时复制文件映射

c++ - 将 GetLastError() 转换为带有错误字符串的异常

c - Windows 编程时关于类型的最佳实践?

c++ - Win32 客户端大小和不正确的大小

c++ - 获取音量帮助

c++ - 在库中拆分实用程序功能以最大化可重用性的最佳方法是什么?