463b72d38dad3621e180641844e7351ad1ca56bb
2 * PROJECT: ReactOS On-Screen Keyboard
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/osk/main.c
5 * PURPOSE: On-screen keyboard.
6 * PROGRAMMERS: Denis ROBERT
9 /* INCLUDES *******************************************************************/
14 /* GLOBALS ********************************************************************/
19 int OSK_SetImage(int IdDlgItem
, int IdResource
);
20 int OSK_DlgInitDialog(HWND hDlg
);
21 int OSK_DlgClose(void);
22 int OSK_DlgTimer(void);
23 BOOL
OSK_DlgCommand(WPARAM wCommand
, HWND hWndControl
);
24 BOOL
OSK_ReleaseKey(WORD ScanCode
);
26 INT_PTR APIENTRY
OSK_DlgProc(HWND hDlg
, UINT msg
, WPARAM wParam
, LPARAM lParam
);
27 int WINAPI
_tWinMain(HINSTANCE
, HINSTANCE
, LPTSTR
, int);
29 /* FUNCTIONS ******************************************************************/
31 /***********************************************************************
35 * Set an image on a button
37 int OSK_SetImage(int IdDlgItem
, int IdResource
)
42 hIcon
= (HICON
)LoadImage(Globals
.hInstance
, MAKEINTRESOURCE(IdResource
),
43 IMAGE_ICON
, 16, 16, LR_DEFAULTCOLOR
);
47 hWndItem
= GetDlgItem(Globals
.hMainWnd
, IdDlgItem
);
54 SendMessage(hWndItem
, BM_SETIMAGE
, (WPARAM
)IMAGE_ICON
, (LPARAM
)hIcon
);
56 /* The system automatically deletes these resources when the process that created them terminates (MSDN) */
61 /***********************************************************************
65 * Function handler for the warning dialog box on startup
67 INT_PTR CALLBACK
OSK_WarningProc(HWND hDlg
, UINT Msg
, WPARAM wParam
, LPARAM lParam
)
69 UNREFERENCED_PARAMETER(lParam
);
80 switch (LOWORD(wParam
))
82 case IDC_SHOWWARNINGCHECK
:
84 Globals
.bShowWarning
= !IsDlgButtonChecked(hDlg
, IDC_SHOWWARNINGCHECK
);
91 EndDialog(hDlg
, LOWORD(wParam
));
103 /***********************************************************************
107 * Handling of WM_INITDIALOG
109 int OSK_DlgInitDialog(HWND hDlg
)
111 HICON hIcon
, hIconSm
;
118 Globals
.hMainWnd
= hDlg
;
120 /* Load the settings from the registry hive */
121 LoadDataFromRegistry();
123 /* Set the application's icon */
124 hIcon
= LoadImageW(Globals
.hInstance
, MAKEINTRESOURCEW(IDI_OSK
), IMAGE_ICON
, 0, 0, LR_SHARED
| LR_DEFAULTSIZE
);
125 hIconSm
= CopyImage(hIcon
, IMAGE_ICON
, GetSystemMetrics(SM_CXSMICON
), GetSystemMetrics(SM_CYSMICON
), LR_COPYFROMRESOURCE
);
126 if (hIcon
|| hIconSm
)
128 /* Set the window icons (they are deleted when the process terminates) */
129 SendMessageW(Globals
.hMainWnd
, WM_SETICON
, ICON_BIG
, (LPARAM
)hIcon
);
130 SendMessageW(Globals
.hMainWnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)hIconSm
);
133 /* Get screen info */
134 memset(&Pt
, 0, sizeof(Pt
));
135 monitor
= MonitorFromPoint(Pt
, MONITOR_DEFAULTTOPRIMARY
);
136 info
.cbSize
= sizeof(info
);
137 GetMonitorInfoW(monitor
, &info
);
139 /* Move the dialog on the bottom of main screen */
140 GetWindowRect(hDlg
, &rcWindow
);
142 (info
.rcMonitor
.left
+ info
.rcMonitor
.right
) / 2 - // Center of screen
143 (rcWindow
.right
- rcWindow
.left
) / 2, // - half size of dialog
144 info
.rcMonitor
.bottom
- // Bottom of screen
145 (rcWindow
.bottom
- rcWindow
.top
), // - size of window
146 rcWindow
.right
- rcWindow
.left
, // Width
147 rcWindow
.bottom
- rcWindow
.top
, // Height
150 /* Set icon on visual buttons */
151 OSK_SetImage(SCAN_CODE_15
, IDI_BACK
);
152 OSK_SetImage(SCAN_CODE_16
, IDI_TAB
);
153 OSK_SetImage(SCAN_CODE_30
, IDI_CAPS_LOCK
);
154 OSK_SetImage(SCAN_CODE_43
, IDI_RETURN
);
155 OSK_SetImage(SCAN_CODE_44
, IDI_SHIFT
);
156 OSK_SetImage(SCAN_CODE_57
, IDI_SHIFT
);
157 OSK_SetImage(SCAN_CODE_127
, IDI_REACTOS
);
158 OSK_SetImage(SCAN_CODE_128
, IDI_REACTOS
);
159 OSK_SetImage(SCAN_CODE_129
, IDI_MENU
);
160 OSK_SetImage(SCAN_CODE_80
, IDI_HOME
);
161 OSK_SetImage(SCAN_CODE_85
, IDI_PG_UP
);
162 OSK_SetImage(SCAN_CODE_86
, IDI_PG_DOWN
);
163 OSK_SetImage(SCAN_CODE_79
, IDI_LEFT
);
164 OSK_SetImage(SCAN_CODE_83
, IDI_TOP
);
165 OSK_SetImage(SCAN_CODE_84
, IDI_BOTTOM
);
166 OSK_SetImage(SCAN_CODE_89
, IDI_RIGHT
);
168 /* Create a green brush for leds */
169 Globals
.hBrushGreenLed
= CreateSolidBrush(RGB(0, 255, 0));
171 /* Set a timer for periodics tasks */
172 Globals
.iTimer
= SetTimer(hDlg
, 0, 200, NULL
);
174 /* If the member of the struct (bShowWarning) is set then display the dialog box */
175 if (Globals
.bShowWarning
)
177 DialogBox(Globals
.hInstance
, MAKEINTRESOURCE(IDD_WARNINGDIALOG_OSK
), Globals
.hMainWnd
, OSK_WarningProc
);
183 /***********************************************************************
187 * Handling of WM_CLOSE
189 int OSK_DlgClose(void)
191 KillTimer(Globals
.hMainWnd
, Globals
.iTimer
);
193 /* Release Ctrl, Shift, Alt keys */
194 OSK_ReleaseKey(SCAN_CODE_44
); // Left shift
195 OSK_ReleaseKey(SCAN_CODE_57
); // Right shift
196 OSK_ReleaseKey(SCAN_CODE_58
); // Left ctrl
197 OSK_ReleaseKey(SCAN_CODE_60
); // Left alt
198 OSK_ReleaseKey(SCAN_CODE_62
); // Right alt
199 OSK_ReleaseKey(SCAN_CODE_64
); // Right ctrl
201 /* delete GDI objects */
202 if (Globals
.hBrushGreenLed
) DeleteObject(Globals
.hBrushGreenLed
);
204 /* Save the settings to the registry hive */
205 SaveDataToRegistry();
210 /***********************************************************************
214 * Handling of WM_TIMER
216 int OSK_DlgTimer(void)
218 /* FIXME: To be deleted when ReactOS will support WS_EX_NOACTIVATE */
219 HWND hWndActiveWindow
;
221 hWndActiveWindow
= GetForegroundWindow();
222 if (hWndActiveWindow
!= NULL
&& hWndActiveWindow
!= Globals
.hMainWnd
)
224 Globals
.hActiveWnd
= hWndActiveWindow
;
227 /* Always redraw leds because it can be changed by the real keyboard) */
228 InvalidateRect(GetDlgItem(Globals
.hMainWnd
, IDC_LED_NUM
), NULL
, TRUE
);
229 InvalidateRect(GetDlgItem(Globals
.hMainWnd
, IDC_LED_CAPS
), NULL
, TRUE
);
230 InvalidateRect(GetDlgItem(Globals
.hMainWnd
, IDC_LED_SCROLL
), NULL
, TRUE
);
235 /***********************************************************************
239 * All handling of dialog command
241 BOOL
OSK_DlgCommand(WPARAM wCommand
, HWND hWndControl
)
250 /* FIXME: To be deleted when ReactOS will support WS_EX_NOACTIVATE */
251 if (Globals
.hActiveWnd
)
255 SetForegroundWindow(Globals
.hActiveWnd
);
256 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
))
258 TranslateMessage(&msg
);
259 DispatchMessage(&msg
);
263 /* KeyDown and/or KeyUp ? */
264 WindowStyle
= GetWindowLong(hWndControl
, GWL_STYLE
);
265 if ((WindowStyle
& BS_AUTOCHECKBOX
) == BS_AUTOCHECKBOX
)
267 /* 2-states key like Shift, Alt, Ctrl, ... */
268 if (SendMessage(hWndControl
, BM_GETCHECK
, 0, 0) == BST_CHECKED
)
288 if (ScanCode
& 0x0200)
291 bExtendedKey
= FALSE
;
294 /* Press and release the key */
297 Input
.type
= INPUT_KEYBOARD
;
299 Input
.ki
.wScan
= ScanCode
;
300 Input
.ki
.time
= GetTickCount();
301 Input
.ki
.dwExtraInfo
= GetMessageExtraInfo();
302 Input
.ki
.dwFlags
= KEYEVENTF_SCANCODE
;
303 if (bExtendedKey
) Input
.ki
.dwFlags
|= KEYEVENTF_EXTENDEDKEY
;
304 SendInput(1, &Input
, sizeof(Input
));
309 Input
.type
= INPUT_KEYBOARD
;
311 Input
.ki
.wScan
= ScanCode
;
312 Input
.ki
.time
= GetTickCount();
313 Input
.ki
.dwExtraInfo
= GetMessageExtraInfo();
314 Input
.ki
.dwFlags
= KEYEVENTF_SCANCODE
| KEYEVENTF_KEYUP
;
315 if (bExtendedKey
) Input
.ki
.dwFlags
|= KEYEVENTF_EXTENDEDKEY
;
316 SendInput(1, &Input
, sizeof(Input
));
322 /***********************************************************************
326 * Release the key of ID wCommand
328 BOOL
OSK_ReleaseKey(WORD ScanCode
)
335 /* Is it a 2-states key ? */
336 hWndControl
= GetDlgItem(Globals
.hMainWnd
, ScanCode
);
337 WindowStyle
= GetWindowLong(hWndControl
, GWL_STYLE
);
338 if ((WindowStyle
& BS_AUTOCHECKBOX
) != BS_AUTOCHECKBOX
) return FALSE
;
340 /* Is the key down ? */
341 if (SendMessage(hWndControl
, BM_GETCHECK
, 0, 0) != BST_CHECKED
) return TRUE
;
344 if (ScanCode
& 0x0200)
347 bExtendedKey
= FALSE
;
350 /* Release the key */
351 Input
.type
= INPUT_KEYBOARD
;
353 Input
.ki
.wScan
= ScanCode
;
354 Input
.ki
.time
= GetTickCount();
355 Input
.ki
.dwExtraInfo
= GetMessageExtraInfo();
356 Input
.ki
.dwFlags
= KEYEVENTF_SCANCODE
| KEYEVENTF_KEYUP
;
357 if (bExtendedKey
) Input
.ki
.dwFlags
|= KEYEVENTF_EXTENDEDKEY
;
358 SendInput(1, &Input
, sizeof(Input
));
363 /***********************************************************************
367 INT_PTR APIENTRY
OSK_DlgProc(HWND hDlg
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
372 OSK_DlgInitDialog(hDlg
);
379 case WM_CTLCOLORSTATIC
:
380 if ((HWND
)lParam
== GetDlgItem(hDlg
, IDC_LED_NUM
))
382 if (GetKeyState(VK_NUMLOCK
) & 0x0001)
383 return (INT_PTR
)Globals
.hBrushGreenLed
;
385 return (INT_PTR
)GetStockObject(BLACK_BRUSH
);
387 if ((HWND
)lParam
== GetDlgItem(hDlg
, IDC_LED_CAPS
))
389 if (GetKeyState(VK_CAPITAL
) & 0x0001)
390 return (INT_PTR
)Globals
.hBrushGreenLed
;
392 return (INT_PTR
)GetStockObject(BLACK_BRUSH
);
394 if ((HWND
)lParam
== GetDlgItem(hDlg
, IDC_LED_SCROLL
))
396 if (GetKeyState(VK_SCROLL
) & 0x0001)
397 return (INT_PTR
)Globals
.hBrushGreenLed
;
399 return (INT_PTR
)GetStockObject(BLACK_BRUSH
);
404 if (wParam
== IDCANCEL
)
405 EndDialog(hDlg
, FALSE
);
406 else if (wParam
!= IDC_STATIC
)
407 OSK_DlgCommand(wParam
, (HWND
) lParam
);
418 /***********************************************************************
422 int WINAPI
_tWinMain(HINSTANCE hInstance
,
429 UNREFERENCED_PARAMETER(prev
);
430 UNREFERENCED_PARAMETER(cmdline
);
431 UNREFERENCED_PARAMETER(show
);
433 ZeroMemory(&Globals
, sizeof(Globals
));
434 Globals
.hInstance
= hInstance
;
436 /* Rry to open a mutex for a single instance */
437 hMutex
= OpenMutexA(MUTEX_ALL_ACCESS
, FALSE
, "osk");
441 /* Mutex doesn\92t exist. This is the first instance so create the mutex. */
442 hMutex
= CreateMutexA(NULL
, FALSE
, "osk");
445 MAKEINTRESOURCE(MAIN_DIALOG
),
449 /* Delete the mutex */
450 if (hMutex
) CloseHandle(hMutex
);
454 /* Programme already launched */
456 /* Delete the mutex */