[ros-diffs] [cfinck] 33062: - Add the actual function for switching the keyboard layout - Handle keyboard layout substitutes (like the "German (IBM)" layout) - Refactor many parts of the code: * Always close hKey handles after they were successfully opened * Build the keyboard layout menu one time and not everytime, when it's opened * Use smaller sizes for some string variables, defined with CCH_LAYOUT_ID and CCH_ULONG_DEC. This also ensures that we don't retrieve bigger values, which would be invalid. - Use a consistent indentation

cfinck at svn.reactos.org cfinck at svn.reactos.org
Sun Apr 20 17:48:44 CEST 2008


Author: cfinck
Date: Sun Apr 20 10:48:43 2008
New Revision: 33062

URL: http://svn.reactos.org/svn/reactos?rev=33062&view=rev
Log:
- Add the actual function for switching the keyboard layout
- Handle keyboard layout substitutes (like the "German (IBM)" layout)
- Refactor many parts of the code:
   * Always close hKey handles after they were successfully opened
   * Build the keyboard layout menu one time and not everytime, when it's opened
   * Use smaller sizes for some string variables, defined with CCH_LAYOUT_ID and CCH_ULONG_DEC.
     This also ensures that we don't retrieve bigger values, which would be invalid.
- Use a consistent indentation

Modified:
    trunk/reactos/base/applications/kbswitch/kbswitch.c
    trunk/reactos/base/applications/kbswitch/kbswitch.h

Modified: trunk/reactos/base/applications/kbswitch/kbswitch.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/kbswitch/kbswitch.c?rev=33062&r1=33061&r2=33062&view=diff
==============================================================================
--- trunk/reactos/base/applications/kbswitch/kbswitch.c [iso-8859-1] (original)
+++ trunk/reactos/base/applications/kbswitch/kbswitch.c [iso-8859-1] Sun Apr 20 10:48:43 2008
@@ -1,4 +1,12 @@
-#include <kbswitch.h>
+/*
+ * PROJECT:         Keyboard Layout Switcher
+ * FILE:            base\applications\kbswitch\kbswitch.c
+ * PURPOSE:         Switching Keyboard Layouts
+ * PROGRAMMERS:     Dmitry Chapyshev (dmitry at reactos.org)
+ *                  Colin Finck (mail at colinfinck.de)
+ */
+
+#include "kbswitch.h"
 
 #define WM_NOTIFYICONMSG (WM_USER + 248)
 #define BUFSIZE 256
@@ -9,13 +17,13 @@
 static VOID
 AddTrayIcon(HWND hwnd, HICON hIcon)
 {
-	NOTIFYICONDATA tnid;
+    NOTIFYICONDATA tnid;
 
     tnid.cbSize = sizeof(NOTIFYICONDATA);
     tnid.hWnd = hwnd;
     tnid.uID = 1;
     tnid.uFlags = NIF_ICON | NIF_MESSAGE;
-	tnid.uCallbackMessage = WM_NOTIFYICONMSG;
+    tnid.uCallbackMessage = WM_NOTIFYICONMSG;
     tnid.hIcon = hIcon;
 
     Shell_NotifyIcon(NIM_ADD, &tnid);
@@ -26,156 +34,199 @@
 static VOID
 DelTrayIcon(HWND hwnd)
 {
-	NOTIFYICONDATA tnid;
-
-	tnid.cbSize = sizeof(NOTIFYICONDATA);
-	tnid.hWnd = hwnd;
-	tnid.uID = 1;
-
-	Shell_NotifyIcon(NIM_DELETE, &tnid);
+    NOTIFYICONDATA tnid;
+
+    tnid.cbSize = sizeof(NOTIFYICONDATA);
+    tnid.hWnd = hwnd;
+    tnid.uID = 1;
+
+    Shell_NotifyIcon(NIM_DELETE, &tnid);
 }
 
 static BOOL
-GetLayoutName(LPCTSTR lcid, LPTSTR name)
+GetLayoutID(LPTSTR szLayoutNum, LPTSTR szLCID)
+{
+    DWORD dwBufLen;
+    DWORD dwTest;
+    HKEY hKey;
+    TCHAR szTempLCID[CCH_LAYOUT_ID + 1];
+
+    // Get the Layout ID
+    if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+    {
+        dwBufLen = sizeof(szTempLCID);
+
+        if(RegQueryValueEx(hKey, szLayoutNum, NULL, NULL, (LPBYTE)szTempLCID, &dwBufLen) != ERROR_SUCCESS)
+        {
+            RegCloseKey(hKey);
+            return FALSE;
+        }
+
+        RegCloseKey(hKey);
+    }
+
+    // Look for a substitude of this layout
+    if(RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Substitutes"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+    {
+        dwBufLen = sizeof(szTempLCID);
+
+        if(RegQueryValueEx(hKey, szTempLCID, NULL, NULL, (LPBYTE)szLCID, &dwBufLen) != ERROR_SUCCESS)
+        {
+            // No substitute found, then use the old LCID
+            lstrcpy(szLCID, szTempLCID);
+        }
+
+        RegCloseKey(hKey);
+    }
+    else
+    {
+        // Substitutes key couldn't be opened, so use the old LCID
+        lstrcpy(szLCID, szTempLCID);
+    }
+
+    return TRUE;
+}
+
+static BOOL
+GetLayoutName(LPTSTR szLayoutNum, LPTSTR szName)
 {
     HKEY hKey;
     DWORD dwBufLen;
-    TCHAR szBuf[BUFSIZE];
-
-    _stprintf(szBuf, _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"),lcid);
+    TCHAR szBuf[MAX_PATH];
+    TCHAR szLCID[CCH_LAYOUT_ID + 1];
+
+    if(!GetLayoutID(szLayoutNum, szLCID))
+        return FALSE;
+
+    wsprintf(szBuf, _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%s"), szLCID);
 
     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)szBuf, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
     {
-        dwBufLen = BUFSIZE;
-        if (RegQueryValueEx(hKey,_T("Layout Text"),NULL,NULL,(LPBYTE)name,&dwBufLen) == ERROR_SUCCESS)
+        dwBufLen = MAX_PATH * sizeof(TCHAR);
+
+        if(RegQueryValueEx(hKey, _T("Layout Text"), NULL, NULL, (LPBYTE)szName, &dwBufLen) != ERROR_SUCCESS)
         {
             RegCloseKey(hKey);
-            return TRUE;
-        }
-    }
-
-    return FALSE;
+            return FALSE;
+        }
+
+        RegCloseKey(hKey);
+    }
+
+    return TRUE;
 }
 
 static VOID
-ActivateLayout(INT LayoutID)
-{
-	TCHAR szLayoutID[MAX_PATH], szNewLayout[MAX_PATH];
-	HKEY hKey;
-	DWORD dwBufLen;
-
-	_stprintf(szLayoutID, _T("%d"), LayoutID);
-
-	if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
-	{
-		dwBufLen = MAX_PATH;
-		if (RegQueryValueEx(hKey, szLayoutID, NULL, NULL, (LPBYTE)szNewLayout, &dwBufLen) == ERROR_SUCCESS)
-		{
-			MessageBox(0, szNewLayout, _T(""), MB_OK);
-			RegCloseKey(hKey);
-		}
-	}
-}
-
-static VOID
-ShowPopupMenu(HWND hwnd, POINT pt)
-{
-	HMENU hMenu;
-	HKEY hKey;
-	DWORD dwIndex = 0, dwSize, dwType;
-	LONG Ret;
-	TCHAR szBuf[MAX_PATH], szPreload[MAX_PATH], szName[MAX_PATH];
-
-	hMenu = CreatePopupMenu();
-
-    if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"),
-        0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
-	{
-		dwSize = MAX_PATH;
-		Ret = RegEnumValue(hKey, dwIndex, szBuf, &dwSize, NULL, &dwType, NULL, NULL);
-		if (Ret == ERROR_SUCCESS)
-		{
-			while (Ret == ERROR_SUCCESS)
-			{
-				dwSize = MAX_PATH;
-				RegQueryValueEx(hKey, szBuf, NULL, NULL, (LPBYTE)szPreload, &dwSize);
-
-				GetLayoutName(szPreload, szName);
-				AppendMenu(hMenu, MF_STRING, _ttoi(szBuf), szName);
-
-				dwIndex++;
-
-				dwSize = MAX_PATH;
-				Ret = RegEnumValue(hKey, dwIndex, szBuf, &dwSize, NULL, &dwType, NULL, NULL);
-			}
-		}
-	}
-
-	TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, hwnd, NULL);
-	DestroyMenu(hMenu);
-	RegCloseKey(hKey);
+ActivateLayout(ULONG uLayoutNum)
+{
+    HKL hKl;
+    TCHAR szLayoutNum[CCH_ULONG_DEC + 1];
+    TCHAR szLCID[CCH_LAYOUT_ID + 1];
+    DWORD Ret;
+
+    _ultot(uLayoutNum, szLayoutNum, 10);
+    GetLayoutID(szLayoutNum, szLCID);
+
+    // Switch to the new keyboard layout
+    hKl = LoadKeyboardLayout(szLCID, KLF_ACTIVATE);
+    Ret = SystemParametersInfo(SPI_SETDEFAULTINPUTLANG, 0, &hKl, SPIF_SENDWININICHANGE);
+}
+
+static HMENU
+BuildPopupMenu()
+{
+    HMENU hMenu;
+    HKEY hKey;
+    DWORD dwIndex, dwSize;
+    TCHAR szLayoutNum[CCH_ULONG_DEC + 1];
+    TCHAR szName[MAX_PATH];
+
+    hMenu = CreatePopupMenu();
+
+    if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Keyboard Layout\\Preload"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+    {
+        for(dwIndex = 0; ; dwIndex++)
+        {
+            dwSize = sizeof(szLayoutNum);
+            if(RegEnumValue(hKey, dwIndex, szLayoutNum, &dwSize, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
+                break;
+
+            if(!GetLayoutName(szLayoutNum, szName))
+                break;
+
+            AppendMenu(hMenu, MF_STRING, _ttoi(szLayoutNum), szName);
+        }
+
+        RegCloseKey(hKey);
+    }
+
+    return hMenu;
 }
 
 LRESULT CALLBACK
 WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
 {
-	POINT pt;
-
-	switch (Message)
-	{
-		case WM_CREATE:
-			AddTrayIcon(hwnd, LoadIcon(hInst, MAKEINTRESOURCE(IDI_MAIN)));
-		break;
-
-		case WM_NOTIFYICONMSG:
-			switch (lParam)
-			{
-				case WM_LBUTTONDBLCLK:
-				case WM_LBUTTONDOWN:
-				case WM_RBUTTONDOWN:
-				{
-					GetCursorPos(&pt);
-					ShowPopupMenu(hwnd, pt);
-				}
-				break;
-			}
-		break;
-
-		case WM_COMMAND:
-			ActivateLayout(LOWORD(wParam));
-		break;
-
-		case WM_DESTROY:
-			DelTrayIcon(hwnd);
-			PostQuitMessage(0);
-		break;
-	}
-
-	return DefWindowProc(hwnd, Message, wParam, lParam);
+    static HMENU hPopupMenu;
+
+    switch (Message)
+    {
+        case WM_CREATE:
+            AddTrayIcon(hwnd, LoadIcon(hInst, MAKEINTRESOURCE(IDI_MAIN)));
+            hPopupMenu = BuildPopupMenu(hwnd);
+            break;
+
+        case WM_NOTIFYICONMSG:
+            switch (lParam)
+            {
+                case WM_LBUTTONDBLCLK:
+                case WM_LBUTTONDOWN:
+                case WM_RBUTTONDOWN:
+                {
+                    POINT pt;
+
+                    GetCursorPos(&pt);
+                    TrackPopupMenu(hPopupMenu, 0, pt.x, pt.y, 0, hwnd, NULL);
+                }
+                break;
+            }
+            break;
+
+        case WM_COMMAND:
+            ActivateLayout(LOWORD(wParam));
+            break;
+
+        case WM_DESTROY:
+            DestroyMenu(hPopupMenu);
+            DelTrayIcon(hwnd);
+            PostQuitMessage(0);
+            break;
+    }
+
+    return DefWindowProc(hwnd, Message, wParam, lParam);
 }
 
 INT WINAPI
 wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPTSTR lpCmdLine, INT nCmdShow)
 {
-	WNDCLASS WndClass = {0};
-	MSG msg;
-
-	hInst = hInstance;
-
-	WndClass.style = 0;
-	WndClass.lpfnWndProc   = (WNDPROC)WndProc;
-	WndClass.cbClsExtra    = 0;
-	WndClass.cbWndExtra    = 0;
-	WndClass.hInstance     = hInstance;
-	WndClass.hIcon         = NULL;
-	WndClass.hCursor       = NULL;
-	WndClass.hbrBackground = NULL;
-	WndClass.lpszMenuName  = NULL;
-	WndClass.lpszClassName = L"kbswitch";
-
-	if (!RegisterClass(&WndClass)) return 0;
-
-	hwnd = CreateWindow(L"kbswitch", L"kbswitch", 0, 0, 0, 1, 1, HWND_DESKTOP, NULL, hInstance, NULL);
+    WNDCLASS WndClass = {0};
+    MSG msg;
+
+    hInst = hInstance;
+
+    WndClass.style = 0;
+    WndClass.lpfnWndProc   = (WNDPROC)WndProc;
+    WndClass.cbClsExtra    = 0;
+    WndClass.cbWndExtra    = 0;
+    WndClass.hInstance     = hInstance;
+    WndClass.hIcon         = NULL;
+    WndClass.hCursor       = NULL;
+    WndClass.hbrBackground = NULL;
+    WndClass.lpszMenuName  = NULL;
+    WndClass.lpszClassName = L"kbswitch";
+
+    if (!RegisterClass(&WndClass)) return 0;
+
+    hwnd = CreateWindow(L"kbswitch", L"kbswitch", 0, 0, 0, 1, 1, HWND_DESKTOP, NULL, hInstance, NULL);
 
     while(GetMessage(&msg,NULL,0,0))
     {

Modified: trunk/reactos/base/applications/kbswitch/kbswitch.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/kbswitch/kbswitch.h?rev=33062&r1=33061&r2=33062&view=diff
==============================================================================
--- trunk/reactos/base/applications/kbswitch/kbswitch.h [iso-8859-1] (original)
+++ trunk/reactos/base/applications/kbswitch/kbswitch.h [iso-8859-1] Sun Apr 20 10:48:43 2008
@@ -1,6 +1,11 @@
+#include <stdlib.h>
 #include <windows.h>
 #include <tchar.h>
-#include <stdio.h>
-#include <stdlib.h>
 
 #include "resource.h"
+
+// Character Count of a layout ID like "00000409"
+#define CCH_LAYOUT_ID    8
+
+// Maximum Character Count of a ULONG in decimal
+#define CCH_ULONG_DEC    10



More information about the Ros-diffs mailing list