windows-nt/Source/XPSP1/NT/shell/osshell/cpls/main/keybdspd.c
2020-09-26 16:20:57 +08:00

459 lines
12 KiB
C

/*++
Copyright (c) 1994-1998, Microsoft Corporation All rights reserved.
Module Name:
keybdspd.c
Abstract:
This module contains the main routines for the Keyboard applet's
Speed property page.
Revision History:
--*/
//
// Include Files.
//
#include "main.h"
#include "rc.h"
#include "util.h"
#include <regstr.h>
#include <help.h>
//
// Constant Declarations.
//
#define KSPEED_MIN 0
#define KSPEED_MAX 31
#define KSPEED_RANGE (KSPEED_MAX - KSPEED_MIN + 1)
//
// For keyboard delay control.
//
#define KDELAY_MIN 0
#define KDELAY_MAX 3
#define KDELAY_RANGE (KDELAY_MAX - KDELAY_MIN + 1)
//
// For control of the cursor blink rate.
//
#define BLINK 1000
#define CURSORMIN 200
#define CURSORMAX 1200
#define CURSORSUM (CURSORMIN + CURSORMAX)
#define CURSORRANGE (CURSORMAX - CURSORMIN)
static ARROWVSCROLL avsDelay = { -1,
1,
-KDELAY_RANGE / 4,
KDELAY_RANGE / 4,
KDELAY_MAX,
KDELAY_MIN
};
static ARROWVSCROLL avsSpeed = { -1,
1,
-KSPEED_RANGE / 4,
KSPEED_RANGE / 4,
KSPEED_MAX,
KSPEED_MIN
};
static ARROWVSCROLL avsCursor = { -1,
1,
-CURSORRANGE / 400,
CURSORRANGE / 400,
CURSORMAX / 100,
CURSORMIN / 100,
0,
0
};
//
// Context Help Ids.
//
static DWORD aKbdHelpIds[] =
{
KDELAY_GROUP, IDH_COMM_GROUPBOX,
KBLINK_GROUP, IDH_COMM_GROUPBOX,
KDELAY_SCROLL, IDH_DLGKEY_REPDEL,
KSPEED_SCROLL, IDH_DLGKEY_REPSPEED,
KREPEAT_EDIT, IDH_DLGKEY_REPTEST,
KBLINK_EDIT, IDH_DLGKEY_CURSOR_GRAPHIC,
KCURSOR_BLINK, IDH_DLGKEY_CURSBLNK,
KCURSOR_SCROLL, IDH_DLGKEY_CURSBLNK,
0, 0
};
//
// Global Variables.
//
//
// FEATURE - these should be moved into the KeyboardSpdStr structure
//
static UINT uOriginalDelay, uOriginalSpeed;
static UINT uBlinkTime;
static UINT uNewBlinkTime;
static BOOL bKbNeedsReset = FALSE;
static HWND hwndCursorScroll;
static RECT rCursor;
//
// Typedef Declarations.
//
typedef struct tag_KeyboardSpdStr
{
HWND hDlg; // HWND hKeyboardSpdDlg;
} KEYBOARDSPDSTR, *PKEYBOARDSPDSTR;
////////////////////////////////////////////////////////////////////////////
//
// KeyboardSpeedSupported
//
////////////////////////////////////////////////////////////////////////////
BOOL KeyboardSpeedSupported()
{
#ifdef WINNT
//
// FEATURE For Windows NT we assume that all keyboards can
// handle the SetSpeed - we might be able to do a
// better check in the future if KEYBOARD.DLL is available.
//
return (TRUE);
#else
HANDLE hKeyboardModule = LoadLibrary16(TEXT("KEYBOARD"));
BOOL bCanDorkWithTheSpeed = FALSE;
if (hKeyboardModule)
{
if (GetProcAddress16(hKeyboardModule, TEXT("SetSpeed")))
{
bCanDorkWithTheSpeed = TRUE;
}
FreeLibrary16(hKeyboardModule);
}
return (bCanDorkWithTheSpeed);
#endif
}
////////////////////////////////////////////////////////////////////////////
//
// SetDelayAndSpeed
//
////////////////////////////////////////////////////////////////////////////
void SetDelayAndSpeed(
HWND hDlg,
int nDelay,
int nSpeed,
UINT uFlags)
{
if (nDelay < 0)
{
nDelay = (int)SendDlgItemMessage( hDlg,
KDELAY_SCROLL,
TBM_GETPOS,
0,
0L );
}
if (nSpeed < 0)
{
nSpeed = (int)SendDlgItemMessage( hDlg,
KSPEED_SCROLL,
TBM_GETPOS,
0,
0L );
}
//
// Only send the WININICHANGE once.
//
SystemParametersInfo( SPI_SETKEYBOARDSPEED,
nSpeed,
0,
uFlags & ~SPIF_SENDWININICHANGE );
SystemParametersInfo( SPI_SETKEYBOARDDELAY,
KDELAY_MAX - nDelay + KDELAY_MIN,
0L,
uFlags );
}
////////////////////////////////////////////////////////////////////////////
//
// DestroyKeyboardSpdDlg
//
////////////////////////////////////////////////////////////////////////////
void DestroyKeyboardSpdDlg(
PKEYBOARDSPDSTR pKstr)
{
HWND hDlg;
if (pKstr)
{
hDlg = pKstr->hDlg;
LocalFree((HGLOBAL)pKstr);
SetWindowLongPtr(hDlg, DWLP_USER, 0);
}
}
////////////////////////////////////////////////////////////////////////////
//
// GetSpeedGlobals
//
// Get Repeat Speed, Delay, and Blink Time.
//
////////////////////////////////////////////////////////////////////////////
VOID GetSpeedGlobals()
{
SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &uOriginalSpeed, FALSE);
SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &uOriginalDelay, FALSE);
uOriginalDelay = KDELAY_MAX - uOriginalDelay + KDELAY_MIN;
uBlinkTime = uNewBlinkTime = GetCaretBlinkTime();
}
////////////////////////////////////////////////////////////////////////////
//
// InitKeyboardSpdDlg
//
////////////////////////////////////////////////////////////////////////////
BOOL InitKeyboardSpdDlg(
HWND hDlg)
{
HourGlass(TRUE);
if (!KeyboardSpeedSupported())
{
MyMessageBox( hDlg,
IDS_KEYBD_NOSETSPEED,
IDS_KEYBD_TITLE,
MB_OK | MB_ICONINFORMATION );
HourGlass(FALSE);
return (FALSE);
}
//
// Get Repeat Speed, Delay, and Blink Time.
//
GetSpeedGlobals();
TrackInit(GetDlgItem(hDlg, KSPEED_SCROLL), uOriginalSpeed, &avsSpeed);
TrackInit(GetDlgItem(hDlg, KDELAY_SCROLL), uOriginalDelay, &avsDelay);
TrackInit(GetDlgItem(hDlg, KCURSOR_SCROLL), (CURSORSUM - uBlinkTime) / 100, &avsCursor );
hwndCursorScroll = GetDlgItem(hDlg, KCURSOR_SCROLL);
GetWindowRect(GetDlgItem(hDlg, KCURSOR_BLINK), &rCursor);
ScreenToClient(hDlg, (LPPOINT)&rCursor.left);
ScreenToClient(hDlg, (LPPOINT)&rCursor.right);
SetTimer(hDlg, BLINK, uBlinkTime, NULL);
HourGlass(FALSE);
return (TRUE);
}
////////////////////////////////////////////////////////////////////////////
//
// KeyboardSpdDlg
//
////////////////////////////////////////////////////////////////////////////
static const TCHAR c_szUserDesktopKey[] = REGSTR_PATH_DESKTOP;
static const TCHAR c_szCursorBlink[] = TEXT("CursorBlinkRate");
INT_PTR CALLBACK KeyboardSpdDlg(
HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
PKEYBOARDSPDSTR pKstr = (PKEYBOARDSPDSTR)GetWindowLongPtr(hDlg, DWLP_USER);
static BOOL fBlink = FALSE;
switch (message)
{
case ( WM_INITDIALOG ) :
{
bKbNeedsReset = FALSE;
return (InitKeyboardSpdDlg(hDlg));
break;
}
case ( WM_DESTROY ) :
{
DestroyKeyboardSpdDlg(pKstr);
break;
}
case ( WM_HSCROLL ) :
{
if ((HWND)lParam == hwndCursorScroll)
{
int nCurrent = (int)SendMessage( (HWND)lParam,
TBM_GETPOS,
0,
0L );
uNewBlinkTime = CURSORSUM - (nCurrent * 100);
SetCaretBlinkTime(uNewBlinkTime);
KillTimer(hDlg, BLINK);
SetTimer(hDlg, BLINK, CURSORSUM - (nCurrent * 100), NULL);
}
else
{
SetDelayAndSpeed(hDlg, -1, -1, 0);
bKbNeedsReset = TRUE;
}
SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0L);
break;
}
case ( WM_TIMER ) :
{
if (wParam == BLINK)
{
HDC hDC = GetDC(hDlg);
if (fBlink)
{
HBRUSH hBrush = CreateSolidBrush((COLORREF)0);
FillRect(hDC, &rCursor, hBrush);
DeleteObject(hBrush);
}
else
InvalidateRect(hDlg, &rCursor, TRUE);
fBlink = !fBlink;
ReleaseDC(hDlg,hDC);
}
break;
}
case ( WM_WININICHANGE ) :
case ( WM_SYSCOLORCHANGE ) :
case ( WM_DISPLAYCHANGE ) :
{
SHPropagateMessage(hDlg, message, wParam, lParam, TRUE);
break;
}
case ( WM_HELP ) : // F1
{
WinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle,
NULL,
HELP_WM_HELP,
(DWORD_PTR)(LPTSTR)aKbdHelpIds );
break;
}
case ( WM_CONTEXTMENU ) : // right mouse click
{
WinHelp( (HWND)wParam,
NULL,
HELP_CONTEXTMENU,
(DWORD_PTR)(LPTSTR)aKbdHelpIds );
break;
}
case ( WM_NOTIFY ) :
{
switch (((NMHDR *)lParam)->code)
{
case ( PSN_APPLY ) :
{
HKEY hk;
HourGlass(TRUE);
if (RegCreateKey( HKEY_CURRENT_USER,
c_szUserDesktopKey,
&hk ) == ERROR_SUCCESS)
{
TCHAR buf[16];
wsprintf(buf, TEXT("%d"), uNewBlinkTime);
RegSetValueEx( hk,
c_szCursorBlink,
0,
REG_SZ,
(LPBYTE)buf,
(DWORD)(lstrlen(buf) + 1) * sizeof(TCHAR) );
RegCloseKey(hk);
}
SetDelayAndSpeed( hDlg,
-1,
-1,
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE );
GetSpeedGlobals();
HourGlass(FALSE);
break;
}
case ( PSN_RESET ) :
{
SetCaretBlinkTime(uBlinkTime);
if (bKbNeedsReset)
{
//
// Restore the original keyboard speed.
//
SetDelayAndSpeed( hDlg,
uOriginalDelay,
uOriginalSpeed,
0 );
}
break;
}
}
break;
}
default :
{
return FALSE;
}
}
return (TRUE);
}