|
|
/****************************** Module Header ******************************\
* Module Name: access.c * * Copyright (c) 1997, Microsoft Corporation * * Accessibility notification dialogs * * History: * 02-01-97 Fritz Sands Created \***************************************************************************/
#include <stdio.h>
#include <wtypes.h>
#include "dialogs.h"
#include <winuserp.h>
#include <oleacc.h>
#pragma hdrstop
/*
* Notification Dialog Stuff */ extern HINSTANCE g_hInstance;
#define cchBuf 1024 // plenty of room for title
#define cchTitle 128
typedef struct tagACCESSINFO { UINT Feature; UINT TitleID; HANDLE hDesk; WCHAR wcTitle[cchTitle]; } ACCESSINFO, *PACCESSINFO;
#define NOTIF_KEY __TEXT("Control Panel\\Accessibility")
#define NOTIFY_VALUE __TEXT("Warning Sounds")
#define HOTKEYCODE 100
#define ID_STICKYKEYNAME NOTIF_KEY __TEXT("\\StickyKeys")
#define ID_TOGGLEKEYS NOTIF_KEY __TEXT("\\ToggleKeys")
#define ID_HIGHCONTROST NOTIF_KEY __TEXT("\\HighContrast")
#define ID_MOUSEKEYS NOTIF_KEY __TEXT("\\MouseKeys")
#define ID_SERIALKEYS NOTIF_KEY __TEXT("\\SerialKeys")
/***************************************************************************
* * * ConfirmHandler_InitDialog * * * * Input: hWnd = dialog window handle * * uiTitle = resource ID of dialog box title * * uiTitle+1 through uiTitle+n = resource ID of dialog box text * * Output: Returns TRUE on success, FALSE on failure. * * * ***************************************************************************/
BOOL ConfirmHandler_InitDialog(HWND hWnd, HDESK hDesk, UINT uiTitle, WCHAR *pszTitle) { RECT rc; // Current window size
WCHAR *pszBuf; WCHAR *pszNext; int cchBufLeft; int cchHelpText; int fSuccess = 0; WCHAR szDesktop[MAX_PATH]; DWORD Len1 = MAX_PATH; BOOL b;
szDesktop[0] = 0; b = GetUserObjectInformation(hDesk, UOI_NAME, szDesktop, MAX_PATH, &Len1); SetWindowText(hWnd, pszTitle); // Init title bar
pszBuf = (WCHAR *)LocalAlloc(LMEM_FIXED, cchBuf * sizeof (WCHAR)); if (!pszBuf) goto Exit;
pszNext = pszBuf; cchBufLeft = cchBuf; while (cchHelpText = LoadString(g_hInstance, ++uiTitle, pszNext, cchBufLeft)) { pszNext += cchHelpText; cchBufLeft -= cchHelpText; }
SetDlgItemText(hWnd, ID_HELPTEXT, pszBuf); // Init help text
if (b && (0 == wcscmp(szDesktop,L"Winlogon"))) { EnableWindow(GetDlgItem(hWnd, IDHELP), FALSE);
}
// Make us a topmost window and center ourselves.
GetWindowRect(hWnd, &rc); // Get size of dialog
// Center dialog and make it topmost
SetWindowPos(hWnd, HWND_TOPMOST, (GetSystemMetrics(SM_CXFULLSCREEN)/2) - (rc.right - rc.left)/2, (GetSystemMetrics(SM_CYFULLSCREEN)/2) - (rc.bottom - rc.top)/2, 0,0, SWP_NOSIZE );
// Make sure we're active!
// Lets try setting this to be the foreground window.
// SetForegroundWindow(hWnd);
// SetForgroundWindow will not work because we are not the forground task. So use accSelect
if ( hWnd ) { IAccessible *pAcc = NULL; VARIANT varChild;
varChild.vt = VT_I4; varChild.lVal = 0; if ( AccessibleObjectFromWindow( hWnd, OBJID_CLIENT, &IID_IAccessible, (void**)&pAcc ) == S_OK ) { if ( pAcc ) pAcc->lpVtbl->accSelect( pAcc, SELFLAG_TAKEFOCUS, varChild ); } } fSuccess = 1;
LocalFree((HLOCAL)pszBuf); Exit: return fSuccess; }
/***************************************************************************
* * * * * ConfirmHandler * * * * Input: Std Window messages * * Output: IDOK if success, IDCANCEL if we should abort * * * * * * Put up the main dialog to tell the user what is happening and to get * * permission to continue. * ***************************************************************************/
INT_PTR CALLBACK ConfirmHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { WCHAR buf[100]; WCHAR szRundll[] = L"rundll32.exe"; WCHAR szDesktop[MAX_PATH]; DWORD Len1, Len2; PACCESSINFO pAccessInfo; PROCESS_INFORMATION ProcessInfo; STARTUPINFO si;
GetStartupInfo(&si);
switch(message) { case WM_INITDIALOG: SetWindowLongPtr(hWnd, DWLP_USER, lParam); pAccessInfo = (PACCESSINFO)lParam; return ConfirmHandler_InitDialog(hWnd, pAccessInfo->hDesk, pAccessInfo->TitleID, pAccessInfo->wcTitle);
case WM_COMMAND: pAccessInfo = (PACCESSINFO)GetWindowLongPtr(hWnd, DWLP_USER);
switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: EndDialog(hWnd, LOWORD(wParam));
return TRUE;
case IDHELP: // IDHELP (Settings... really) dismisses dialog with no changes
EndDialog(hWnd, IDCANCEL);
//
// Spawn the correct help
//
lstrcpy(buf,L" Shell32.dll,Control_RunDLL access.cpl,,"); switch (pAccessInfo->Feature) { case ACCESS_STICKYKEYS: case ACCESS_FILTERKEYS: case ACCESS_TOGGLEKEYS: default: lstrcat(buf,L"1"); break;
case ACCESS_MOUSEKEYS: lstrcat(buf,L"4"); break;
case ACCESS_HIGHCONTRAST: lstrcat(buf,L"3"); break; }
CreateProcess( szRundll, buf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &ProcessInfo );
return TRUE; break;
default: return FALSE; } break; default: // fall thru rather than return FALSE to keep compiler happy
break; } return FALSE; }
DWORD MakeAccessDlg(PACCESSINFO pAccessInfo) { DWORD iRet = 0; HDESK hDeskOld;
hDeskOld = GetThreadDesktop(GetCurrentThreadId()); if (hDeskOld == NULL) return 0;
pAccessInfo->hDesk = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED); if (pAccessInfo->hDesk == NULL) return 0;
if (LoadString(g_hInstance, pAccessInfo->TitleID, pAccessInfo->wcTitle, cchTitle)) { SetThreadDesktop(pAccessInfo->hDesk); if (!FindWindowEx(GetDesktopWindow(), NULL, (LPCTSTR)0x8002, pAccessInfo->wcTitle)) { iRet = (DWORD)DialogBoxParam(g_hInstance, MAKEINTRESOURCE(DLG_CONFIRM), NULL, ConfirmHandler, (LPARAM)pAccessInfo); } SetThreadDesktop(hDeskOld); } CloseDesktop(pAccessInfo->hDesk);
return iRet; }
/***************************************************************************
* * * The thread opens the input desktopn, connects to it, and calls the * * notification dialog for the accessibility feature. * * * ***************************************************************************/ DWORD WINAPI StickyKeysNotification(BOOL fNotifReq) { DWORD iRet = IDCANCEL ; ACCESSINFO AccessInfo; STICKYKEYS sticky; DWORD dwS; BOOL b;
AccessInfo.Feature = ACCESS_STICKYKEYS; AccessInfo.TitleID = ID_STICKY_TITLE;
if ( fNotifReq ) { iRet = MakeAccessDlg(&AccessInfo); } else iRet = IDOK;
if (iRet) { sticky.cbSize = sizeof sticky; b = SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof sticky, &sticky, 0); dwS= sticky.dwFlags;
if (iRet & HOTKEYCODE) { sticky.dwFlags &= ~SKF_HOTKEYACTIVE; b = SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof sticky, &sticky, SPIF_UPDATEINIFILE); iRet &= ~HOTKEYCODE; } if (iRet == IDOK) { sticky.dwFlags |= SKF_STICKYKEYSON; }
if (dwS != sticky.dwFlags) { b = SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof sticky, &sticky, 0);
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETSTICKYKEYS, FALSE, SMTO_ABORTIFHUNG, 5000, NULL); }
iRet = 1; }
return iRet; }
/***************************************************************************
* * * The thread opens the input desktopn, connects to it, and calls the * * notification dialog for the accessibility feature. * * * ***************************************************************************/ DWORD WINAPI FilterKeysNotification(BOOL fNotifReq) { DWORD iRet = IDCANCEL ; ACCESSINFO AccessInfo; FILTERKEYS filter; DWORD dwF; BOOL b;
AccessInfo.Feature = ACCESS_FILTERKEYS; AccessInfo.TitleID = ID_FILTER_TITLE;
if ( fNotifReq ) { iRet = MakeAccessDlg(&AccessInfo); } else iRet = IDOK;
if (iRet) { filter.cbSize = sizeof filter; b = SystemParametersInfo(SPI_GETFILTERKEYS, sizeof filter, &filter, 0); dwF = filter.dwFlags;
if (iRet & HOTKEYCODE) { filter.dwFlags &= ~FKF_HOTKEYACTIVE; b = SystemParametersInfo(SPI_SETFILTERKEYS, sizeof filter, &filter, SPIF_UPDATEINIFILE); iRet &= ~HOTKEYCODE; } if (iRet == IDOK) { filter.dwFlags |= FKF_FILTERKEYSON; } if (dwF !=filter.dwFlags) { b = SystemParametersInfo(SPI_SETFILTERKEYS, sizeof filter, &filter, 0); // Broadcast a message. Being extra safe not to turn on filter keys
// during logon. Send message to notify all specially systray: a-anilk
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETFILTERKEYS, FALSE, SMTO_ABORTIFHUNG, 5000, NULL);
} iRet = 1; }
return iRet; }
/***************************************************************************
* * * The thread opens the input desktopn, connects to it, and calls the * * notification dialog for the accessibility feature. * * * ***************************************************************************/ DWORD WINAPI ToggleKeysNotification(BOOL fNotifReq) { DWORD iRet = IDCANCEL; ACCESSINFO AccessInfo; TOGGLEKEYS toggle; DWORD dwT; BOOL b;
toggle.cbSize = sizeof toggle;
AccessInfo.Feature = ACCESS_TOGGLEKEYS; AccessInfo.TitleID = ID_TOGGLE_TITLE;
if ( fNotifReq ) { iRet = MakeAccessDlg(&AccessInfo); } else iRet = IDOK;
if (iRet) { toggle.cbSize = sizeof toggle; b = SystemParametersInfo(SPI_GETTOGGLEKEYS, sizeof toggle, &toggle, 0); dwT = toggle.dwFlags;
if (iRet & HOTKEYCODE) { toggle.dwFlags &= ~TKF_HOTKEYACTIVE; b = SystemParametersInfo(SPI_SETTOGGLEKEYS, sizeof toggle, &toggle, SPIF_UPDATEINIFILE); iRet &= ~HOTKEYCODE; } if (iRet == IDOK) { toggle.dwFlags |= TKF_TOGGLEKEYSON; }
if (toggle.dwFlags != dwT) { b = SystemParametersInfo(SPI_SETTOGGLEKEYS, sizeof toggle, &toggle, 0); // Not required to send message, As it currently has no indicators...
} iRet = 1; } return iRet; }
/***************************************************************************
* * * The thread opens the input desktopn, connects to it, and calls the * * notification dialog for the accessibility feature. * * * ***************************************************************************/ DWORD WINAPI MouseKeysNotification(BOOL fNotifReq) { DWORD iRet = IDCANCEL; ACCESSINFO AccessInfo; MOUSEKEYS mouse; DWORD dwM; BOOL b;
AccessInfo.Feature = ACCESS_MOUSEKEYS; AccessInfo.TitleID = ID_MOUSE_TITLE;
if ( fNotifReq ) { iRet = MakeAccessDlg(&AccessInfo); } else iRet = IDOK;
if (iRet) { mouse.cbSize = sizeof mouse; b = SystemParametersInfo(SPI_GETMOUSEKEYS, sizeof mouse, &mouse, 0); dwM = mouse.dwFlags;
if (iRet & HOTKEYCODE) { mouse.dwFlags &= ~MKF_HOTKEYACTIVE; b = SystemParametersInfo(SPI_SETMOUSEKEYS, sizeof mouse, &mouse, SPIF_UPDATEINIFILE); iRet &= ~HOTKEYCODE; }
if (iRet == IDOK) { mouse.dwFlags |= MKF_MOUSEKEYSON; }
if (mouse.dwFlags != dwM) { b = SystemParametersInfo(SPI_SETMOUSEKEYS, sizeof mouse, &mouse, 0);
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETMOUSEKEYS, FALSE, SMTO_ABORTIFHUNG, 5000, NULL); }
iRet = 1; } return iRet; }
/***************************************************************************
* * * The thread opens the input desktopn, connects to it, and calls the * * notification dialog for the accessibility feature. * * * ***************************************************************************/ DWORD WINAPI HighContNotification(BOOL fNotifReq) { DWORD iRet = IDCANCEL ; ACCESSINFO AccessInfo; HIGHCONTRAST hc; DWORD dwH; BOOL b;
AccessInfo.Feature = ACCESS_HIGHCONTRAST; AccessInfo.TitleID = ID_HC_TITLE;
if ( fNotifReq ) { iRet = MakeAccessDlg(&AccessInfo); } else iRet = IDOK;
if (iRet) { hc.cbSize = sizeof hc; b = SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof hc, &hc, 0); dwH = hc.dwFlags;
if (iRet & HOTKEYCODE) { hc.dwFlags &= ~HCF_HOTKEYACTIVE; b = SystemParametersInfo(SPI_SETHIGHCONTRAST, sizeof hc, &hc, SPIF_UPDATEINIFILE); iRet &= ~HOTKEYCODE; }
if (iRet == IDOK) { hc.dwFlags |= HCF_HIGHCONTRASTON; }
if (hc.dwFlags != dwH) { b = SystemParametersInfo(SPI_SETHIGHCONTRAST, sizeof hc, &hc, 0);
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETHIGHCONTRAST, FALSE, SMTO_ABORTIFHUNG, 5000, NULL); } iRet = 1; }
return iRet; }
|