Win32: Add separate window class for helper window

The current window procedure needs to deal with messages both for user
created windows and the hidden helper window.

This commit separates out the device message handling of the helper
window, allowing both window procedures to be less complicated.
This commit is contained in:
Camilla Löwy 2022-03-27 19:40:35 +02:00
parent ad3dbeb65f
commit 2ae3e0c8d7
3 changed files with 64 additions and 45 deletions

View File

@ -179,6 +179,7 @@ information on what to include when reporting a bug.
- [Win32] Added the `GLFW_WIN32_KEYBOARD_MENU` window hint for enabling access - [Win32] Added the `GLFW_WIN32_KEYBOARD_MENU` window hint for enabling access
to the window menu to the window menu
- [Win32] Added a version info resource to the GLFW DLL - [Win32] Added a version info resource to the GLFW DLL
- [Win32] Made hidden helper window use its own window class
- [Win32] Disabled framebuffer transparency on Windows 7 when DWM windows are - [Win32] Disabled framebuffer transparency on Windows 7 when DWM windows are
opaque (#1512) opaque (#1512)
- [Win32] Bugfix: `GLFW_INCLUDE_VULKAN` plus `VK_USE_PLATFORM_WIN32_KHR` caused - [Win32] Bugfix: `GLFW_INCLUDE_VULKAN` plus `VK_USE_PLATFORM_WIN32_KHR` caused

View File

@ -331,15 +331,63 @@ static void createKeyTables(void)
} }
} }
// Window procedure for the hidden helper window
//
static LRESULT CALLBACK helperWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DISPLAYCHANGE:
_glfwPollMonitorsWin32();
break;
case WM_DEVICECHANGE:
{
if (!_glfw.joysticksInitialized)
break;
if (wParam == DBT_DEVICEARRIVAL)
{
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
_glfwDetectJoystickConnectionWin32();
}
else if (wParam == DBT_DEVICEREMOVECOMPLETE)
{
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
_glfwDetectJoystickDisconnectionWin32();
}
break;
}
}
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
// Creates a dummy window for behind-the-scenes work // Creates a dummy window for behind-the-scenes work
// //
static GLFWbool createHelperWindow(void) static GLFWbool createHelperWindow(void)
{ {
MSG msg; MSG msg;
WNDCLASSEXW wc = { sizeof(wc) };
wc.style = CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) helperWindowProc;
wc.hInstance = _glfw.win32.instance;
wc.lpszClassName = L"GLFW3 Helper";
if (!RegisterClassExW(&wc))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WIn32: Failed to register helper window class");
return GLFW_FALSE;
}
_glfw.win32.helperWindowHandle = _glfw.win32.helperWindowHandle =
CreateWindowExW(WS_EX_OVERLAPPEDWINDOW, CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,
_GLFW_WNDCLASSNAME, L"GLFW3 Helper",
L"GLFW message window", L"GLFW message window",
WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0, 0, 1, 1, 0, 0, 1, 1,
@ -663,7 +711,10 @@ void _glfwTerminateWin32(void)
UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle); UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle);
if (_glfw.win32.helperWindowHandle) if (_glfw.win32.helperWindowHandle)
{
DestroyWindow(_glfw.win32.helperWindowHandle); DestroyWindow(_glfw.win32.helperWindowHandle);
UnregisterClassW(L"GLFW3 Helper", _glfw.win32.instance);
}
_glfwUnregisterWindowClassWin32(); _glfwUnregisterWindowClassWin32();

View File

@ -533,19 +533,14 @@ static void maximizeWindowManually(_GLFWwindow* window)
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED); SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
} }
// Window callback function (handles window messages) // Window procedure for user-created windows
// //
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
_GLFWwindow* window = GetPropW(hWnd, L"GLFW"); _GLFWwindow* window = GetPropW(hWnd, L"GLFW");
if (!window) if (!window)
{ {
// This is the message handling for the hidden helper window if (uMsg == WM_NCCREATE)
// and for a regular window during its initial creation
switch (uMsg)
{
case WM_NCCREATE:
{ {
if (_glfwIsWindows10Version1607OrGreaterWin32()) if (_glfwIsWindows10Version1607OrGreaterWin32())
{ {
@ -559,34 +554,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
if (wndconfig && wndconfig->scaleToMonitor) if (wndconfig && wndconfig->scaleToMonitor)
EnableNonClientDpiScaling(hWnd); EnableNonClientDpiScaling(hWnd);
} }
break;
}
case WM_DISPLAYCHANGE:
_glfwPollMonitorsWin32();
break;
case WM_DEVICECHANGE:
{
if (!_glfw.joysticksInitialized)
break;
if (wParam == DBT_DEVICEARRIVAL)
{
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
_glfwDetectJoystickConnectionWin32();
}
else if (wParam == DBT_DEVICEREMOVECOMPLETE)
{
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
_glfwDetectJoystickDisconnectionWin32();
}
break;
}
} }
return DefWindowProcW(hWnd, uMsg, wParam, lParam); return DefWindowProcW(hWnd, uMsg, wParam, lParam);