我试图捕获用于窗口游戏的鼠标以处理鼠标输入,并且每次尝试时,它都会返回nullptr。我在窗口上看到的是一个等待的光标(蓝色圆圈)。
这是Win32窗口包装程序的代码:
XWindow::XWindow(WCHAR* title, int width, int height)
{
memcpy(m_szTitle, title, sizeof(title));
m_width = width;
m_height = height;
}
ATOM XWindow::MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance,
MAKEINTRESOURCE(IDI_WIN32PROJECT1));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = nullptr;
wcex.lpszClassName = m_szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance,
MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
BOOL XWindow::InitInstance(HINSTANCE hInstance, int nCmdShow)
{
m_hInst = hInstance;
m_hWnd = CreateWindowW(m_szWindowClass, m_szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, m_width, m_height, nullptr, nullptr, hInstance, nullptr);
if (!m_hWnd)
return FALSE;
ShowWindow(m_hWnd, nCmdShow);
UpdateWindow(m_hWnd);
return TRUE;
}
LRESULT CALLBACK XWindow::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
switch (wmId)
{
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
这是WinMain函数:
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE
hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
XIllumin* pMainGameWindow = new XIllumin(L"X3DEngine", 800, 600);
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
if (LoadStringW(hInstance, IDS_APP_TITLE, pMainGameWindow-
>GetWindowTitle(), MAX_LOADSTRING) == 0)
return FALSE;
if (LoadStringW(hInstance, IDC_WIN32PROJECT1, pMainGameWindow-
>GetWindowClass(), MAX_LOADSTRING) == 0)
return FALSE;
pMainGameWindow->MyRegisterClass(hInstance);
if (!pMainGameWindow->InitInstance(hInstance, nCmdShow))
return FALSE;
if (SetCapture(pMainGameWindow->GetWindowHandle()) == nullptr)
// return FALSE;
if (!pMainGameWindow->ParseInitFile("Config/GameInit.txt"))
{
pMainGameWindow->FAIL_MSG_BOX(L"Error loading init file.");
return FALSE;
}
pMainGameWindow->InitGameObjects(" ");
HACCEL hAccelTable = LoadAccelerators(hInstance,
MAKEINTRESOURCE(IDC_WIN32PROJECT1));
MSG msg;
while (1)
{
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
pMainGameWindow->CleanUp();
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (!pMainGameWindow->GameMain(" "))
break;
}
return (int)msg.wParam;
}
我不确定到底是什么问题。我认为这可能是CreateWindowW()的窗口创建参数,但实际上并不知道该使用哪个。
编辑:当我将鼠标光标悬停在游戏窗口上时,输入应该由游戏窗口处理,但是一旦窗口弹出并且光标位于它上面,我就会看到等待的光标。不确定在此之上还有什么要说的。
最佳答案
请注意,SetCapture
将句柄返回到先前捕获鼠标的窗口。因此,当以前没有其他窗口捕获鼠标时,SetCapture
可以返回NULL
。 “等待”光标与它无关。
请注意,通过注释// return FALSE;
可以将if
范围更改为以下内容,可能会跳过配置加载:
if (SetCapture(pMainGameWindow->GetWindowHandle()) == nullptr)
{
// return FALSE;
if (!pMainGameWindow->ParseInitFile("Config/GameInit.txt"))
{
pMainGameWindow->FAIL_MSG_BOX(L"Error loading init file.");
return FALSE;
}
}
这是一个很好的例子,说明为什么不应省略
{}
。您应该在调用
SetCapture
之前泵送消息,以便窗口将被初始化并正确地进入前台:// at InitInstance
UpdateWindow(m_hWnd);
MSG msg;
while(PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}