I am using gainput (https://github.com/jkuhlmann/gainput) for input management and on windows I have to pass in all windows message manually for gainput to correctly register mouse and keyboard events
// Update Gainput
manager.Update();
MSG msg;
while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
// Forward any input messages to Gainput
manager.HandleMessage(msg);
}
unfortunately sokol_app "swallows" all win32 event messages and I have no way to stop sokol from stealing my events.
I found a workaround that makes me handle win32 events before sokol does. I have to paste the following code before the #define SOKOL_IMPL
#if defined(_WIN32)
# ifdef WIN32_LEAN_AND_MEAN
# undef WIN32_LEAN_AND_MEAN
# endif
# include <Windows.h>
// "hook" TranslateMessage call from sokol
extern "C" void hook_TranslateMessage(const MSG *lpMsg);
# define TranslateMessage(MSG) \
hook_TranslateMessage(MSG); \
TranslateMessage(MSG);
#endif
#define SOKOL_IMPL
#define SOKOL_GLCORE33
#include <sokol/sokol_app.h>
then in my main app I just have to implement
#ifdef _WIN32
extern "C" void hook_TranslateMessage(const MSG *msg) {
manager.HandleMessage(*msg);
}
#endif
this works fine, but I am wondering if it is possible to add "native" event callbacks to sapp_desc to handle such cases.
Greetings!
~ Rico (Ex Bigpoint Member)
Hi Rico :)
Hmm yeah that's a good point. I need to think of a good way to expose this type of stuff though because I can't have any Win32-types in the "public API". So basically a callback which takes a void* which would need to be cast to a MSG* in the user-provided callback.
The callback should be passed in via sapp_desc, e.g.
void my_win32_msg_callback(const void* msg) {
const MSG* win32_msg = (const MSG*) msg;
...
}
sapp_desc sokol_main(int argc, char* argv[]) {
return (sapp_desc) {
.win32_msg_intercept_cb = my_win32_msg_callback
....
};
}
There should also be a second sapp_desc callback type with a user_data pointer (same as with the init/frame/event/cleanup callbacks).
I probably won't get around implementing this for a little while because I'm still focused on the WebGPU backend, but you could provide a pull request in the meantime if you want :)
Here is a workaround that works for my use case:
It is possible to replace the WNDPROC callback that handles events for a specific window.
I do so with the following call in init_cb().
SetWindowLongPtr((HWND)sapp_win32_get_hwnd(), GWLP_WNDPROC, (LONG_PTR)hook_sapp_win32_wndproc);
I define the function alongside the sokol_app implementation to get access to the original callback _sapp_win32_wndproc():
_SOKOL_PRIVATE LRESULT CALLBACK hook_sapp_win32_wndproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case ...:
...
default:
break;
}
return _sapp_win32_wndproc(hWnd, uMsg, wParam, lParam);
}
Now about Gainput specifically. They are using MSG structures but they seem to only use the message, wParam, and lParam members. I think you can forward the messages from a custom WNDPROC.
Most helpful comment
Here is a workaround that works for my use case:
It is possible to replace the
WNDPROCcallback that handles events for a specific window.I do so with the following call in
init_cb().I define the function alongside the sokol_app implementation to get access to the original callback
_sapp_win32_wndproc():Now about Gainput specifically. They are using MSG structures but they seem to only use the
message,wParam, andlParammembers. I think you can forward the messages from a customWNDPROC.