|
|
/*++
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.
//
// timer ID
#define BLINK 1000
// Note that 1300 is converted to -1, which means "off". The max value
// that we set is actually 1200.
#define CURSORMIN 200
#define CURSORMAX 1300
#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, // lineup
1, // linedown
-CURSORRANGE / 400, // pageup
CURSORRANGE / 400, // pagedown
CURSORRANGE / 100, // top
0, // bottom
0, // thumbpos
0 // thumbtrack
};
//
// 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_CURSOR_GRAPHIC, 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 HWND hwndCursorBlink; static BOOL fBlink = TRUE;
//
// Typedef Declarations.
//
typedef struct tag_KeyboardSpdStr { HWND hDlg; // HWND hKeyboardSpdDlg;
} KEYBOARDSPDSTR, *PKEYBOARDSPDSTR;
//
// Helper functions to handle the caret "off" setting
//
void _SetCaretBlinkTime(UINT uInterval) { if (uInterval != uNewBlinkTime) { uNewBlinkTime = uInterval;
if (CURSORMAX == uInterval) uInterval = (UINT)-1; // blink is "off"
SetCaretBlinkTime(uInterval); } }
void _SetTimer(HWND hDlg, UINT uInterval) { if (uInterval < CURSORMAX) { SetTimer(hDlg, BLINK, uInterval, NULL); } else { // Caret blink is "off".
// Kill the timer and show our pseudo-caret.
KillTimer(hDlg, BLINK); fBlink = TRUE; ShowWindow(hwndCursorBlink, SW_SHOW); } }
////////////////////////////////////////////////////////////////////////////
//
// 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;
// -1 means "off"
uBlinkTime = GetCaretBlinkTime(); if ((UINT)-1 == uBlinkTime || uBlinkTime > CURSORMAX) uBlinkTime = CURSORMAX; uNewBlinkTime = uBlinkTime; }
////////////////////////////////////////////////////////////////////////////
//
// 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), (CURSORMAX - uBlinkTime) / 100, &avsCursor );
hwndCursorScroll = GetDlgItem(hDlg, KCURSOR_SCROLL); hwndCursorBlink = GetDlgItem(hDlg, KCURSOR_BLINK);
_SetTimer(hDlg, uBlinkTime);
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); 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 );
_SetCaretBlinkTime(CURSORMAX - (nCurrent * 100)); _SetTimer(hDlg, uNewBlinkTime); } else { SetDelayAndSpeed(hDlg, -1, -1, 0); bKbNeedsReset = TRUE; }
SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0L); break; } case ( WM_TIMER ) : { if (wParam == BLINK) { fBlink = !fBlink; ShowWindow(hwndCursorBlink, fBlink ? SW_SHOW : SW_HIDE); } 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];
if (CURSORMAX == uNewBlinkTime) lstrcpy(buf, TEXT("-1")); else 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); }
|