我试图抓住鼠标进行窗口游戏来处理鼠标输入,每次尝试时都会返回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()的窗口创建参数,但并不是真的知道要使用哪个。
编辑:当我将鼠标光标悬停在游戏窗口上时,输入应该由游戏窗口处理,但是当窗口弹出并且光标在其上时我看到等待光标。不确定还有什么可以说的。
答案 0 :(得分:2)
请注意,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);
}