[OSK] Implement standard/enhanced keyboard handler (#1338)
[reactos.git] / base / applications / osk / main.c
index 6c17933..72cee21 100644 (file)
@@ -24,7 +24,7 @@ BOOL OSK_DlgCommand(WPARAM wCommand, HWND hWndControl);
 BOOL OSK_ReleaseKey(WORD ScanCode);
 
 INT_PTR APIENTRY OSK_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
-int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int);
+int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int);
 
 /* FUNCTIONS ******************************************************************/
 
@@ -39,8 +39,8 @@ int OSK_SetImage(int IdDlgItem, int IdResource)
     HICON hIcon;
     HWND hWndItem;
 
-    hIcon = (HICON)LoadImage(Globals.hInstance, MAKEINTRESOURCE(IdResource),
-                             IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+    hIcon = (HICON)LoadImageW(Globals.hInstance, MAKEINTRESOURCEW(IdResource),
+                              IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
     if (hIcon == NULL)
         return FALSE;
 
@@ -51,7 +51,7 @@ int OSK_SetImage(int IdDlgItem, int IdResource)
         return FALSE;
     }
 
-    SendMessage(hWndItem, BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hIcon);
+    SendMessageW(hWndItem, BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hIcon);
 
     /* The system automatically deletes these resources when the process that created them terminates (MSDN) */
 
@@ -99,6 +99,32 @@ INT_PTR CALLBACK OSK_WarningProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lPar
     return FALSE;
 }
 
+/***********************************************************************
+ *
+ *          OSK_About
+ *
+ *  Initializes the "About" dialog box
+ */
+VOID OSK_About(VOID)
+{
+    WCHAR szTitle[MAX_BUFF];
+    WCHAR szAuthors[MAX_BUFF];
+    HICON OSKIcon;
+
+    /* Load the icon */
+    OSKIcon = LoadImageW(Globals.hInstance, MAKEINTRESOURCEW(IDI_OSK), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
+
+    /* Load the strings into the "About" dialog */
+    LoadStringW(Globals.hInstance, STRING_OSK, szTitle, countof(szTitle));
+    LoadStringW(Globals.hInstance, STRING_AUTHORS, szAuthors, countof(szAuthors));
+
+    /* Finally, execute the "About" dialog by using the Shell routine */
+    ShellAboutW(Globals.hMainWnd, szTitle, szAuthors, OSKIcon);
+
+    /* Once done, destroy the icon */
+    DestroyIcon(OSKIcon);
+}
+
 
 /***********************************************************************
  *
@@ -108,7 +134,8 @@ INT_PTR CALLBACK OSK_WarningProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lPar
  */
 int OSK_DlgInitDialog(HWND hDlg)
 {
-    HMONITOR  monitor;
+    HICON hIcon, hIconSm;
+    HMONITOR monitor;
     MONITORINFO info;
     POINT Pt;
     RECT rcWindow;
@@ -116,12 +143,33 @@ int OSK_DlgInitDialog(HWND hDlg)
     /* Save handle */
     Globals.hMainWnd = hDlg;
 
-    /* Load the settings from the registry hive */
-    LoadDataFromRegistry();
+    /* Check the checked menu item before displaying the modal box */
+    if (Globals.bIsEnhancedKeyboard)
+    {
+        /* Enhanced keyboard dialog chosen, set the respective menu item as checked */
+        CheckMenuItem(GetMenu(hDlg), IDM_ENHANCED_KB, MF_BYCOMMAND | MF_CHECKED);
+        CheckMenuItem(GetMenu(hDlg), IDM_STANDARD_KB, MF_BYCOMMAND | MF_UNCHECKED);
+    }
+    else
+    {
+        /* Standard keyboard dialog chosen, set the respective menu item as checked */
+        CheckMenuItem(GetMenu(hDlg), IDM_STANDARD_KB, MF_BYCOMMAND | MF_CHECKED);
+        CheckMenuItem(GetMenu(hDlg), IDM_ENHANCED_KB, MF_BYCOMMAND | MF_UNCHECKED);
+    }
+
+    /* Set the application's icon */
+    hIcon = LoadImageW(Globals.hInstance, MAKEINTRESOURCEW(IDI_OSK), IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE);
+    hIconSm = CopyImage(hIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_COPYFROMRESOURCE);
+    if (hIcon || hIconSm)
+    {
+        /* Set the window icons (they are deleted when the process terminates) */
+        SendMessageW(Globals.hMainWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
+        SendMessageW(Globals.hMainWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
+    }
 
     /* Get screen info */
     memset(&Pt, 0, sizeof(Pt));
-    monitor = MonitorFromPoint(Pt, MONITOR_DEFAULTTOPRIMARY );
+    monitor = MonitorFromPoint(Pt, MONITOR_DEFAULTTOPRIMARY);
     info.cbSize = sizeof(info);
     GetMonitorInfoW(monitor, &info);
 
@@ -160,12 +208,6 @@ int OSK_DlgInitDialog(HWND hDlg)
     /* Set a timer for periodics tasks */
     Globals.iTimer = SetTimer(hDlg, 0, 200, NULL);
 
-    /* If the member of the struct (bShowWarning) is set then display the dialog box */
-    if (Globals.bShowWarning)
-    {
-        DialogBox(Globals.hInstance, MAKEINTRESOURCE(IDD_WARNINGDIALOG_OSK), Globals.hMainWnd, OSK_WarningProc);
-    }
-
     return TRUE;
 }
 
@@ -242,19 +284,19 @@ BOOL OSK_DlgCommand(WPARAM wCommand, HWND hWndControl)
         MSG msg;
 
         SetForegroundWindow(Globals.hActiveWnd);
-        while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
+        while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE))
         {
             TranslateMessage(&msg);
-            DispatchMessage(&msg);
+            DispatchMessageW(&msg);
         }
     }
 
     /* KeyDown and/or KeyUp ? */
-    WindowStyle = GetWindowLong(hWndControl, GWL_STYLE);
+    WindowStyle = GetWindowLongW(hWndControl, GWL_STYLE);
     if ((WindowStyle & BS_AUTOCHECKBOX) == BS_AUTOCHECKBOX)
     {
         /* 2-states key like Shift, Alt, Ctrl, ... */
-        if (SendMessage(hWndControl, BM_GETCHECK, 0, 0) == BST_CHECKED)
+        if (SendMessageW(hWndControl, BM_GETCHECK, 0, 0) == BST_CHECKED)
         {
             bKeyDown = TRUE;
             bKeyUp = FALSE;
@@ -323,11 +365,11 @@ BOOL OSK_ReleaseKey(WORD ScanCode)
 
     /* Is it a 2-states key ? */
     hWndControl = GetDlgItem(Globals.hMainWnd, ScanCode);
-    WindowStyle = GetWindowLong(hWndControl, GWL_STYLE);
+    WindowStyle = GetWindowLongW(hWndControl, GWL_STYLE);
     if ((WindowStyle & BS_AUTOCHECKBOX) != BS_AUTOCHECKBOX) return FALSE;
 
     /* Is the key down ? */
-    if (SendMessage(hWndControl, BM_GETCHECK, 0, 0) != BST_CHECKED) return TRUE;
+    if (SendMessageW(hWndControl, BM_GETCHECK, 0, 0) != BST_CHECKED) return TRUE;
 
     /* Extended key ? */
     if (ScanCode & 0x0200)
@@ -390,10 +432,82 @@ INT_PTR APIENTRY OSK_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
             break;
 
         case WM_COMMAND:
-            if (wParam == IDCANCEL)
-                EndDialog(hDlg, FALSE);
-            else if (wParam != IDC_STATIC)
-                OSK_DlgCommand(wParam, (HWND) lParam);
+            switch (LOWORD(wParam))
+            {
+                case IDCANCEL:
+                {
+                    EndDialog(hDlg, FALSE);
+                    break;
+                }
+
+                case IDM_EXIT:
+                {
+                    EndDialog(hDlg, FALSE);
+                    break;
+                }
+
+                case IDM_ENHANCED_KB:
+                {
+                    if (!Globals.bIsEnhancedKeyboard)
+                    {
+                        /* 
+                            The user attempted to switch to enhanced keyboard dialog type.
+                            Set the member value as TRUE, destroy the dialog and save the data configuration into the registry.
+                        */
+                        Globals.bIsEnhancedKeyboard = TRUE;
+                        EndDialog(hDlg, FALSE);
+                        SaveDataToRegistry();
+
+                        /* Change the condition of enhanced keyboard item menu to checked */
+                        CheckMenuItem(GetMenu(hDlg), IDM_ENHANCED_KB, MF_BYCOMMAND | MF_CHECKED);
+                        CheckMenuItem(GetMenu(hDlg), IDM_STANDARD_KB, MF_BYCOMMAND | MF_UNCHECKED);
+
+                        /* Finally, display the dialog modal box with the enhanced keyboard dialog */
+                        DialogBoxW(Globals.hInstance,
+                                   MAKEINTRESOURCEW(MAIN_DIALOG_ENHANCED_KB),
+                                   GetDesktopWindow(),
+                                   OSK_DlgProc);
+                    }
+
+                    break;
+                }
+
+                case IDM_STANDARD_KB:
+                {
+                    if (Globals.bIsEnhancedKeyboard)
+                    {
+                        /*
+                            The user attempted to switch to standard keyboard dialog type.
+                            Set the member value as FALSE, destroy the dialog and save the data configuration into the registry.
+                        */
+                        Globals.bIsEnhancedKeyboard = FALSE;
+                        EndDialog(hDlg, FALSE);
+                        SaveDataToRegistry();
+
+                        /* Change the condition of standard keyboard item menu to checked */
+                        CheckMenuItem(GetMenu(hDlg), IDM_ENHANCED_KB, MF_BYCOMMAND | MF_UNCHECKED);
+                        CheckMenuItem(GetMenu(hDlg), IDM_STANDARD_KB, MF_BYCOMMAND | MF_CHECKED);
+
+                        /* Finally, display the dialog modal box with the standard keyboard dialog */
+                        DialogBoxW(Globals.hInstance,
+                                   MAKEINTRESOURCEW(MAIN_DIALOG_STANDARD_KB),
+                                   GetDesktopWindow(),
+                                   OSK_DlgProc);
+                    }
+
+                    break;
+                }
+
+                case IDM_ABOUT:
+                {
+                    OSK_About();
+                    break;
+                }
+
+                default:
+                    OSK_DlgCommand(wParam, (HWND)lParam);
+                    break;
+            }
             break;
 
         case WM_CLOSE:
@@ -408,12 +522,13 @@ INT_PTR APIENTRY OSK_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  *
  *       WinMain
  */
-int WINAPI _tWinMain(HINSTANCE hInstance,
-                     HINSTANCE prev,
-                     LPTSTR cmdline,
-                     int show)
+int WINAPI wWinMain(HINSTANCE hInstance,
+                    HINSTANCE prev,
+                    LPWSTR cmdline,
+                    int show)
 {
     HANDLE hMutex;
+    INT LayoutResource;
 
     UNREFERENCED_PARAMETER(prev);
     UNREFERENCED_PARAMETER(cmdline);
@@ -422,18 +537,38 @@ int WINAPI _tWinMain(HINSTANCE hInstance,
     ZeroMemory(&Globals, sizeof(Globals));
     Globals.hInstance = hInstance;
 
+    /* Load the settings from the registry hive */
+    LoadDataFromRegistry();
+
+    /* If the member of the struct (bShowWarning) is set then display the dialog box */
+    if (Globals.bShowWarning)
+    {
+        DialogBoxW(Globals.hInstance, MAKEINTRESOURCEW(IDD_WARNINGDIALOG_OSK), Globals.hMainWnd, OSK_WarningProc);
+    }
+
+    /* Before initializing the dialog execution, check if the chosen keyboard type is standard or enhanced */
+    if (Globals.bIsEnhancedKeyboard)
+    {
+        LayoutResource = MAIN_DIALOG_ENHANCED_KB;
+    }
+    else
+    {
+        LayoutResource = MAIN_DIALOG_STANDARD_KB;
+    }
+
     /* Rry to open a mutex for a single instance */
-    hMutex = OpenMutexA(MUTEX_ALL_ACCESS, FALSE, "osk");
+    hMutex = OpenMutexW(MUTEX_ALL_ACCESS, FALSE, L"osk");
 
     if (!hMutex)
     {
         /* Mutex doesn\92t exist. This is the first instance so create the mutex. */
-        hMutex = CreateMutexA(NULL, FALSE, "osk");
+        hMutex = CreateMutexW(NULL, FALSE, L"osk");
 
-        DialogBox(hInstance,
-                  MAKEINTRESOURCE(MAIN_DIALOG),
-                  GetDesktopWindow(),
-                  OSK_DlgProc);
+        /* Create the modal box based on the configuration registry */
+        DialogBoxW(hInstance,
+                   MAKEINTRESOURCEW(LayoutResource),
+                   GetDesktopWindow(),
+                   OSK_DlgProc);
 
         /* Delete the mutex */
         if (hMutex) CloseHandle(hMutex);