|
|
// **************************************************************************
// Access.c
//
// Accessability Property sheet page creator
//
// **************************************************************************
#include "Access.h"
#ifdef UNICODE // Windows uses UNICODE
#define _UNICODE // but tchar.h uses _UNICODE
#endif
DWORD g_dwOrigFKFlags; BOOL g_bFKOn;
#include <stdlib.h>
#include <stddef.h>
#include <tchar.h>
#define OLDDISABLED 32760
#ifndef FKF_VALID
#define FKF_VALID 0x0000007F
#endif
#ifndef SKF_VALID
#define SKF_VALID 0x000001FF
#endif
#ifndef MKF_VALID
#define MKF_VALID 0x000000FF
#endif
#ifndef ATF_VALID
#define ATF_VALID 0x00000003
#endif
#ifndef SSF_VALID
#define SSF_VALID 0x00000007
#endif
#ifndef TKF_VALID
#define TKF_VALID 0x0000003F
#endif
//////////////////////////////////////////////////////////////////////////
// collection of data that represents the saved accessability state
typedef struct ACCSTATE // as
{ // Keyboard property page
STICKYKEYS sk; FILTERKEYS fk; TOGGLEKEYS tk; BOOL fExtraKeyboardHelp;
// Sound Property page
SOUNDSENTRY ss; BOOL fShowSounds;
// Display Property page
HIGHCONTRAST hc; TCHAR szDefaultScheme[256]; // hc.lpszDefaultScheme
CARET_SETTINGS cs;
// Mouse Property page
MOUSEKEYS mk;
// General Property page
BOOL fShowWarnMsgOnFeatureActivate; BOOL fPlaySndOnFeatureActivate;
ACCESSTIMEOUT ato; SERIALKEYS serk; TCHAR szActivePort[MAX_PATH]; // serk.szActivePort
TCHAR szPort[MAX_PATH]; // serk.szPort
} ACCSTATE, *PACCSTATE;
//////////////////////////////////////////////////////////////////////////
extern BOOL g_SPISetValue = FALSE;
static ACCSTATE s_asOrg; // original settings from app start-up
static ACCSTATE s_asPrev; // previous saved settings
extern BOOL g_fWinNT = -1; // TRUE if we're running on NT and must
// disable some features
extern BOOL g_fSaveSettings = TRUE; extern BOOL g_fShowWarnMsgOnFeatureActivate = TRUE; extern BOOL g_fPlaySndOnFeatureActivate = TRUE; extern BOOL g_fCopyToLogon = FALSE; extern BOOL g_fCopyToDefault = FALSE; // Keyboard property page
// extern STICKYKEYS g_sk = {0};
STICKYKEYS g_sk; FILTERKEYS g_fk; // g_dwLastBounceKeySetting, g_nLastRepeatDelay, g_nLastRepeatRate
// and g_nLastWait are part of FilterKeys
DWORD g_dwLastBounceKeySetting = 0; DWORD g_nLastRepeatDelay = 0; DWORD g_nLastRepeatRate = 0; DWORD g_nLastWait = 0;
TOGGLEKEYS g_tk; BOOL g_fExtraKeyboardHelp = TRUE;
// Sound Property page
SOUNDSENTRY g_ss; BOOL g_fShowSounds;
// Display Property page
HIGHCONTRAST g_hc; CARET_SETTINGS g_cs;
// Mouse Property page
MOUSEKEYS g_mk;
// General Property page
ACCESSTIMEOUT g_ato; SERIALKEYS g_serk; TCHAR g_szActivePort[MAX_PATH]; TCHAR g_szPort[MAX_PATH];
#define CONTROL_PANEL_DESKTOP TEXT("Control Panel\\Desktop")
#define CURSOR_BLINK_RATE TEXT("CursorBlinkRate")
#define DEFAULT_BLINK_RATE 530
//////////////////////////////////////////////////////////////////////////
void CopyHighContrast(LPHIGHCONTRAST phcDest, LPHIGHCONTRAST phcSrc) { LPTSTR lpszDefaultScheme = phcDest->lpszDefaultScheme;
memcpy(phcDest, phcSrc, sizeof(*phcDest)); phcDest->lpszDefaultScheme = lpszDefaultScheme;
if (NULL != phcDest->lpszDefaultScheme) { lstrcpy(phcDest->lpszDefaultScheme, phcSrc->lpszDefaultScheme); } }
//////////////////////////////////////////////////////////////////////////
BOOL IsHighContrastEqual(LPHIGHCONTRAST phcDest, LPHIGHCONTRAST phcSrc) { BOOL fIsEqual = FALSE; LPTSTR lpszDefaultScheme = phcDest->lpszDefaultScheme;
// Temporarily make the pointers match
phcDest->lpszDefaultScheme = phcSrc->lpszDefaultScheme;
// match the bits of the structures and the pointed to data
fIsEqual = (0 == memcmp(phcDest, phcSrc, sizeof(*phcDest)) && 0 == lstrcmp(lpszDefaultScheme, phcSrc->lpszDefaultScheme));
phcDest->lpszDefaultScheme = lpszDefaultScheme;
return(fIsEqual); }
//////////////////////////////////////////////////////////////////////////
void CopySerialKeys(LPSERIALKEYS pskDest, LPSERIALKEYS pskSrc) { LPTSTR lpszActivePort = pskDest->lpszActivePort; LPTSTR lpszPort = pskDest->lpszPort;
memcpy(pskDest, pskSrc, sizeof(*pskDest)); pskDest->lpszActivePort = lpszActivePort;
if (NULL != pskDest->lpszActivePort) { lstrcpy(pskDest->lpszActivePort, pskSrc->lpszActivePort); }
pskDest->lpszPort = lpszPort; if (NULL != pskDest->lpszPort) { lstrcpy(pskDest->lpszPort, pskSrc->lpszPort); } }
//////////////////////////////////////////////////////////////////////////
BOOL IsSerialKeysEqual(LPSERIALKEYS pskDest, LPSERIALKEYS pskSrc) { BOOL fIsEqual = FALSE; LPTSTR lpszActivePort = pskDest->lpszActivePort; LPTSTR lpszPort = pskDest->lpszPort;
// Temporarily make the pointers match
pskDest->lpszActivePort = pskSrc->lpszActivePort; pskDest->lpszPort = pskSrc->lpszPort;
// match the bits of the structures and the pointed to data
fIsEqual = (0 == memcmp(pskDest, pskSrc, sizeof(*pskDest)) && (NULL == lpszActivePort || 0 == lstrcmp(lpszActivePort, pskSrc->lpszActivePort)) && (NULL == lpszPort || 0 == lstrcmp(lpszPort, pskSrc->lpszPort)));
pskDest->lpszActivePort = lpszActivePort; pskDest->lpszPort = lpszPort;
return(fIsEqual); }
//////////////////////////////////////////////////////////////////////////
BOOL IsAccStateEqual(PACCSTATE pasDest, PACCSTATE pasSrc) { BOOL fIsEqual = FALSE; HIGHCONTRAST hc = pasDest->hc; SERIALKEYS serk = pasDest->serk; int nLen;
// Clear out the unused sections of the string buffers
nLen = lstrlen(pasDest->szDefaultScheme); memset(&pasDest->szDefaultScheme[nLen], 0, sizeof(pasDest->szDefaultScheme)-nLen*sizeof(*pasDest->szDefaultScheme));
nLen = lstrlen(pasDest->szActivePort); memset(&pasDest->szActivePort[nLen], 0, sizeof(pasDest->szActivePort)-nLen*sizeof(*pasDest->szActivePort));
nLen = lstrlen(pasDest->szPort); memset(&pasDest->szPort[nLen], 0, sizeof(pasDest->szPort)-nLen*sizeof(*pasDest->szPort));
nLen = lstrlen(pasSrc->szDefaultScheme); memset(&pasSrc->szDefaultScheme[nLen], 0, sizeof(pasSrc->szDefaultScheme)-nLen*sizeof(*pasSrc->szDefaultScheme));
nLen = lstrlen(pasSrc->szActivePort); memset(&pasSrc->szActivePort[nLen], 0, sizeof(pasSrc->szActivePort)-nLen*sizeof(*pasSrc->szActivePort));
nLen = lstrlen(pasSrc->szActivePort); memset(&pasSrc->szPort[nLen], 0, sizeof(pasSrc->szPort)-nLen*sizeof(*pasSrc->szPort));
// Temporarily make the elements with pointers match
pasDest->hc = pasSrc->hc; pasDest->serk = pasSrc->serk;
// match the bits of the structures and the elements with pointers
fIsEqual = (0 == memcmp(pasDest, pasSrc, sizeof(*pasDest)) && IsHighContrastEqual(&hc, &pasSrc->hc) && IsSerialKeysEqual(&serk, &pasSrc->serk));
pasDest->hc = hc; pasDest->serk = serk;
return(fIsEqual); }
//////////////////////////////////////////////////////////////////////////
int WINAPI RegQueryInt (int nDefault, HKEY hkey, LPTSTR lpSubKey, LPTSTR lpValueName) {
DWORD dwType; DWORD dwVal = nDefault; DWORD cbData = sizeof(int); if (ERROR_SUCCESS == RegOpenKeyEx(hkey, lpSubKey, 0, KEY_QUERY_VALUE, &hkey)) { RegQueryValueEx(hkey, lpValueName, NULL, &dwType, (PBYTE) &dwVal, &cbData); RegCloseKey(hkey); } return(dwVal); }
//////////////////////////////////////////////////////////////////////////
BOOL WINAPI RegSetInt (HKEY hkey, LPTSTR lpSubKey, LPTSTR lpValueName, int nVal) { BOOL fOk = FALSE; DWORD dwDisposition; LONG lRet;
if (ERROR_SUCCESS == RegCreateKeyEx(hkey, lpSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hkey, &dwDisposition)) {
lRet = RegSetValueEx(hkey, lpValueName, 0, REG_DWORD, (CONST BYTE *) &nVal, sizeof(nVal)); fOk = (ERROR_SUCCESS == lRet); RegCloseKey(hkey); } return fOk; }
//////////////////////////////////////////////////////////////////////////
void WINAPI RegQueryStr( LPTSTR lpDefault, HKEY hkey, LPTSTR lpSubKey, LPTSTR lpValueName, LPTSTR lpszValue, DWORD cbData) // note this is bytes, not characters.
{ DWORD dwType; DWORD dwOrigCount = cbData; lstrcpy(lpszValue, lpDefault); if (ERROR_SUCCESS == RegOpenKeyEx(hkey, lpSubKey, 0, KEY_QUERY_VALUE, &hkey)) { RegQueryValueEx(hkey, lpValueName, NULL, &dwType, (PBYTE) lpszValue, &cbData); lpszValue[dwOrigCount/sizeof (TCHAR)-1] = TEXT('\0'); RegCloseKey(hkey); } }
/***************************************************************************\
**AccessWriteProfileString * * History: * 12-19-95 a-jimhar Created (was called AccessWriteProfileString) * 02-08-95 a-jimhar revised and moved from accrare.c to access.c \***************************************************************************/ BOOL RegSetStr( HKEY hkey, LPCTSTR lpSection, LPCTSTR lpKeyName, LPCTSTR lpString) { BOOL fRet = FALSE; LONG lErr; DWORD dwDisposition;
lErr = RegCreateKeyEx( hkey, lpSection, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hkey, &dwDisposition);
if (ERROR_SUCCESS == lErr) { if (NULL != lpString) { lErr = RegSetValueEx( hkey, lpKeyName, 0, REG_SZ, (CONST BYTE *)lpString, (lstrlen(lpString) + 1) * sizeof(*lpString)); } else { lErr = RegSetValueEx( hkey, lpKeyName, 0, REG_SZ, (CONST BYTE *)__TEXT(""), 1 * sizeof(*lpString)); }
if (ERROR_SUCCESS == lErr) { fRet = TRUE; } RegCloseKey(hkey); } return(fRet); }
DWORD WINAPI RegQueryStrDW( DWORD dwDefault, HKEY hkey, LPTSTR lpSubKey, LPTSTR lpValueName) { DWORD dwRet = dwDefault;
TCHAR szTemp[40]; TCHAR szDefault[40];
const LPTSTR pwszd = __TEXT("%d");
wsprintf(szDefault, pwszd, dwDefault);
RegQueryStr( szDefault, hkey, lpSubKey, lpValueName, szTemp, sizeof(szTemp));
dwRet = _ttol(szTemp);
return dwRet; }
BOOL RegSetStrDW( HKEY hkey, LPTSTR lpSection, LPCTSTR lpKeyName, DWORD dwValue) { BOOL fRet; TCHAR szTemp[40]; const LPTSTR pwszd = __TEXT("%d");
wsprintf(szTemp, pwszd, dwValue); fRet = RegSetStr(hkey, lpSection, lpKeyName, szTemp);
return fRet; }
//////////////////////////////////////////////////////////////////////////
/*------------------------------------------------------------------
* Function void KillAccStat() * * Purpose Check if accstat is already running. If it is we need * to check to see if it should be. It should only be running * if each feature that is on also has the 'show status on * screen flag checked. If not we want to kill accstat. * * Params: None * * Return: TRUE if we had to kill accstat * FALSE if accstat not running/valid session *------------------------------------------------------------------*/
void KillAccStat (void) { BOOL fCanTurnOff = FALSE; // Can we turn off accstat due to invalid feature?
BOOL fValidFeature = FALSE; // Are there any valid features?
// Accstat may be running. Determine if it should be running
// We need to check the FilterKeys, MouseKeys and StickyKeys
if (g_sk.dwFlags & SKF_STICKYKEYSON) if (!(g_sk.dwFlags & SKF_INDICATOR)) fCanTurnOff = TRUE; // A mismatched flag - we MAY be able to turn off.
else fValidFeature = TRUE; // A valid feature - we CAN't turn off accstat.
if (g_fk.dwFlags & FKF_FILTERKEYSON) if (!(g_fk.dwFlags & FKF_INDICATOR)) fCanTurnOff = TRUE; // A mismatched flag - we MAY be able to turn off.
else fValidFeature = TRUE; // A valid feature - we CAN't turn off accstat.
if (g_mk.dwFlags & MKF_MOUSEKEYSON) if (!(g_mk.dwFlags & MKF_INDICATOR)) fCanTurnOff = TRUE; // A mismatched flag - we MAY be able to turn off.
else fValidFeature = TRUE; // A valid feature - we CAN't turn off accstat.
// Now we have two flags: fCanTurnOff is TRUE if there is a mismatched flag set
// ie, feature on, indicator off. ValidFeature is TRUE if any feature has
// ON and INDICATOR set which implies accstat must remain active.
if (!fValidFeature && fCanTurnOff) { TCHAR szBuf[256]; HWND hwndAccStat; LoadString(g_hinst, IDS_ACCSTAT_WINDOW_TITLE, szBuf, ARRAY_SIZE(szBuf)); if (IsWindow(hwndAccStat = FindWindow(NULL, szBuf))) { // Note sending 1 as the lParam tells accstat to shutup and
// go away NOW.
SendMessage(hwndAccStat, WM_SYSCOMMAND, SC_CLOSE, 1); } } }
//////////////////////////////////////////////////////////////////////////
void WINAPI GetAccessibilitySettings (void) { BOOL fUpdate;
if (g_fWinNT == -1) { OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(osvi); GetVersionEx(&osvi); g_fWinNT = (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT); }
g_fShowWarnMsgOnFeatureActivate = (BOOL) RegQueryInt(TRUE, HKEY_CURRENT_USER, GENERAL_KEY, WARNING_SOUNDS);
s_asPrev.fShowWarnMsgOnFeatureActivate = g_fShowWarnMsgOnFeatureActivate;
// Query the Sound On Activation entry
g_fPlaySndOnFeatureActivate = (BOOL) RegQueryInt(TRUE, HKEY_CURRENT_USER, GENERAL_KEY, SOUND_ON_ACTIVATION);
s_asPrev.fPlaySndOnFeatureActivate = g_fPlaySndOnFeatureActivate;
g_fSaveSettings = TRUE;
// Keyboard property page
g_sk.cbSize = sizeof(g_sk); AccessSystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(g_sk), &g_sk, 0); s_asPrev.sk = g_sk;
g_fk.cbSize = sizeof(g_fk); AccessSystemParametersInfo(SPI_GETFILTERKEYS, sizeof(g_fk), &g_fk, 0); g_fk.dwFlags |= FKF_AVAILABLE;
// FILTERKEYS used to use OLDDISABLED as it's "unused" flag. This doesn't
// work very well on NT (SPI_SETFILTERKEYS calls fail). We now use 0
// for disabled values. Take this opertunity to change any OLDDISABLED
// values to 0 and save if needed.
fUpdate = FALSE;
if (OLDDISABLED == g_fk.iBounceMSec) { g_fk.iBounceMSec = 0; fUpdate = TRUE; } if (OLDDISABLED == g_fk.iDelayMSec) { g_fk.iDelayMSec = 0; fUpdate = TRUE; } if (OLDDISABLED == g_fk.iRepeatMSec) { g_fk.iRepeatMSec = 0; fUpdate = TRUE; } if (OLDDISABLED == g_fk.iWaitMSec) { g_fk.iWaitMSec = 0; fUpdate = TRUE; }
if (fUpdate) { AccessSystemParametersInfo( SPI_SETFILTERKEYS, sizeof(g_fk), &g_fk, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE); }
s_asPrev.fk = g_fk; // fix Filter keys bug
g_dwOrigFKFlags = g_fk.dwFlags; g_bFKOn = g_fk.dwFlags & FKF_FILTERKEYSON;
// g_dwLastBounceKeySetting, g_nLastRepeatDelay, g_nLastRepeatRate
// and g_nLastWait are part of FilterKeys
if (0 != g_fk.iBounceMSec) { // Bounce keys enabeled
g_fk.iDelayMSec = 0; g_fk.iRepeatMSec = 0; g_fk.iWaitMSec = 0;
g_dwLastBounceKeySetting = g_fk.iBounceMSec; g_nLastRepeatDelay = RegQueryInt(0, HKEY_CURRENT_USER, FILTER_KEY, LAST_REPEAT_DELAY); g_nLastRepeatRate = RegQueryInt(0, HKEY_CURRENT_USER, FILTER_KEY, LAST_REPEAT_RATE); g_nLastWait = RegQueryInt(0, HKEY_CURRENT_USER, FILTER_KEY, LAST_WAIT); } else { if (0 == g_fk.iDelayMSec) { g_fk.iRepeatMSec = 0; } g_dwLastBounceKeySetting = RegQueryInt(0, HKEY_CURRENT_USER, FILTER_KEY, LAST_BOUNCE_SETTING); g_nLastRepeatDelay = RegQueryInt(0, HKEY_CURRENT_USER, FILTER_KEY, LAST_REPEAT_DELAY); g_nLastRepeatRate = RegQueryInt(0, HKEY_CURRENT_USER, FILTER_KEY, LAST_REPEAT_RATE); if (0 != g_fk.iWaitMSec) { g_nLastWait = g_fk.iWaitMSec; } else { g_nLastWait = RegQueryInt(0, HKEY_CURRENT_USER, FILTER_KEY, LAST_WAIT); } }
g_tk.cbSize = sizeof(g_tk); AccessSystemParametersInfo(SPI_GETTOGGLEKEYS, sizeof(g_tk), &g_tk, 0); s_asPrev.tk = g_tk;
AccessSystemParametersInfo(SPI_GETKEYBOARDPREF, 0, &g_fExtraKeyboardHelp, 0); s_asPrev.fExtraKeyboardHelp = g_fExtraKeyboardHelp;
// Sound Property page
g_ss.cbSize = sizeof(g_ss); AccessSystemParametersInfo(SPI_GETSOUNDSENTRY, sizeof(g_ss), &g_ss, 0); s_asPrev.ss = g_ss;
SystemParametersInfo(SPI_GETSHOWSOUNDS, 0, &g_fShowSounds, 0);
// BUG, BUG GetSystemMetrics() is not updating value on reboot :a-anilk
// g_fShowSounds = GetSystemMetrics(SM_SHOWSOUNDS);
s_asPrev.fShowSounds = g_fShowSounds;
// Display Property page
g_hc.cbSize = sizeof(g_hc); AccessSystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(g_hc), &g_hc, 0);
// Currently NT will not store these flags. We fake them so we
// can tell if they actually changed.
s_asPrev.hc.lpszDefaultScheme = s_asPrev.szDefaultScheme; CopyHighContrast(&s_asPrev.hc, &g_hc);
SystemParametersInfo(SPI_GETCARETWIDTH, 0, (PVOID)&g_cs.dwCaretWidth, 0); g_cs.dwCaretBlinkRate = RegQueryStrDW( DEFAULT_BLINK_RATE , HKEY_CURRENT_USER , CONTROL_PANEL_DESKTOP , CURSOR_BLINK_RATE); if (g_cs.dwCaretBlinkRate == BLINK_OFF) g_cs.dwCaretBlinkRate = CURSORMAX; s_asPrev.cs.dwCaretBlinkRate = g_cs.dwCaretBlinkRate; s_asPrev.cs.dwCaretWidth = g_cs.dwCaretWidth;
// Mouse Property page
g_mk.cbSize = sizeof(g_mk); AccessSystemParametersInfo(SPI_GETMOUSEKEYS, sizeof(g_mk), &g_mk, 0); s_asPrev.mk = g_mk;
// General Property page
g_ato.cbSize = sizeof(g_ato); AccessSystemParametersInfo(SPI_GETACCESSTIMEOUT, sizeof(g_ato), &g_ato, 0); s_asPrev.ato = g_ato;
g_serk.cbSize = sizeof(g_serk); g_serk.lpszActivePort = g_szActivePort; g_serk.lpszPort = g_szPort; AccessSystemParametersInfo(SPI_GETSERIALKEYS, sizeof(g_serk), &g_serk, 0);
s_asPrev.serk.lpszActivePort = s_asPrev.szActivePort; s_asPrev.serk.lpszPort = s_asPrev.szPort; CopySerialKeys(&s_asPrev.serk, &g_serk);
if (NULL == s_asOrg.hc.lpszDefaultScheme) { // s_asOrg has not yet been initialized
s_asOrg = s_asPrev; s_asOrg.hc.lpszDefaultScheme = s_asOrg.szDefaultScheme; s_asOrg.serk.lpszActivePort = s_asOrg.szActivePort; s_asOrg.serk.lpszPort = s_asOrg.szPort; } }
//////////////////////////////////////////////////////////////////////////
//a-anilk: Change, Admin options, Keyboard flags: 05/06/99
void WINAPI SetAccessibilitySettings (void) { HKEY hkey; DWORD dwDisposition; UINT fWinIni = SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE; BOOL fAnyNotifyChange = FALSE;
g_SPISetValue = TRUE;
SetCursor(LoadCursor(NULL, IDC_WAIT));
if (g_fShowWarnMsgOnFeatureActivate) { g_hc.dwFlags |= HCF_CONFIRMHOTKEY; g_fk.dwFlags |= FKF_CONFIRMHOTKEY; g_sk.dwFlags |= SKF_CONFIRMHOTKEY; g_mk.dwFlags |= MKF_CONFIRMHOTKEY; g_tk.dwFlags |= TKF_CONFIRMHOTKEY; } else { g_hc.dwFlags &= ~HCF_CONFIRMHOTKEY; g_fk.dwFlags &= ~FKF_CONFIRMHOTKEY; g_sk.dwFlags &= ~SKF_CONFIRMHOTKEY; g_mk.dwFlags &= ~MKF_CONFIRMHOTKEY; g_tk.dwFlags &= ~TKF_CONFIRMHOTKEY; }
if (g_fPlaySndOnFeatureActivate) { g_hc.dwFlags |= HCF_HOTKEYSOUND; g_fk.dwFlags |= FKF_HOTKEYSOUND; g_sk.dwFlags |= SKF_HOTKEYSOUND; g_mk.dwFlags |= MKF_HOTKEYSOUND; g_tk.dwFlags |= TKF_HOTKEYSOUND; g_ato.dwFlags |= ATF_ONOFFFEEDBACK; } else { g_hc.dwFlags &= ~HCF_HOTKEYSOUND; g_fk.dwFlags &= ~FKF_HOTKEYSOUND; g_sk.dwFlags &= ~SKF_HOTKEYSOUND; g_mk.dwFlags &= ~MKF_HOTKEYSOUND; g_tk.dwFlags &= ~TKF_HOTKEYSOUND; g_ato.dwFlags &= ~ATF_ONOFFFEEDBACK; }
// Keyboard property page
if (0 != memcmp(&g_sk, &s_asPrev.sk, sizeof(g_sk))) { if (g_fWinNT) { g_sk.dwFlags &= SKF_VALID; } AccessSystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(g_sk), &g_sk, fWinIni); s_asPrev.sk = g_sk; fAnyNotifyChange = TRUE; }
if (g_bFKOn) g_fk.dwFlags |= FKF_FILTERKEYSON; else g_fk.dwFlags &= ~FKF_FILTERKEYSON;
g_dwOrigFKFlags = g_fk.dwFlags;
if (0 != memcmp(&g_fk, &s_asPrev.fk, sizeof(g_fk))) { if (g_fWinNT) { g_fk.dwFlags &= FKF_VALID; }
// g_dwLastBounceKeySetting, g_nLastRepeatDelay, g_nLastRepeatRate
// and g_nLastWait are part of FilterKeys
if (0 != g_fk.iBounceMSec) { // Bounce keys enabeled
g_fk.iDelayMSec = 0; g_fk.iRepeatMSec = 0; g_fk.iWaitMSec = 0;
g_dwLastBounceKeySetting = g_fk.iBounceMSec; } else { g_nLastWait = g_fk.iWaitMSec; if (0 != g_fk.iDelayMSec) { // Slow key enabled
g_nLastRepeatDelay = g_fk.iDelayMSec; g_nLastRepeatRate = g_fk.iRepeatMSec; } else { // neither Bounce or Slow
g_fk.iRepeatMSec = 0; } }
AccessSystemParametersInfo(SPI_SETFILTERKEYS, sizeof(g_fk), &g_fk, fWinIni); s_asPrev.fk = g_fk;
fAnyNotifyChange = TRUE; }
// always save these
RegSetInt(HKEY_CURRENT_USER, FILTER_KEY, LAST_BOUNCE_SETTING, g_dwLastBounceKeySetting); RegSetInt(HKEY_CURRENT_USER, FILTER_KEY, LAST_REPEAT_DELAY, g_nLastRepeatDelay); RegSetInt(HKEY_CURRENT_USER, FILTER_KEY, LAST_REPEAT_RATE, g_nLastRepeatRate); RegSetInt(HKEY_CURRENT_USER, FILTER_KEY, LAST_WAIT, g_nLastWait);
if (0 != memcmp(&g_tk, &s_asPrev.tk, sizeof(g_tk))) { if (g_fWinNT) { g_tk.dwFlags &= TKF_VALID; } AccessSystemParametersInfo(SPI_SETTOGGLEKEYS, sizeof(g_tk), &g_tk, fWinIni); s_asPrev.tk = g_tk; fAnyNotifyChange = TRUE; }
if (g_fExtraKeyboardHelp != s_asPrev.fExtraKeyboardHelp) { // Set this too. Some controls check this flag...0x100B
AccessSystemParametersInfo(SPI_SETKEYBOARDCUES, 0, IntToPtr(g_fExtraKeyboardHelp), fWinIni);
AccessSystemParametersInfo(SPI_SETKEYBOARDPREF, g_fExtraKeyboardHelp, 0, fWinIni); s_asPrev.fExtraKeyboardHelp = g_fExtraKeyboardHelp; fAnyNotifyChange = TRUE; }
// Display Property page
if (!IsHighContrastEqual(&g_hc, &s_asPrev.hc)) { AccessSystemParametersInfo(SPI_SETHIGHCONTRAST, sizeof(g_hc), &g_hc, fWinIni); if (ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, HC_KEY, 0, __TEXT(""), REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hkey, &dwDisposition)) { RegSetValueEx(hkey, HIGHCONTRAST_SCHEME, 0, REG_SZ, (PBYTE) g_hc.lpszDefaultScheme, (lstrlen(g_hc.lpszDefaultScheme) + 1) * sizeof(*g_hc.lpszDefaultScheme)); RegSetValueEx(hkey, VOLATILE_SCHEME, 0, REG_SZ, (PBYTE) g_hc.lpszDefaultScheme, (lstrlen(g_hc.lpszDefaultScheme) + 1) * sizeof(*g_hc.lpszDefaultScheme)); RegCloseKey(hkey); hkey = NULL; } CopyHighContrast(&s_asPrev.hc, &g_hc); fAnyNotifyChange = TRUE; }
if (g_cs.dwCaretBlinkRate != s_asPrev.cs.dwCaretBlinkRate) { DWORD dwCaretBlinkRate = (g_cs.dwCaretBlinkRate < CURSORMAX)?g_cs.dwCaretBlinkRate:BLINK_OFF;
// Set the blink rate for this session
SetCaretBlinkTime(dwCaretBlinkRate);
// and persist it to the registry
RegSetStrDW(HKEY_CURRENT_USER, CONTROL_PANEL_DESKTOP, CURSOR_BLINK_RATE, dwCaretBlinkRate); }
if (g_cs.dwCaretWidth != s_asPrev.cs.dwCaretWidth) AccessSystemParametersInfo(SPI_SETCARETWIDTH, 0, IntToPtr(g_cs.dwCaretWidth), fWinIni);
s_asPrev.cs = g_cs;
// Mouse Property page
if (0 != memcmp(&g_mk, &s_asPrev.mk, sizeof(g_mk))) { if (g_fWinNT) { g_mk.dwFlags &= MKF_VALID; } AccessSystemParametersInfo(SPI_SETMOUSEKEYS, sizeof(g_mk), &g_mk, fWinIni); s_asPrev.mk = g_mk; fAnyNotifyChange = TRUE; }
// General Property page
if (g_fPlaySndOnFeatureActivate) { g_ato.dwFlags |= ATF_ONOFFFEEDBACK; } else { g_ato.dwFlags &= ~ATF_ONOFFFEEDBACK; }
if (0 != memcmp(&g_ato, &s_asPrev.ato, sizeof(g_ato))) { if (g_fWinNT) { g_ato.dwFlags &= ATF_VALID; } AccessSystemParametersInfo(SPI_SETACCESSTIMEOUT, sizeof(g_ato), &g_ato, fWinIni); s_asPrev.ato = g_ato; fAnyNotifyChange = TRUE; }
if (!IsSerialKeysEqual(&g_serk, &s_asPrev.serk)) { AccessSystemParametersInfo(SPI_SETSERIALKEYS, sizeof(g_serk), &g_serk, fWinIni); CopySerialKeys(&s_asPrev.serk, &g_serk); fAnyNotifyChange = TRUE; }
if (g_fSaveSettings) { if (RegCreateKeyEx(HKEY_CURRENT_USER, GENERAL_KEY, 0, __TEXT(""), REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hkey, &dwDisposition) == ERROR_SUCCESS) {
// Save the Warning Sounds entry
if (g_fShowWarnMsgOnFeatureActivate != s_asPrev.fShowWarnMsgOnFeatureActivate) { RegSetValueEx(hkey, WARNING_SOUNDS, 0, REG_DWORD, (PBYTE) &g_fShowWarnMsgOnFeatureActivate, sizeof(g_fShowWarnMsgOnFeatureActivate)); s_asPrev.fShowWarnMsgOnFeatureActivate = g_fShowWarnMsgOnFeatureActivate; }
// Save the Sound On Activation entry
if (g_fPlaySndOnFeatureActivate != s_asPrev.fPlaySndOnFeatureActivate) { RegSetValueEx(hkey, SOUND_ON_ACTIVATION, 0, REG_DWORD, (PBYTE) &g_fPlaySndOnFeatureActivate, sizeof(g_fPlaySndOnFeatureActivate)); s_asPrev.fPlaySndOnFeatureActivate = g_fPlaySndOnFeatureActivate; } RegCloseKey(hkey); hkey = NULL; } }
// Sound Property page
if (0 != memcmp(&g_ss, &s_asPrev.ss, sizeof(g_ss))) { if (g_fWinNT) { g_ss.dwFlags &= SSF_VALID; } AccessSystemParametersInfo(SPI_SETSOUNDSENTRY, sizeof(g_ss), &g_ss, fWinIni); s_asPrev.ss = g_ss; fAnyNotifyChange = TRUE; }
// We do the sound property page last because the SPI_SETSHOWSOUNDS call is used
// to send out notifications. We make this call if either g_fShowSounds changed
// or we need to send out notifications
// Changed Nov.18 '98 to send out WM_SETTINGSCHANGE Seperately.
if (g_fShowSounds != s_asPrev.fShowSounds /*||
(fAnyNotifyChange && g_fSaveSettings)*/) { // if (g_fSaveSettings) fWinIni |= SPIF_SENDWININICHANGE;
AccessSystemParametersInfo(SPI_SETSHOWSOUNDS, g_fShowSounds, NULL, fWinIni); s_asPrev.fShowSounds = g_fShowSounds; }
g_SPISetValue = FALSE;
// Do Admin options
SaveDefaultSettings(g_fCopyToLogon, g_fCopyToDefault);
SetCursor(LoadCursor(NULL, IDC_ARROW)); }
//////////////////////////////////////////////////////////////////////////
INT_PTR WINAPI KeyboardDlg (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR WINAPI SoundDlg (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR WINAPI GeneralDlg (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR WINAPI DisplayDlg (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); INT_PTR WINAPI MouseDlg (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
#define MAX_PAGES 10
// ************************************************************************
// OpenAccessPropertySheet
// Opens property sheet
// ************************************************************************
BOOL OpenAccessPropertySheet (HWND hwnd, int nID) { HPROPSHEETPAGE rPages[MAX_PAGES]; PROPSHEETPAGE psp; PROPSHEETHEADER psh; INT_PTR nPsRet;
KillAccStat(); GetAccessibilitySettings();
// Simple errorchecking - only allow control to move to tabs 0-4.
// Any tab request greater than 4 is invalid - so default to tab 0
if ((nID < 0) || (nID > 4)) nID = 0;
// Initialize the property sheets
psh.dwSize = sizeof(psh); // SteveDon 5-26-98
// no longer use PSH_PROPTITLE because we want it to read "Accessibility Options"
// rather than "Accessibility Properties" or "Properties for Accessibility"
psh.dwFlags = 0; // psh.dwFlags = PSH_PROPTITLE; // | PSH_PROPSHEETPAGE | PSP_USEICONID;
psh.hwndParent = hwnd; psh.hInstance = g_hinst; psh.pszCaption = MAKEINTRESOURCE(IDS_PROPERTY_TITLE); //ACCESSIBILITY);
psh.pszIcon = MAKEINTRESOURCE(IDI_ACCESS); psh.nPages = 0; psh.nStartPage = 0; psh.phpage = rPages;
// Add First Sheet, keyboard
psp.dwSize = sizeof(psp); psp.dwFlags = PSP_DEFAULT; psp.hInstance = g_hinst; psp.pszTemplate = MAKEINTRESOURCE(IDD_KEYBOARD); psp.pfnDlgProc = KeyboardDlg; psp.lParam = 0;
psh.phpage[psh.nPages] = CreatePropertySheetPage(&psp); if (psh.phpage[psh.nPages]) psh.nPages++;
// Add second sheet, Sound
psp.dwSize = sizeof(psp); psp.dwFlags = PSP_DEFAULT; psp.hInstance = g_hinst; psp.pszTemplate = MAKEINTRESOURCE(IDD_SOUND); psp.pfnDlgProc = SoundDlg; psp.lParam = 0;
psh.phpage[psh.nPages] = CreatePropertySheetPage(&psp); if (psh.phpage[psh.nPages]) psh.nPages++;
// Add third sheet, Display
psp.dwSize = sizeof(psp); psp.dwFlags = PSP_DEFAULT; psp.hInstance = g_hinst; psp.pszTemplate = MAKEINTRESOURCE(IDD_DISPLAY); psp.pfnDlgProc = DisplayDlg; psp.lParam = 0;
psh.phpage[psh.nPages] = CreatePropertySheetPage(&psp); if (psh.phpage[psh.nPages]) psh.nPages++;
// Add fourth sheet, Mouse
psp.dwSize = sizeof(psp); psp.dwFlags = PSP_DEFAULT; psp.hInstance = g_hinst; psp.pszTemplate = MAKEINTRESOURCE(IDD_MOUSE); psp.pfnDlgProc = MouseDlg; psp.lParam = 0;
psh.phpage[psh.nPages] = CreatePropertySheetPage(&psp); if (psh.phpage[psh.nPages]) psh.nPages++;
// Add fifth sheet, General
psp.dwSize = sizeof(psp); psp.dwFlags = PSP_DEFAULT; psp.hInstance = g_hinst; psp.pszTemplate = MAKEINTRESOURCE(IDD_GENERAL); psp.pfnDlgProc = GeneralDlg; psp.lParam = 0;
psh.phpage[psh.nPages] = CreatePropertySheetPage(&psp); if (psh.phpage[psh.nPages]) psh.nPages++;
// Simple errorchecking - only allow control to move to tabs 0 to psh.nPages
// Any tab request greater than psh.nPages is invalid
if (0 <= nID && nID < (int)psh.nPages) { psh.nStartPage = nID; }
nPsRet = PropertySheet(&psh);
if ( nPsRet <= 0 ) return FALSE; else return TRUE; }
///////////////////////////////// End of File /////////////////////////////////
|