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(a)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>