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 */