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,59 +533,26 @@ 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()) const CREATESTRUCTW* cs = (const CREATESTRUCTW*) lParam;
{ const _GLFWwndconfig* wndconfig = cs->lpCreateParams;
const CREATESTRUCTW* cs = (const CREATESTRUCTW*) lParam;
const _GLFWwndconfig* wndconfig = cs->lpCreateParams;
// On per-monitor DPI aware V1 systems, only enable // On per-monitor DPI aware V1 systems, only enable
// non-client scaling for windows that scale the client area // non-client scaling for windows that scale the client area
// We need WM_GETDPISCALEDSIZE from V2 to keep the client // We need WM_GETDPISCALEDSIZE from V2 to keep the client
// area static when the non-client area is scaled // area static when the non-client area is scaled
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;
} }
} }