459 lines
12 KiB
C
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);
|
|
}
|