1 /*
2  * PROJECT:         ReactOS Keyboard Layout Switcher
3  * FILE:            base/applications/kbswitch/kbsdll/kbsdll.c
4  * PROGRAMMER:      Dmitry Chapyshev <dmitry@reactos.org>
5  *
6  */
7 
8 #include "../kbswitch.h"
9 
10 HHOOK hWinHook = NULL;
11 HHOOK hShellHook = NULL;
12 HINSTANCE hInstance = NULL;
13 HWND hKbSwitchWnd = NULL;
14 
15 static VOID
16 SendMessageToMainWnd(UINT Msg, WPARAM wParam, LPARAM lParam)
17 {
18     PostMessage(hKbSwitchWnd, Msg, wParam, lParam);
19 }
20 
21 LRESULT CALLBACK
22 WinHookProc(int code, WPARAM wParam, LPARAM lParam)
23 {
24     int id = GlobalAddAtom(_T("KBSWITCH"));
25 
26     switch (code)
27     {
28         case HCBT_SETFOCUS:
29         {
30             if ((HWND)wParam != NULL)
31             {
32                 if ((HWND)wParam != hKbSwitchWnd)
33                 {
34                     SendMessageToMainWnd(WM_WINDOW_ACTIVATE, wParam, lParam);
35                 }
36             }
37         }
38         break;
39     }
40 
41     GlobalDeleteAtom(id);
42 
43     return CallNextHookEx(hWinHook, code, wParam, lParam);
44 }
45 
46 LRESULT CALLBACK
47 ShellHookProc(int code, WPARAM wParam, LPARAM lParam)
48 {
49     switch (code)
50     {
51         case HSHELL_LANGUAGE:
52         {
53             SendMessageToMainWnd(WM_LANG_CHANGED, wParam, lParam);
54         }
55         break;
56     }
57 
58     return CallNextHookEx(hShellHook, code, wParam, lParam);
59 }
60 
61 BOOL WINAPI
62 KbSwitchSetHooks(VOID)
63 {
64     hWinHook = SetWindowsHookEx(WH_CBT, WinHookProc, hInstance, 0);
65     hShellHook = SetWindowsHookEx(WH_SHELL, ShellHookProc, hInstance, 0);
66 
67     if (!hWinHook || !hShellHook)
68     {
69         return FALSE;
70     }
71 
72     return TRUE;
73 }
74 
75 VOID WINAPI
76 KbSwitchDeleteHooks(VOID)
77 {
78     if (hWinHook) UnhookWindowsHookEx(hWinHook);
79     if (hShellHook) UnhookWindowsHookEx(hShellHook);
80 }
81 
82 BOOL WINAPI
83 DllMain(IN HINSTANCE hinstDLL,
84         IN DWORD dwReason,
85         IN LPVOID lpvReserved)
86 {
87     switch (dwReason)
88     {
89         case DLL_PROCESS_ATTACH:
90         {
91             hInstance = hinstDLL;
92             hKbSwitchWnd = FindWindow(szKbSwitcherName, NULL);
93             if (!hKbSwitchWnd)
94             {
95                 return FALSE;
96             }
97         }
98         break;
99     }
100 
101     return TRUE;
102 }
103