From a96664674f6174773ef4a30eb1c53afcdddcaae1 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 9 Nov 2025 07:42:50 -0800 Subject: [PATCH] Fixed windows events on 32-bit Windows When running on 32-bit Windows, DefWindowProc resolves to a function in ntdll.dll, but after the window is created the actual window proc is a function in user32.dll. We solve this by using our own custom default window proc and looking for that instead. Fixes https://github.com/libsdl-org/SDL/issues/1442 --- src/video/windows/SDL_windowsevents.c | 7 ++++++- src/video/windows/SDL_windowsevents.h | 4 ++-- src/video/windows/SDL_windowswindow.c | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index bde2a53bde..b9f6e9dba0 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -2471,6 +2471,11 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara } } +LRESULT CALLBACK WIN_DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam); +} + int WIN_WaitEventTimeout(SDL_VideoDevice *_this, Sint64 timeoutNS) { if (g_WindowsEnableMessageLoop) { @@ -2754,7 +2759,7 @@ bool SDL_RegisterApp(const char *name, Uint32 style, void *hInst) wcex.cbSize = sizeof(WNDCLASSEX); wcex.lpszClassName = SDL_Appname; wcex.style = SDL_Appstyle; - wcex.lpfnWndProc = DefWindowProc; + wcex.lpfnWndProc = WIN_DefWindowProc; wcex.hInstance = SDL_Instance; #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) diff --git a/src/video/windows/SDL_windowsevents.h b/src/video/windows/SDL_windowsevents.h index 5336013b65..78a9220831 100644 --- a/src/video/windows/SDL_windowsevents.h +++ b/src/video/windows/SDL_windowsevents.h @@ -28,8 +28,8 @@ extern Uint32 SDL_Appstyle; extern HINSTANCE SDL_Instance; extern LRESULT CALLBACK WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam); -extern LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, - LPARAM lParam); +extern LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT CALLBACK WIN_DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); extern void WIN_PollRawInput(SDL_VideoDevice *_this, Uint64 poll_start); extern void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, bool initial_check); extern void WIN_PumpEvents(SDL_VideoDevice *_this); diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index 223020d2c6..542c29f510 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -427,13 +427,13 @@ static bool SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, HWND hwn // Set up the window proc function #ifdef GWLP_WNDPROC data->wndproc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC); - if (data->wndproc == DefWindowProc) { + if (data->wndproc == WIN_DefWindowProc) { data->wndproc = NULL; SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)WIN_WindowProc); } #else data->wndproc = (WNDPROC)GetWindowLong(hwnd, GWL_WNDPROC); - if (data->wndproc == DefWindowProc) { + if (data->wndproc == WIN_DefWindowProc) { data->wndproc = NULL; SetWindowLong(hwnd, GWL_WNDPROC, (LONG_PTR)WIN_WindowProc); }