[ros-diffs] [dchapyshev] 33607: - Added kbsdll to install hooks (does not work on ReactOS). To switch layouts temporarily used keys Left Alt + F10

dchapyshev at svn.reactos.org dchapyshev at svn.reactos.org
Tue May 20 14:53:32 CEST 2008


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/kbsdll/kbsdll.c?rev=33607&view=auto
==============================================================================
--- 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 at 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/kbsdll/kbsdll.def?rev=33607&view=auto
==============================================================================
--- 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/kbsdll/kbsdll.rbuild?rev=33607&view=auto
==============================================================================
--- 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/kbsdll/kbsdll.rc?rev=33607&view=auto
==============================================================================
--- 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/kbswitch.c?rev=33607&r1=33606&r2=33607&view=diff
==============================================================================
--- 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/kbswitch.h?rev=33607&r1=33606&r2=33607&view=diff
==============================================================================
--- 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/kbswitch.rbuild?rev=33607&r1=33606&r2=33607&view=diff
==============================================================================
--- 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>



More information about the Ros-diffs mailing list