Author: dchapyshev Date: Tue May 20 07:53:31 2008 New Revision: 33607
URL: http://svn.reactos.org/svn/reactos?rev=33607&view=rev Log: - Added kbsdll to install hooks (does not work on ReactOS). To switch layouts temporarily used keys Left Alt + F10
Added: trunk/reactos/base/applications/kbswitch/kbsdll/ trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.c (with props) trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.def (with props) trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.rbuild (with props) trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.rc (with props) Modified: trunk/reactos/base/applications/kbswitch/kbswitch.c trunk/reactos/base/applications/kbswitch/kbswitch.h trunk/reactos/base/applications/kbswitch/kbswitch.rbuild
Added: trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/kbswitch/... ============================================================================== --- trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.c (added) +++ trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.c [iso-8859-1] Tue May 20 07:53:31 2008 @@ -1,0 +1,127 @@ +/* + * PROJECT: ReactOS Keyboard Layout Switcher + * FILE: kbswitch/kbsdll/kbsdll.c + * PROGRAMMER: Dmitry Chapyshev dmitry@reactos.org + * + */ + +#include "../kbswitch.h" + +HHOOK hKeyboardHook, hLangHook, hWinHook; +HINSTANCE hInstance; +HWND hKbSwitchWnd; + +static VOID +SendMessageToMainWnd(UINT Msg, WPARAM wParam, LPARAM lParam) +{ + PostMessage(hKbSwitchWnd, Msg, wParam, lParam); +} + +/* Not used yet */ +LRESULT CALLBACK +KeyboardHookProc(int code, WPARAM wParam, LPARAM lParam) +{ + return CallNextHookEx(hKeyboardHook, code, wParam, lParam); +} + +LRESULT CALLBACK +LangHookProc(int code, WPARAM wParam, LPARAM lParam) +{ + PMSG msg; + msg = (PMSG) lParam; + + switch (msg->message) + { + case WM_INPUTLANGCHANGEREQUEST: + { + SendMessageToMainWnd(WM_LANG_CHANGED, wParam, msg->lParam); + } + break; + + case WM_HOTKEY: + { + if (msg->hwnd) + { + SendMessageToMainWnd(WM_LOAD_LAYOUT, (WPARAM)msg->hwnd, msg->lParam); + } + } + break; + } + + return CallNextHookEx(hLangHook, code, wParam, lParam); +} + +LRESULT CALLBACK +WinHookProc(int code, WPARAM wParam, LPARAM lParam) +{ + int id = GlobalAddAtom(_T("KBSWITCH")); + + switch (code) + { + case HCBT_SETFOCUS: + { + if ((HWND)wParam != NULL) + { + if ((HWND)wParam != hKbSwitchWnd) + { + SendMessageToMainWnd(WM_WINDOW_ACTIVATE, wParam, lParam); + } + } + } + break; + + case HCBT_CREATEWND: + { + RegisterHotKey((HWND)wParam, id, MOD_ALT, VK_F10); + } + break; + + case HCBT_DESTROYWND: + { + UnregisterHotKey((HWND)wParam, id); + } + break; + } + + GlobalDeleteAtom(id); + + return CallNextHookEx(hWinHook, code, wParam, lParam); +} + +BOOL +KbSwitchSetHooks() +{ + hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardHookProc, hInstance, 0); + hLangHook = SetWindowsHookEx(WH_GETMESSAGE, LangHookProc, hInstance, 0); + hWinHook = SetWindowsHookEx(WH_CBT, WinHookProc, hInstance, 0); + + if ((hKeyboardHook)&&(hLangHook)&&(hWinHook)) + return TRUE; + else + return FALSE; +} + +VOID +KbSwitchDeleteHooks() +{ + if (hKeyboardHook) UnhookWindowsHookEx(hKeyboardHook); + if (hLangHook) UnhookWindowsHookEx(hLangHook); + if (hWinHook) UnhookWindowsHookEx(hWinHook); +} + +BOOL WINAPI +DllMain(IN HINSTANCE hinstDLL, + IN DWORD dwReason, + IN LPVOID lpvReserved) +{ + switch (dwReason) + { + case DLL_PROCESS_ATTACH: + hInstance = hinstDLL; + hKbSwitchWnd = FindWindow(szKbSwitcherName, NULL); + if (!hKbSwitchWnd) return FALSE; + break; + } + + return TRUE; +}
Propchange: trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.def URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/kbswitch/... ============================================================================== --- trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.def (added) +++ trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.def [iso-8859-1] Tue May 20 07:53:31 2008 @@ -1,0 +1,7 @@ +LIBRARY kbsdll.dll + +EXPORTS +KbSwitchSetHooks +KbSwitchDeleteHooks + +; EOF
Propchange: trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.def ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/kbswitch/... ============================================================================== --- trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.rbuild (added) +++ trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.rbuild [iso-8859-1] Tue May 20 07:53:31 2008 @@ -1,0 +1,15 @@ +<?xml version="1.0"?> +<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd"> +<module name="kbsdll" type="win32dll" baseaddress="0x74720000" installbase="system32" installname="kbsdll.dll" unicode="yes"> + <importlibrary definition="kbsdll.def" /> + <include base="kbsdll">.</include> + <define name="_WIN32_IE">0x0500</define> + <define name="_WIN32_WINNT">0x0600</define> + <define name="WINVER">0x0600</define> + <library>ntdll</library> + <library>kernel32</library> + <library>user32</library> + <library>comctl32</library> + <file>kbsdll.c</file> + <file>kbsdll.rc</file> +</module>
Propchange: trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.rbuild ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.rc URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/kbswitch/... ============================================================================== --- trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.rc (added) +++ trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.rc [iso-8859-1] Tue May 20 07:53:31 2008 @@ -1,0 +1,8 @@ +#include <windows.h> + +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Keyboard Layout Switcher\0" +#define REACTOS_STR_INTERNAL_NAME "kbsdll\0" +#define REACTOS_STR_ORIGINAL_FILENAME "kbsdll.dll\0" +#include <reactos/version.rc> +
Propchange: trunk/reactos/base/applications/kbswitch/kbsdll/kbsdll.rc ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/base/applications/kbswitch/kbswitch.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/kbswitch/... ============================================================================== --- trunk/reactos/base/applications/kbswitch/kbswitch.c [iso-8859-1] (original) +++ trunk/reactos/base/applications/kbswitch/kbswitch.c [iso-8859-1] Tue May 20 07:53:31 2008 @@ -10,7 +10,8 @@
#define WM_NOTIFYICONMSG (WM_USER + 248)
-TCHAR szKbSwitcherName[] = _T("kbswitcher"); +PROC KbSwitchSetHooks = NULL; +PROC KbSwitchDeleteHooks = NULL;
static BOOL @@ -21,6 +22,8 @@
HINSTANCE hInst; HANDLE hProcessHeap; +HMODULE hDllLib; +ULONG ulCurrentLayoutNum = 1;
static HICON CreateTrayIcon(LPTSTR szLCID) @@ -135,7 +138,7 @@ tnid.cbSize = sizeof(NOTIFYICONDATA); tnid.hWnd = hwnd; tnid.uID = 1; - tnid.uFlags = NIF_ICON | NIF_MESSAGE |NIF_TIP; + tnid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; tnid.uCallbackMessage = WM_NOTIFYICONMSG; tnid.hIcon = CreateTrayIcon(szLCID);
@@ -187,6 +190,16 @@ }
return TRUE; +} + +VOID +GetLayoutIDByHkl(HKL hKl, LPTSTR szLayoutID) +{ + /* + FIXME!!! This way of getting layout ID incorrect! + This will not work correctly for 0001040a, 00010410, etc + */ + wsprintf(szLayoutID, _T("00000%x"), LOWORD(hKl)); }
static BOOL @@ -258,7 +271,7 @@ BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { - SendMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, 0, lParam); + PostMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, 0, lParam); return TRUE; }
@@ -278,8 +291,10 @@ // Switch to the new keyboard layout UpdateTrayIcon(hwnd, szLCID, szName); hKl = LoadKeyboardLayout(szLCID, KLF_ACTIVATE); - SystemParametersInfo(SPI_SETDEFAULTINPUTLANG, 0, &hKl, SPIF_SENDWININICHANGE); + EnumWindows(EnumWindowsProc, (LPARAM) hKl); + + ulCurrentLayoutNum = uLayoutNum; }
static HMENU @@ -360,18 +375,101 @@ return hMenu; }
+BOOL +SetHooks() +{ + hDllLib = LoadLibrary(_T("kbsdll.dll")); + if (!hDllLib) return FALSE; + + KbSwitchSetHooks = (PROC) GetProcAddress(hDllLib, MAKEINTRESOURCEA(1)); + KbSwitchDeleteHooks = (PROC) GetProcAddress(hDllLib, MAKEINTRESOURCEA(2)); + + if ((KbSwitchSetHooks == NULL)||(KbSwitchDeleteHooks == NULL)) + return FALSE; + + return KbSwitchSetHooks(); +} + +VOID +DeleteHooks() +{ + if (KbSwitchDeleteHooks) KbSwitchDeleteHooks(); + if (hDllLib) FreeLibrary(hDllLib); +} + +BOOL CALLBACK +EnumChildProc(HWND hwnd, LPARAM lParam) +{ + SendMessage(hwnd, WM_INPUTLANGCHANGEREQUEST, 0, lParam); + return TRUE; +} + +ULONG +GetNextLayout() +{ + TCHAR szLayoutNum[3 + 1], szLayoutID[CCH_LAYOUT_ID + 1]; + ULONG Ret = ulCurrentLayoutNum; + + _ultot(ulCurrentLayoutNum, szLayoutNum, 10); + if (!GetLayoutID(szLayoutNum, szLayoutID)) + { + return -1; + } + + _ultot(Ret + 1, szLayoutNum, 10); + + if (GetLayoutID(szLayoutNum, szLayoutID)) + { + return (Ret + 1); + } + else + { + _ultot(Ret - 1, szLayoutNum, 10); + if (GetLayoutID(szLayoutNum, szLayoutID)) + return (Ret - 1); + else + return -1; + } + + return -1; +} + LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { static HMENU hLeftPopupMenu, hRightPopupMenu; + static TCHAR szLCID[MAX_PATH];
switch (Message) { case WM_CREATE: + { + SetHooks(); AddTrayIcon(hwnd); hLeftPopupMenu = BuildLeftPopupMenu(hwnd); hRightPopupMenu = BuildRightPopupMenu(hwnd); - break; + } + break; + + case WM_LANG_CHANGED: + { + GetLayoutIDByHkl((HKL)lParam, szLCID); + UpdateTrayIcon(hwnd, szLCID, _T("")); + } + break; + + case WM_LOAD_LAYOUT: + { + ActivateLayout(hwnd, GetNextLayout()); + } + break; + + case WM_WINDOW_ACTIVATE: + { + GetLayoutIDByHkl(GetKeyboardLayout(GetWindowThreadProcessId((HWND)wParam, 0)), szLCID); + UpdateTrayIcon(hwnd, szLCID, _T("")); + } + break;
case WM_NOTIFYICONMSG: switch (lParam) @@ -388,8 +486,8 @@ else TrackPopupMenu(hRightPopupMenu, 0, pt.x, pt.y, 0, hwnd, NULL); PostMessage(hwnd, WM_NULL, 0, 0); - break; } + break; } break;
@@ -412,9 +510,8 @@
if (!ShellExecuteEx(&shInputDll)) MessageBox(hwnd, _T("Can't start input.dll"), NULL, MB_OK | MB_ICONERROR); - - break; } + break;
default: ActivateLayout(hwnd, LOWORD(wParam)); @@ -428,15 +525,18 @@ { //FIXME: Should detect default language changes by CPL applet or by other tools and update UI } - } - break; + } + break;
case WM_DESTROY: + { + DeleteHooks(); DestroyMenu(hLeftPopupMenu); DestroyMenu(hRightPopupMenu); DelTrayIcon(hwnd); PostQuitMessage(0); - break; + } + break; }
return DefWindowProc(hwnd, Message, wParam, lParam);
Modified: trunk/reactos/base/applications/kbswitch/kbswitch.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/kbswitch/... ============================================================================== --- trunk/reactos/base/applications/kbswitch/kbswitch.h [iso-8859-1] (original) +++ trunk/reactos/base/applications/kbswitch/kbswitch.h [iso-8859-1] Tue May 20 07:53:31 2008 @@ -11,3 +11,10 @@
// Maximum Character Count of a ULONG in decimal #define CCH_ULONG_DEC 10 + +#define WM_KEY_PRESSED (WM_USER + 10100) +#define WM_LANG_CHANGED (WM_USER + 10200) +#define WM_WINDOW_ACTIVATE (WM_USER + 10300) +#define WM_LOAD_LAYOUT (WM_USER + 10400) + +TCHAR szKbSwitcherName[] = _T("kbswitcher");
Modified: trunk/reactos/base/applications/kbswitch/kbswitch.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/kbswitch/... ============================================================================== --- trunk/reactos/base/applications/kbswitch/kbswitch.rbuild [iso-8859-1] (original) +++ trunk/reactos/base/applications/kbswitch/kbswitch.rbuild [iso-8859-1] Tue May 20 07:53:31 2008 @@ -1,13 +1,16 @@ <?xml version="1.0"?> <group xmlns:xi="http://www.w3.org/2001/XInclude"> - <module name="kbswitch" type="win32gui" installbase="system32" installname="kbswitch.exe" unicode="yes"> - <include base="kbswitch">.</include> - <library>kernel32</library> - <library>advapi32</library> - <library>user32</library> - <library>shell32</library> - <library>gdi32</library> - <file>kbswitch.c</file> - <file>kbswitch.rc</file> - </module> +<module name="kbswitch" type="win32gui" installbase="system32" installname="kbswitch.exe" unicode="yes"> + <include base="kbswitch">.</include> + <library>kernel32</library> + <library>advapi32</library> + <library>user32</library> + <library>shell32</library> + <library>gdi32</library> + <file>kbswitch.c</file> + <file>kbswitch.rc</file> +</module> +<directory name="kbsdll"> + <xi:include href="kbsdll/kbsdll.rbuild" /> +</directory> </group>