mirror of
https://github.com/reactos/reactos.git
synced 2024-06-28 17:01:28 +00:00
- Added kbsdll to install hooks (does not work on ReactOS). To switch layouts temporarily used keys Left Alt + F10
svn path=/trunk/; revision=33607
This commit is contained in:
parent
14f90f0f92
commit
0f37c3c8f0
127
reactos/base/applications/kbswitch/kbsdll/kbsdll.c
Normal file
127
reactos/base/applications/kbswitch/kbsdll/kbsdll.c
Normal file
|
@ -0,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;
|
||||
}
|
7
reactos/base/applications/kbswitch/kbsdll/kbsdll.def
Normal file
7
reactos/base/applications/kbswitch/kbsdll/kbsdll.def
Normal file
|
@ -0,0 +1,7 @@
|
|||
LIBRARY kbsdll.dll
|
||||
|
||||
EXPORTS
|
||||
KbSwitchSetHooks
|
||||
KbSwitchDeleteHooks
|
||||
|
||||
; EOF
|
15
reactos/base/applications/kbswitch/kbsdll/kbsdll.rbuild
Normal file
15
reactos/base/applications/kbswitch/kbsdll/kbsdll.rbuild
Normal file
|
@ -0,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>
|
8
reactos/base/applications/kbswitch/kbsdll/kbsdll.rc
Normal file
8
reactos/base/applications/kbswitch/kbsdll/kbsdll.rc
Normal file
|
@ -0,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>
|
||||
|
|
@ -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 @@ GetLayoutName(LPTSTR szLayoutNum, LPTSTR szName);
|
|||
|
||||
HINSTANCE hInst;
|
||||
HANDLE hProcessHeap;
|
||||
HMODULE hDllLib;
|
||||
ULONG ulCurrentLayoutNum = 1;
|
||||
|
||||
static HICON
|
||||
CreateTrayIcon(LPTSTR szLCID)
|
||||
|
@ -135,7 +138,7 @@ UpdateTrayIcon(HWND hwnd, LPTSTR szLCID, LPTSTR szName)
|
|||
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);
|
||||
|
||||
|
@ -189,6 +192,16 @@ GetLayoutID(LPTSTR szLayoutNum, LPTSTR szLCID)
|
|||
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
|
||||
GetLayoutName(LPTSTR szLayoutNum, LPTSTR szName)
|
||||
{
|
||||
|
@ -258,7 +271,7 @@ GetLayoutName(LPTSTR szLayoutNum, LPTSTR szName)
|
|||
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 @@ ActivateLayout(HWND hwnd, ULONG uLayoutNum)
|
|||
// 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 @@ BuildRightPopupMenu()
|
|||
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 @@ WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
|||
else
|
||||
TrackPopupMenu(hRightPopupMenu, 0, pt.x, pt.y, 0, hwnd, NULL);
|
||||
PostMessage(hwnd, WM_NULL, 0, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -412,9 +510,8 @@ WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
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 @@ WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
|
|||
{
|
||||
//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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue