diff --git a/inc/dd.h b/inc/dd.h
index a344d7d..ae096f9 100644
--- a/inc/dd.h
+++ b/inc/dd.h
@@ -125,6 +125,7 @@ typedef struct CNCDDRAW
     BOOL fixpitch;
     int fixchilds;
     BOOL fixwndprochook;
+    BOOL fixmousehook;
     BOOL fixnotresponding;
     BOOL d3d9linear;
     BOOL gdilinear;
diff --git a/inc/mouse.h b/inc/mouse.h
index b3c6460..4457c08 100644
--- a/inc/mouse.h
+++ b/inc/mouse.h
@@ -3,6 +3,9 @@
 
 void mouse_lock();
 void mouse_unlock();
+LRESULT CALLBACK mouse_hook_proc(int Code, WPARAM wParam, LPARAM lParam);
 
+extern HHOOK g_mouse_hook;
+extern HOOKPROC g_mouse_proc;
 
 #endif
diff --git a/src/config.c b/src/config.c
index 19d7c73..3bda579 100644
--- a/src/config.c
+++ b/src/config.c
@@ -62,6 +62,7 @@ void cfg_load()
     g_ddraw->fixpitch = cfg_get_bool("fixpitch", FALSE);
     g_ddraw->fixchilds = cfg_get_int("fixchilds", FIX_CHILDS_DETECT_PAINT);
     g_ddraw->fixwndprochook = cfg_get_bool("fixwndprochook", FALSE);
+    g_ddraw->fixmousehook = cfg_get_bool("fixmousehook", FALSE);
     g_ddraw->fixnotresponding = cfg_get_bool("fixnotresponding", FALSE);
     g_ddraw->d3d9linear = cfg_get_bool("d3d9linear", TRUE);
     g_ddraw->gdilinear = cfg_get_bool("gdilinear", FALSE);
@@ -722,7 +723,15 @@ static void cfg_create_ini()
             "\n"
             "; Jagged Alliance 2\n"
             "[ja2]\n"
-            "hook=0\n"
+            "fixmousehook=true\n"
+            "\n"
+            "; Jagged Alliance 2: Wildfire\n"
+            "[WF6]\n"
+            "fixmousehook=true\n"
+            "\n"
+            "; Jagged Alliance 2 - UC mod\n"
+            "[JA2_UC]\n"
+            "fixmousehook=true\n"
             "\n"
             "; Kings Quest 8\n"
             "[Mask]\n"
diff --git a/src/hook.c b/src/hook.c
index bddaabd..a6fb2a5 100644
--- a/src/hook.c
+++ b/src/hook.c
@@ -566,6 +566,7 @@ void hook_early_init()
     hook_patch_iat(GetModuleHandle(NULL), FALSE, "dinput8.dll", "DirectInput8Create", (PROC)fake_DirectInput8Create);
     hook_patch_iat(GetModuleHandle(NULL), FALSE, "user32.dll", "GetClientRect", (PROC)fake_GetClientRect); //anno 1602
     hook_patch_iat(GetModuleHandle("AcGenral"), FALSE, "user32.dll", "SetWindowsHookExA", (PROC)fake_SetWindowsHookExA);
+    hook_patch_iat(GetModuleHandle(NULL), FALSE, "user32.dll", "SetWindowsHookExA", (PROC)fake_SetWindowsHookExA);
 }
 
 void hook_exit()
@@ -621,4 +622,5 @@ void hook_exit()
     hook_patch_iat(GetModuleHandle(NULL), TRUE, "dinput8.dll", "DirectInput8Create", (PROC)fake_DirectInput8Create);
     hook_patch_iat(GetModuleHandle(NULL), TRUE, "user32.dll", "GetClientRect", (PROC)fake_GetClientRect); //anno 1602
     hook_patch_iat(GetModuleHandle("AcGenral"), TRUE, "user32.dll", "SetWindowsHookExA", (PROC)fake_SetWindowsHookExA);
+    hook_patch_iat(GetModuleHandle(NULL), TRUE, "user32.dll", "SetWindowsHookExA", (PROC)fake_SetWindowsHookExA);
 }
diff --git a/src/mouse.c b/src/mouse.c
index 9f5f79b..774dd4b 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -1,10 +1,13 @@
-#define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include "debug.h"
+#include "winapi_hooks.h"
 #include "dd.h"
 #include "hook.h"
 
 
+HHOOK g_mouse_hook;
+HOOKPROC g_mouse_proc;
+
 void mouse_lock()
 {
     if (g_ddraw->devmode || g_ddraw->bnet_active)
@@ -93,3 +96,51 @@ void mouse_unlock()
             (int)(rc.top + g_ddraw->render.viewport.y + ((cur_y + g_ddraw->mouse_y_adjust) * g_ddraw->render.scale_h)));
     }
 }
+
+LRESULT CALLBACK mouse_hook_proc(int Code, WPARAM wParam, LPARAM lParam)
+{
+    if (!g_ddraw || !g_ddraw->fixmousehook)
+        return g_mouse_proc(Code, wParam, lParam);
+
+    if (Code < 0)
+        return CallNextHookEx(g_mouse_hook, Code, wParam, lParam);
+
+    switch (wParam)
+    {
+    case WM_LBUTTONUP:
+    case WM_RBUTTONUP:
+    case WM_MBUTTONUP:
+    {
+        if (!g_ddraw->devmode && !g_ddraw->locked)
+        {
+            mouse_lock();
+            return CallNextHookEx(g_mouse_hook, Code, wParam, lParam);
+        }
+        break;
+    }
+    /* down messages are ignored if we have no cursor lock */
+    case WM_XBUTTONDBLCLK:
+    case WM_XBUTTONDOWN:
+    case WM_XBUTTONUP:
+    case WM_MOUSEWHEEL:
+    case WM_MOUSEHOVER:
+    case WM_LBUTTONDBLCLK:
+    case WM_MBUTTONDBLCLK:
+    case WM_RBUTTONDBLCLK:
+    case WM_LBUTTONDOWN:
+    case WM_RBUTTONDOWN:
+    case WM_MBUTTONDOWN:
+    case WM_MOUSEMOVE:
+    {
+        if (!g_ddraw->devmode && !g_ddraw->locked)
+        {
+            return CallNextHookEx(g_mouse_hook, Code, wParam, lParam);
+        }
+        break;
+    }
+    }
+
+    fake_GetCursorPos(&((MOUSEHOOKSTRUCT*)lParam)->pt);
+
+    return g_mouse_proc(Code, wParam, lParam);
+}
diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c
index 95e0a9d..04d4772 100644
--- a/src/winapi_hooks.c
+++ b/src/winapi_hooks.c
@@ -492,6 +492,12 @@ HHOOK WINAPI fake_SetWindowsHookExA(int idHook, HOOKPROC lpfn, HINSTANCE hmod, D
         return NULL;
     }
 
+    if (idHook == WH_MOUSE && lpfn && !g_mouse_hook)
+    {
+        g_mouse_proc = lpfn;
+        return g_mouse_hook = real_SetWindowsHookExA(idHook, mouse_hook_proc, hmod, dwThreadId);
+    }
+
     return real_SetWindowsHookExA(idHook, lpfn, hmod, dwThreadId);
 }
 
@@ -589,6 +595,12 @@ HWND WINAPI fake_CreateWindowExA(
     DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y,
     int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
 {
+    /* Fix for SMACKW32.DLL creating another window that steals the focus */
+    if (HIWORD(lpClassName) && _strcmpi(lpClassName, "MouseTypeWind") == 0 && g_ddraw)
+    {
+        dwStyle &= ~WS_VISIBLE;
+    }
+
     if (HIWORD(lpClassName) && _strcmpi(lpClassName, "SDlgDialog") == 0 && g_ddraw)
     {
         if (!g_ddraw->bnet_active)
diff --git a/src/wndproc.c b/src/wndproc.c
index d8ab5e6..37c0246 100644
--- a/src/wndproc.c
+++ b/src/wndproc.c
@@ -539,8 +539,20 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
                 break;
             }
 
-            if (wParam && g_ddraw->alt_key_down)
-                PostMessageA(g_ddraw->hwnd, WM_SYSKEYUP, VK_MENU, 0);
+            /* jagged alliance 2 */
+            if (wParam)
+            {
+                INPUT ip;
+                memset(&ip, 0, sizeof(ip));
+
+                ip.type = INPUT_KEYBOARD;
+                ip.ki.wVk = VK_MENU;
+                ip.ki.dwFlags = KEYEVENTF_KEYUP;
+                SendInput(1, &ip, sizeof(ip));
+            }
+            
+            //if (wParam && g_ddraw->alt_key_down)
+            //    PostMessageA(g_ddraw->hwnd, WM_SYSKEYUP, VK_MENU, 0);
 
             return 0;
         }