Window 句柄没有正确保存
Window handle doesn't save correctly
我真的不知道如何在 C++ 中使用 HWND。
我想按下一个按钮,它应该启动一个代码为 运行 的线程。
但我从未在其他回调中收到按钮单击命令。
所以我做了一些调试,似乎 _wndInstance->GetWndHWND() returns 无效。方法 returns 存储它的私有字段。
如果您查看案例 WM_CREATE,添加的 window 内容将不会显示为 _wndInstance->GetWndHWND()。但如果我只是使用参数中的 hwnd,它确实有效。但是,如果我的第一个 test-check 验证它们是相同的,那怎么可能呢??
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (_wndInstance->GetWndHWND() == hwnd)
cout << "same" << endl; // Code is getting here!
switch (msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CREATE:
{
_wndInstance->CreateWndContent(_wndInstance->GetWndHWND()); // not working, but hwnd is!
}
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
编辑:
_wndInstance是我写的一个mainwindowclass的实例。
主窗口的一部分 header:
private:
HWND _wndHwnd;
public:
HWND GetWndHWND();
主窗口 cpp:
HWND MainWindow::GetWndHWND()
{
return _wndHwnd;
}
_wndHwnd 在创建 window:
的私有方法中设置
_wndHwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"\"Xbox controller on WINDOWS\" Manager",
WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX, // no maximize box
CW_USEDEFAULT, CW_USEDEFAULT, 450, 370,
NULL, NULL, hinstance, NULL);
if (_wndHwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return;
}
ShowWindow(_wndHwnd, nCmdShow);
UpdateWindow(_wndHwnd);
WM_CREATE
在 CreateWindowEx()
returns 之前发送,因此在您的分配发生之前。您将需要重组代码,以便 HWND
仅在分配给 _wndHwnd
.
后使用
如果您不需要在 WM_CREATE
和消息循环开始之间执行任何操作,您可以删除 WM_CREATE
处理程序。这取决于您的代码将来如何工作。
但更安全的方法是在您的 WM_CREATE
处理程序(甚至 WM_NCCREATE
)中分配 _wndHwnd
,因为您可以将其作为 hwnd
参数使用您的 window 过程,它将处理在 window 创建和变量赋值之间发送的其他消息。您甚至可以将 _wndInstance
作为最后一个参数传递给 CreateWindowEx()
并从 WM_CREATE
访问它;有关详细信息,请参阅 this。
我真的不知道如何在 C++ 中使用 HWND。 我想按下一个按钮,它应该启动一个代码为 运行 的线程。 但我从未在其他回调中收到按钮单击命令。 所以我做了一些调试,似乎 _wndInstance->GetWndHWND() returns 无效。方法 returns 存储它的私有字段。
如果您查看案例 WM_CREATE,添加的 window 内容将不会显示为 _wndInstance->GetWndHWND()。但如果我只是使用参数中的 hwnd,它确实有效。但是,如果我的第一个 test-check 验证它们是相同的,那怎么可能呢??
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (_wndInstance->GetWndHWND() == hwnd)
cout << "same" << endl; // Code is getting here!
switch (msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CREATE:
{
_wndInstance->CreateWndContent(_wndInstance->GetWndHWND()); // not working, but hwnd is!
}
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
编辑:
_wndInstance是我写的一个mainwindowclass的实例。 主窗口的一部分 header:
private:
HWND _wndHwnd;
public:
HWND GetWndHWND();
主窗口 cpp:
HWND MainWindow::GetWndHWND()
{
return _wndHwnd;
}
_wndHwnd 在创建 window:
的私有方法中设置_wndHwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"\"Xbox controller on WINDOWS\" Manager",
WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX, // no maximize box
CW_USEDEFAULT, CW_USEDEFAULT, 450, 370,
NULL, NULL, hinstance, NULL);
if (_wndHwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return;
}
ShowWindow(_wndHwnd, nCmdShow);
UpdateWindow(_wndHwnd);
WM_CREATE
在 CreateWindowEx()
returns 之前发送,因此在您的分配发生之前。您将需要重组代码,以便 HWND
仅在分配给 _wndHwnd
.
如果您不需要在 WM_CREATE
和消息循环开始之间执行任何操作,您可以删除 WM_CREATE
处理程序。这取决于您的代码将来如何工作。
但更安全的方法是在您的 WM_CREATE
处理程序(甚至 WM_NCCREATE
)中分配 _wndHwnd
,因为您可以将其作为 hwnd
参数使用您的 window 过程,它将处理在 window 创建和变量赋值之间发送的其他消息。您甚至可以将 _wndInstance
作为最后一个参数传递给 CreateWindowEx()
并从 WM_CREATE
访问它;有关详细信息,请参阅 this。