[OSK] Restore the previous window coordination

Implement the coordination dialog data saver. This allows OSK to launch using the previous placement values. Such behaviour can be seen with the XP's part of On-Screen Keyboard.
This commit is contained in:
Bișoc George 2019-03-02 18:10:26 +01:00 committed by Hermès BÉLUSCA - MAÏTO
parent b9148b8c62
commit 65239bcf4b
3 changed files with 134 additions and 24 deletions

View file

@ -1,9 +1,9 @@
/* /*
* PROJECT: ReactOS On-Screen Keyboard * PROJECT: ReactOS On-Screen Keyboard
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/osk/main.c
* PURPOSE: On-screen keyboard. * PURPOSE: On-screen keyboard.
* PROGRAMMERS: Denis ROBERT * COPYRIGHT: Denis ROBERT
* Copyright 2019 Bișoc George (fraizeraust99 at gmail dot com)
*/ */
/* INCLUDES *******************************************************************/ /* INCLUDES *******************************************************************/
@ -138,7 +138,7 @@ int OSK_DlgInitDialog(HWND hDlg)
HMONITOR monitor; HMONITOR monitor;
MONITORINFO info; MONITORINFO info;
POINT Pt; POINT Pt;
RECT rcWindow; RECT rcWindow, rcDlgIntersect;
/* Save handle */ /* Save handle */
Globals.hMainWnd = hDlg; Globals.hMainWnd = hDlg;
@ -178,17 +178,42 @@ int OSK_DlgInitDialog(HWND hDlg)
monitor = MonitorFromPoint(Pt, MONITOR_DEFAULTTOPRIMARY); monitor = MonitorFromPoint(Pt, MONITOR_DEFAULTTOPRIMARY);
info.cbSize = sizeof(info); info.cbSize = sizeof(info);
GetMonitorInfoW(monitor, &info); GetMonitorInfoW(monitor, &info);
/* Move the dialog on the bottom of main screen */
GetWindowRect(hDlg, &rcWindow); GetWindowRect(hDlg, &rcWindow);
MoveWindow(hDlg,
(info.rcMonitor.left + info.rcMonitor.right) / 2 - // Center of screen /*
(rcWindow.right - rcWindow.left) / 2, // - half size of dialog If the coordination values are default then re-initialize using the specific formulas
info.rcMonitor.bottom - // Bottom of screen to move the dialog at the bottom of the screen.
(rcWindow.bottom - rcWindow.top), // - size of window */
rcWindow.right - rcWindow.left, // Width if (Globals.PosX == CW_USEDEFAULT && Globals.PosY == CW_USEDEFAULT)
rcWindow.bottom - rcWindow.top, // Height {
TRUE); Globals.PosX = (info.rcMonitor.left + info.rcMonitor.right - (rcWindow.right - rcWindow.left)) / 2;
Globals.PosY = info.rcMonitor.bottom - (rcWindow.bottom - rcWindow.top);
}
/*
Calculate the intersection of two rectangle sources (dialog and work desktop area).
If such sources do not intersect, then the dialog is deemed as "off screen".
*/
if (IntersectRect(&rcDlgIntersect, &rcWindow, &info.rcWork) == 0)
{
Globals.PosX = (info.rcMonitor.left + info.rcMonitor.right - (rcWindow.right - rcWindow.left)) / 2;
Globals.PosY = info.rcMonitor.bottom - (rcWindow.bottom - rcWindow.top);
}
else
{
/*
There's still some intersection but we're not for sure if it is sufficient (the dialog could also be partially hidden).
Therefore, check the remaining intersection if it's enough.
*/
if (rcWindow.top < info.rcWork.top || rcWindow.left < info.rcWork.left || rcWindow.right > info.rcWork.right || rcWindow.bottom > info.rcWork.bottom)
{
Globals.PosX = (info.rcMonitor.left + info.rcMonitor.right - (rcWindow.right - rcWindow.left)) / 2;
Globals.PosY = info.rcMonitor.bottom - (rcWindow.bottom - rcWindow.top);
}
}
/* Move the dialog according to the placement coordination */
SetWindowPos(hDlg, HWND_TOP, Globals.PosX, Globals.PosY, 0, 0, SWP_NOSIZE);
/* Set icon on visual buttons */ /* Set icon on visual buttons */
OSK_SetImage(SCAN_CODE_15, IDI_BACK); OSK_SetImage(SCAN_CODE_15, IDI_BACK);
@ -593,7 +618,7 @@ int WINAPI wWinMain(HINSTANCE hInstance,
if (!hMutex) if (!hMutex)
{ {
/* Mutex doesnt exist. This is the first instance so create the mutex. */ /* Mutex doesn't exist. This is the first instance so create the mutex. */
hMutex = CreateMutexW(NULL, FALSE, L"osk"); hMutex = CreateMutexW(NULL, FALSE, L"osk");
/* Create the modal box based on the configuration registry */ /* Create the modal box based on the configuration registry */

View file

@ -1,9 +1,9 @@
/* /*
* PROJECT: ReactOS On-Screen Keyboard * PROJECT: ReactOS On-Screen Keyboard
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/osk/main.h
* PURPOSE: On screen keyboard. * PURPOSE: On screen keyboard.
* PROGRAMMERS: Denis ROBERT * COPYRIGHT: Denis ROBERT
* Copyright 2019 Bișoc George (fraizeraust99 at gmail dot com)
*/ */
#ifndef _OSKMAIN_H #ifndef _OSKMAIN_H
@ -26,6 +26,8 @@ typedef struct
BOOL bShowWarning; BOOL bShowWarning;
BOOL bIsEnhancedKeyboard; BOOL bIsEnhancedKeyboard;
BOOL bSoundClick; BOOL bSoundClick;
INT PosX;
INT PosY;
} OSK_GLOBALS; } OSK_GLOBALS;
/* DEFINES ********************************************************************/ /* DEFINES ********************************************************************/

View file

@ -1,8 +1,8 @@
/* /*
* PROJECT: ReactOS On-Screen Keyboard * PROJECT: ReactOS On-Screen Keyboard
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Settings file for warning dialog on startup * PURPOSE: Configuration settings of the application
* COPYRIGHT: Copyright 2018 Bișoc George (fraizeraust99 at gmail dot com) * COPYRIGHT: Copyright 2018-2019 Bișoc George (fraizeraust99 at gmail dot com)
*/ */
/* INCLUDES *******************************************************************/ /* INCLUDES *******************************************************************/
@ -16,7 +16,7 @@ BOOL LoadDataFromRegistry()
{ {
HKEY hKey; HKEY hKey;
LONG lResult; LONG lResult;
DWORD dwShowWarningData, dwLayout, dwSoundOnClick; DWORD dwShowWarningData, dwLayout, dwSoundOnClick, dwPositionLeft, dwPositionTop;
DWORD cbData = sizeof(DWORD); DWORD cbData = sizeof(DWORD);
/* Set the structure members to TRUE (and the bSoundClick member to FALSE) */ /* Set the structure members to TRUE (and the bSoundClick member to FALSE) */
@ -24,9 +24,13 @@ BOOL LoadDataFromRegistry()
Globals.bIsEnhancedKeyboard = TRUE; Globals.bIsEnhancedKeyboard = TRUE;
Globals.bSoundClick = FALSE; Globals.bSoundClick = FALSE;
/* Set the coordinate values to default */
Globals.PosX = CW_USEDEFAULT;
Globals.PosY = CW_USEDEFAULT;
/* Open the key, so that we can query it */ /* Open the key, so that we can query it */
lResult = RegOpenKeyExW(HKEY_CURRENT_USER, lResult = RegOpenKeyExW(HKEY_CURRENT_USER,
L"Software\\Microsoft\\osk", L"Software\\Microsoft\\Osk",
0, 0,
KEY_READ, KEY_READ,
&hKey); &hKey);
@ -75,7 +79,7 @@ BOOL LoadDataFromRegistry()
/* Query the key */ /* Query the key */
lResult = RegQueryValueExW(hKey, lResult = RegQueryValueExW(hKey,
L"OnSoundClick", L"ClickSound",
0, 0,
0, 0,
(BYTE *)&dwSoundOnClick, (BYTE *)&dwSoundOnClick,
@ -90,6 +94,41 @@ BOOL LoadDataFromRegistry()
/* Load the sound on click value event */ /* Load the sound on click value event */
Globals.bSoundClick = (dwSoundOnClick != 0); Globals.bSoundClick = (dwSoundOnClick != 0);
/* Query the key */
lResult = RegQueryValueExW(hKey,
L"WindowLeft",
0,
0,
(BYTE *)&dwPositionLeft,
&cbData);
if (lResult != ERROR_SUCCESS)
{
/* Bail out and return FALSE if we fail */
RegCloseKey(hKey);
return FALSE;
}
/* Load the X value data of the dialog's coordinate */
Globals.PosX = dwPositionLeft;
lResult = RegQueryValueExW(hKey,
L"WindowTop",
0,
0,
(BYTE *)&dwPositionTop,
&cbData);
if (lResult != ERROR_SUCCESS)
{
/* Bail out and return FALSE if we fail */
RegCloseKey(hKey);
return FALSE;
}
/* Load the Y value data of the dialog's coordinate */
Globals.PosY = dwPositionTop;
/* If we're here then we succeed, close the key and return TRUE */ /* If we're here then we succeed, close the key and return TRUE */
RegCloseKey(hKey); RegCloseKey(hKey);
@ -100,11 +139,16 @@ BOOL SaveDataToRegistry()
{ {
HKEY hKey; HKEY hKey;
LONG lResult; LONG lResult;
DWORD dwShowWarningData, dwLayout, dwSoundOnClick; DWORD dwShowWarningData, dwLayout, dwSoundOnClick, dwPositionLeft, dwPositionTop;
WINDOWPLACEMENT wp;
/* Set the structure length and retrieve the dialog's placement */
wp.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(Globals.hMainWnd, &wp);
/* If no key has been made, create one */ /* If no key has been made, create one */
lResult = RegCreateKeyExW(HKEY_CURRENT_USER, lResult = RegCreateKeyExW(HKEY_CURRENT_USER,
L"Software\\Microsoft\\osk", L"Software\\Microsoft\\Osk",
0, 0,
NULL, NULL,
0, 0,
@ -122,6 +166,7 @@ BOOL SaveDataToRegistry()
/* The data value of the subkey will be appended to the warning dialog switch */ /* The data value of the subkey will be appended to the warning dialog switch */
dwShowWarningData = Globals.bShowWarning; dwShowWarningData = Globals.bShowWarning;
/* Welcome warning box value key */
lResult = RegSetValueExW(hKey, lResult = RegSetValueExW(hKey,
L"ShowWarning", L"ShowWarning",
0, 0,
@ -139,6 +184,7 @@ BOOL SaveDataToRegistry()
/* The value will be appended to the layout dialog */ /* The value will be appended to the layout dialog */
dwLayout = Globals.bIsEnhancedKeyboard; dwLayout = Globals.bIsEnhancedKeyboard;
/* Keyboard dialog switcher */
lResult = RegSetValueExW(hKey, lResult = RegSetValueExW(hKey,
L"IsEnhancedKeyboard", L"IsEnhancedKeyboard",
0, 0,
@ -156,8 +202,9 @@ BOOL SaveDataToRegistry()
/* The value will be appended to the sound on click event */ /* The value will be appended to the sound on click event */
dwSoundOnClick = Globals.bSoundClick; dwSoundOnClick = Globals.bSoundClick;
/* "Sound on Click" switcher value key */
lResult = RegSetValueExW(hKey, lResult = RegSetValueExW(hKey,
L"OnSoundClick", L"ClickSound",
0, 0,
REG_DWORD, REG_DWORD,
(BYTE *)&dwSoundOnClick, (BYTE *)&dwSoundOnClick,
@ -170,6 +217,42 @@ BOOL SaveDataToRegistry()
return FALSE; return FALSE;
} }
/* The value will be appended to the X coordination dialog's placement */
dwPositionLeft = wp.rcNormalPosition.left;
/* Position X coordination of dialog's placement value key */
lResult = RegSetValueExW(hKey,
L"WindowLeft",
0,
REG_DWORD,
(BYTE *)&dwPositionLeft,
sizeof(dwPositionLeft));
if (lResult != ERROR_SUCCESS)
{
/* Bail out and return FALSE if we fail */
RegCloseKey(hKey);
return FALSE;
}
/* The value will be appended to the Y coordination dialog's placement */
dwPositionTop = wp.rcNormalPosition.top;
/* Position Y coordination of dialog's placement value key */
lResult = RegSetValueExW(hKey,
L"WindowTop",
0,
REG_DWORD,
(BYTE *)&dwPositionTop,
sizeof(dwPositionTop));
if (lResult != ERROR_SUCCESS)
{
/* Bail out and return FALSE if we fail */
RegCloseKey(hKey);
return FALSE;
}
/* If we're here then we succeed, close the key and return TRUE */ /* If we're here then we succeed, close the key and return TRUE */
RegCloseKey(hKey); RegCloseKey(hKey);
return TRUE; return TRUE;