diff --git a/cnc-ddraw.vcxproj b/cnc-ddraw.vcxproj index c9500e9..992cb3e 100644 --- a/cnc-ddraw.vcxproj +++ b/cnc-ddraw.vcxproj @@ -51,6 +51,7 @@ + @@ -87,6 +88,7 @@ + diff --git a/cnc-ddraw.vcxproj.filters b/cnc-ddraw.vcxproj.filters index 7de9def..e1e9a15 100644 --- a/cnc-ddraw.vcxproj.filters +++ b/cnc-ddraw.vcxproj.filters @@ -165,6 +165,9 @@ Source Files + + Source Files + @@ -287,6 +290,9 @@ Header Files + + Header Files + diff --git a/inc/keyboard.h b/inc/keyboard.h new file mode 100644 index 0000000..8962198 --- /dev/null +++ b/inc/keyboard.h @@ -0,0 +1,11 @@ +#ifndef KEYBOARD_H +#define KEYBOARD_H + + +void keyboard_hook_init(); +void keyboard_hook_exit(); +LRESULT CALLBACK keyboard_hook_proc(int Code, WPARAM wParam, LPARAM lParam); + +extern HHOOK g_keyboard_hook; + +#endif diff --git a/src/dd.c b/src/dd.c index bb28d7f..bff1ec8 100644 --- a/src/dd.c +++ b/src/dd.c @@ -6,6 +6,7 @@ #include "hook.h" #include "config.h" #include "mouse.h" +#include "keyboard.h" #include "wndproc.h" #include "render_d3d9.h" #include "render_gdi.h" @@ -1362,6 +1363,8 @@ HRESULT dd_SetCooperativeLevel(HWND hwnd, DWORD dwFlags) g_ddraw.wndproc = (WNDPROC)real_SetWindowLongA(g_ddraw.hwnd, GWL_WNDPROC, (LONG)fake_WndProc); g_ddraw.gui_thread_id = GetWindowThreadProcessId(g_ddraw.hwnd, NULL); + keyboard_hook_init(); + if (!g_ddraw.render.hdc) { g_ddraw.render.hdc = GetDC(g_ddraw.hwnd); diff --git a/src/dllmain.c b/src/dllmain.c index b75c335..cfb3013 100644 --- a/src/dllmain.c +++ b/src/dllmain.c @@ -138,6 +138,7 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) indeo_disable(); timeEndPeriod(1); + keyboard_hook_exit(); dinput_hook_exit(); hook_exit(); break; diff --git a/src/keyboard.c b/src/keyboard.c new file mode 100644 index 0000000..e4145cf --- /dev/null +++ b/src/keyboard.c @@ -0,0 +1,102 @@ +#include +#include "debug.h" +#include "hook.h" +#include "dd.h" +#include "utils.h" +#include "config.h" +#include "keyboard.h" +#include "mouse.h" + + +HHOOK g_keyboard_hook; + +void keyboard_hook_init() +{ + if (g_keyboard_hook && UnhookWindowsHookEx(g_keyboard_hook)) + { + g_keyboard_hook = NULL; + } + + if (!g_ddraw.gui_thread_id) + return; + + g_keyboard_hook = + real_SetWindowsHookExA( + WH_KEYBOARD, + keyboard_hook_proc, + NULL, + g_ddraw.gui_thread_id); +} + +void keyboard_hook_exit() +{ + if (g_keyboard_hook) + { + UnhookWindowsHookEx(g_keyboard_hook); + } +} + +LRESULT CALLBACK keyboard_hook_proc(int code, WPARAM wParam, LPARAM lParam) +{ + if (code < 0 || !wParam) // code != HC_ACTION || + return CallNextHookEx(g_keyboard_hook, code, wParam, lParam); + + BOOL alt_down = (lParam & (1 << 29)); + BOOL key_down = !(lParam & (1 << 30)); + BOOL key_up = !!(lParam & (1 << 31)); + + if (wParam == g_config.hotkeys.toggle_fullscreen && alt_down) + { + if (key_up) + util_toggle_fullscreen(); + + return 1; + } + + if (wParam == g_config.hotkeys.toggle_maximize && + g_config.resizable && + g_config.windowed && + !g_config.fullscreen && + alt_down) + { + if (key_up) + util_toggle_maximize(); + + return 1; + } + + if (g_config.homm_hack && wParam == VK_F4) /* Heroes of Might and Magic 3 and 4 */ + { + if (key_up) + util_toggle_fullscreen(); + + return 1; + } + + if (wParam == VK_CONTROL || wParam == g_config.hotkeys.unlock_cursor1) + { + if ((real_GetAsyncKeyState(VK_CONTROL) & 0x8000) && + (real_GetAsyncKeyState(g_config.hotkeys.unlock_cursor1) & 0x8000)) + { + mouse_unlock(); + return 1; + } + } + + if (wParam == g_config.hotkeys.unlock_cursor2 || wParam == VK_MENU || wParam == VK_CONTROL) + { + if ((real_GetAsyncKeyState(VK_RMENU) & 0x8000) && + (real_GetAsyncKeyState(g_config.hotkeys.unlock_cursor2) & 0x8000)) + { + mouse_unlock(); + return 1; + } + } + + if (key_up && wParam == g_config.hotkeys.screenshot) + { + ss_take_screenshot(g_ddraw.primary); + } + + return CallNextHookEx(g_keyboard_hook, code, wParam, lParam); +} diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c index 6768a9b..68dc9dd 100644 --- a/src/winapi_hooks.c +++ b/src/winapi_hooks.c @@ -9,6 +9,7 @@ #include "config.h" #include "utils.h" #include "mouse.h" +#include "keyboard.h" #include "wndproc.h" #include "render_gdi.h" #include "render_d3d9.h" @@ -601,7 +602,14 @@ HHOOK WINAPI fake_SetWindowsHookExA(int idHook, HOOKPROC lpfn, HINSTANCE hmod, D return g_mouse_hook = real_SetWindowsHookExA(idHook, mouse_hook_proc, hmod, dwThreadId); } - return real_SetWindowsHookExA(idHook, lpfn, hmod, dwThreadId); + HHOOK result = real_SetWindowsHookExA(idHook, lpfn, hmod, dwThreadId); + + if (idHook == WH_KEYBOARD) + { + keyboard_hook_init(); + } + + return result; } BOOL HandleMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax) diff --git a/src/wndproc.c b/src/wndproc.c index a12c2c5..2da7daf 100644 --- a/src/wndproc.c +++ b/src/wndproc.c @@ -758,29 +758,6 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam } case WM_SYSKEYDOWN: { - BOOL context_code = (lParam & (1 << 29)) != 0; - BOOL key_state = (lParam & (1 << 30)) != 0; - - if (g_config.hotkeys.toggle_fullscreen && - wParam == g_config.hotkeys.toggle_fullscreen && - (!g_config.fullscreen || g_config.toggle_upscaled || (g_config.windowed && g_config.toggle_borderless)) && - context_code && - !key_state) - { - util_toggle_fullscreen(); - return 0; - } - - if (g_config.hotkeys.toggle_maximize && - wParam == g_config.hotkeys.toggle_maximize && - g_config.resizable && - g_config.windowed && - !g_config.fullscreen) - { - util_toggle_maximize(); - return 0; - } - if (wParam == VK_MENU) { g_ddraw.alt_key_down = TRUE; @@ -795,7 +772,7 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam g_ddraw.alt_key_down = FALSE; } - if (wParam == VK_TAB || (g_config.hotkeys.toggle_fullscreen && wParam == g_config.hotkeys.toggle_fullscreen)) + if (wParam == VK_TAB || (wParam && wParam == g_config.hotkeys.toggle_fullscreen)) { return DefWindowProc(hWnd, uMsg, wParam, lParam); } @@ -804,42 +781,10 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam } case WM_KEYDOWN: { - if (g_config.homm_hack && wParam == VK_F4) /* Heroes of Might and Magic 3 and 4 */ - { - util_toggle_fullscreen(); - return 0; - } - - if (g_config.hotkeys.unlock_cursor1 && - (wParam == VK_CONTROL || wParam == g_config.hotkeys.unlock_cursor1)) - { - if (real_GetAsyncKeyState(VK_CONTROL) & 0x8000 && real_GetAsyncKeyState(g_config.hotkeys.unlock_cursor1) & 0x8000) - { - mouse_unlock(); - return 0; - } - } - - if (g_config.hotkeys.unlock_cursor2 && - (wParam == g_config.hotkeys.unlock_cursor2 || wParam == VK_MENU || wParam == VK_CONTROL)) - { - if ((real_GetAsyncKeyState(VK_RMENU) & 0x8000) && real_GetAsyncKeyState(g_config.hotkeys.unlock_cursor2) & 0x8000) - { - mouse_unlock(); - return 0; - } - } - break; } case WM_KEYUP: { - if (g_config.homm_hack && wParam == VK_F4) /* Heroes of Might and Magic 3 and 4 */ - return 0; - - if (g_config.hotkeys.screenshot && wParam == g_config.hotkeys.screenshot) - ss_take_screenshot(g_ddraw.primary); - break; } /* button up messages reactivate cursor lock */