diff --git a/dll/cpl/access/access.c b/dll/cpl/access/access.c index 82ebb52ac04..324aaade0c0 100644 --- a/dll/cpl/access/access.c +++ b/dll/cpl/access/access.c @@ -189,11 +189,11 @@ SystemApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam) PGLOBAL_DATA pGlobalData; PROPSHEETPAGE psp[5]; PROPSHEETHEADER psh; - INT nPage = 0; + UINT nPage = 0; // This is unsigned so we don't have to deal with negative numbers INT ret; if (uMsg == CPL_STARTWPARMSW && lParam != 0) - nPage = _wtoi((PWSTR)lParam); + nPage = (*(PWSTR)lParam) - '1'; // Convert from 1-based to 0-based. pGlobalData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLOBAL_DATA)); if (pGlobalData == NULL) diff --git a/dll/cpl/access/mouse.c b/dll/cpl/access/mouse.c index a81d947d4ea..14e01a047e6 100644 --- a/dll/cpl/access/mouse.c +++ b/dll/cpl/access/mouse.c @@ -162,6 +162,11 @@ MousePageProc(HWND hwndDlg, CheckDlgButton(hwndDlg, IDC_MOUSE_BOX, pGlobalData->mouseKeys.dwFlags & MKF_MOUSEKEYSON ? BST_CHECKED : BST_UNCHECKED); + +#if 1 // FIXME: Feature not implemented, disable the UI + EnableWindow(GetDlgItem(hwndDlg, IDC_MOUSE_BOX), pGlobalData->mouseKeys.dwFlags & MKF_MOUSEKEYSON); + EnableWindow(GetDlgItem(hwndDlg, IDC_MOUSE_BUTTON), pGlobalData->mouseKeys.dwFlags & MKF_MOUSEKEYSON); +#endif return TRUE; diff --git a/dll/shellext/stobject/csystray.cpp b/dll/shellext/stobject/csystray.cpp index bab008c0d01..4077d635100 100644 --- a/dll/shellext/stobject/csystray.cpp +++ b/dll/shellext/stobject/csystray.cpp @@ -12,6 +12,7 @@ #include #include #include +#include SysTrayIconHandlers_t g_IconHandlers [] = { { VOLUME_SERVICE_FLAG, Volume_Init, Volume_Shutdown, Volume_Update, Volume_Message }, @@ -20,10 +21,13 @@ SysTrayIconHandlers_t g_IconHandlers [] = { }; const int g_NumIcons = _countof(g_IconHandlers); +SysTrayIconHandlers_t g_StandaloneHandlers[] = { + { MOUSE_SERVICE_FLAG, MouseKeys_Init, MouseKeys_Shutdown, MouseKeys_Update, MouseKeys_Message }, +}; + CSysTray::CSysTray() : dwServicesEnabled(0) { wm_SHELLHOOK = RegisterWindowMessageW(L"SHELLHOOK"); - wm_DESTROYWINDOW = RegisterWindowMessageW(L"CSysTray_DESTROY"); } CSysTray::~CSysTray() @@ -69,7 +73,7 @@ VOID CSysTray::EnableService(DWORD dwServiceFlag, BOOL bEnable) this->dwServicesEnabled &= ~dwServiceFlag; if (RegCreateKeyExW(HKEY_CURRENT_USER, - L"Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\SysTray", + REGSTR_PATH_SYSTRAY, 0, NULL, REG_OPTION_NON_VOLATILE, @@ -78,15 +82,18 @@ VOID CSysTray::EnableService(DWORD dwServiceFlag, BOOL bEnable) &hKey, NULL) == ERROR_SUCCESS) { + DWORD dwConfig = this->dwServicesEnabled & ~STANDALONESERVICEMASK; RegSetValueExW(hKey, L"Services", 0, REG_DWORD, - (LPBYTE)&this->dwServicesEnabled, - sizeof(DWORD)); + (LPBYTE)&dwConfig, + sizeof(dwConfig)); RegCloseKey(hKey); } + + ConfigurePollTimer(); } BOOL CSysTray::IsServiceEnabled(DWORD dwServiceFlag) @@ -94,6 +101,18 @@ BOOL CSysTray::IsServiceEnabled(DWORD dwServiceFlag) return (this->dwServicesEnabled & dwServiceFlag); } +void CSysTray::ConfigurePollTimer() +{ + // FIXME: VOLUME_SERVICE_FLAG should use mixerOpen(CALLBACK_WINDOW) + // FIXME: POWER_SERVICE_FLAG should use WM_DEVICECHANGE, WM_POWERBROADCAST + + DWORD fNeedsTimer = VOLUME_SERVICE_FLAG | POWER_SERVICE_FLAG; + if (this->dwServicesEnabled & fNeedsTimer) + SetTimer(POLL_TIMER_ID, 2000, NULL); + else + KillTimer(POLL_TIMER_ID); +} + HRESULT CSysTray::InitNetShell() { HRESULT hr = CoCreateInstance(CLSID_ConnectionTray, 0, 1u, IID_PPV_ARG(IOleCommandTarget, &pctNetShell)); @@ -119,7 +138,7 @@ HRESULT CSysTray::ShutdownNetShell() HRESULT CSysTray::InitIcons() { TRACE("Initializing Notification icons...\n"); - for (int i = 0; i < g_NumIcons; i++) + for (UINT i = 0; i < g_NumIcons; i++) { if (this->dwServicesEnabled & g_IconHandlers[i].dwServiceFlag) { @@ -128,8 +147,10 @@ HRESULT CSysTray::InitIcons() return hr; } } - - MouseKeys_Init(this); + for (UINT i = 0; i < _countof(g_StandaloneHandlers); ++i) + { + g_StandaloneHandlers[i].pfnInit(this); + } return InitNetShell(); } @@ -137,7 +158,7 @@ HRESULT CSysTray::InitIcons() HRESULT CSysTray::ShutdownIcons() { TRACE("Shutting down Notification icons...\n"); - for (int i = 0; i < g_NumIcons; i++) + for (UINT i = 0; i < g_NumIcons; i++) { if (this->dwServicesEnabled & g_IconHandlers[i].dwServiceFlag) { @@ -146,8 +167,10 @@ HRESULT CSysTray::ShutdownIcons() FAILED_UNEXPECTEDLY(hr); } } - - MouseKeys_Shutdown(this); + for (UINT i = 0; i < _countof(g_StandaloneHandlers); ++i) + { + g_StandaloneHandlers[i].pfnShutdown(this); + } return ShutdownNetShell(); } @@ -170,12 +193,19 @@ HRESULT CSysTray::UpdateIcons() HRESULT CSysTray::ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult) { - for (int i = 0; i < g_NumIcons; i++) + for (UINT i = 0; i < g_NumIcons; i++) { HRESULT hr = g_IconHandlers[i].pfnMessage(this, uMsg, wParam, lParam, lResult); if (FAILED(hr)) return hr; - + if (hr == S_OK) + return hr; + } + for (UINT i = 0; i < _countof(g_StandaloneHandlers); ++i) + { + HRESULT hr = g_StandaloneHandlers[i].pfnMessage(this, uMsg, wParam, lParam, lResult); + if (FAILED(hr)) + return hr; if (hr == S_OK) return hr; } @@ -285,7 +315,7 @@ HRESULT CSysTray::DestroySysTrayWindow() if (!DestroyWindow()) { // Window is from another thread, ask it politely to destroy itself: - SendMessage(wm_DESTROYWINDOW); + SendMessage(WM_CLOSE); } return S_OK; } @@ -319,14 +349,13 @@ BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM if (hWnd != m_hWnd) return FALSE; - if (wm_DESTROYWINDOW && uMsg == wm_DESTROYWINDOW) + if (uMsg == wm_SHELLHOOK && wm_SHELLHOOK) { - return DestroyWindow(); - } - - if (wm_SHELLHOOK && uMsg == wm_SHELLHOOK) - { - if (wParam == HSHELL_ACCESSIBILITYSTATE && lParam == ACCESS_MOUSEKEYS) + if (wParam == HSHELL_ACCESSIBILITYSTATE && lParam == ACCESS_STICKYKEYS) + { + StickyKeys_Update(this); + } + else if (wParam == HSHELL_ACCESSIBILITYSTATE && lParam == ACCESS_MOUSEKEYS) { MouseKeys_Update(this); } @@ -340,29 +369,32 @@ BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM case WM_NCDESTROY: return FALSE; + case WM_CLOSE: + return DestroyWindow(); + case WM_CREATE: GetServicesEnabled(); InitIcons(); - SetTimer(1, 2000, NULL); RegisterShellHookWindow(hWnd); + ConfigurePollTimer(); return TRUE; case WM_TIMER: - if (wParam == 1) + if (wParam == POLL_TIMER_ID) UpdateIcons(); else ProcessIconMessage(uMsg, wParam, lParam, lResult); return TRUE; case WM_SETTINGCHANGE: + if (wParam == SPI_SETSTICKYKEYS) + StickyKeys_Update(this); if (wParam == SPI_SETMOUSEKEYS) - { MouseKeys_Update(this); - } break; case WM_DESTROY: - KillTimer(1); + KillTimer(POLL_TIMER_ID); DeregisterShellHookWindow(hWnd); ShutdownIcons(); PostQuitMessage(0); @@ -377,3 +409,18 @@ BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM return (hr == S_OK); } + +void CSysTray::RunDll(PCSTR Dll, PCSTR Parameters) +{ + WCHAR buf[400], rundll[MAX_PATH]; + GetSystemDirectory(rundll, _countof(rundll)); + PathAppendW(rundll, L"rundll32.exe"); + + wsprintfW(buf, L"%hs %hs%hs", "shell32.dll,Control_RunDLL", Dll, Parameters); + ShellExecuteW(NULL, NULL, rundll, buf, NULL, SW_SHOW); +} + +void CSysTray::RunAccessCpl(PCSTR Parameters) +{ + RunDll("access.cpl", Parameters); +} diff --git a/dll/shellext/stobject/csystray.h b/dll/shellext/stobject/csystray.h index 059e7047f0b..8b6ed307c7d 100644 --- a/dll/shellext/stobject/csystray.h +++ b/dll/shellext/stobject/csystray.h @@ -55,6 +55,10 @@ public: VOID EnableService(DWORD dwServiceFlag, BOOL bEnable); BOOL IsServiceEnabled(DWORD dwServiceFlag); + void ConfigurePollTimer(); + + static void RunDll(PCSTR Dll, PCSTR Parameters); + static void RunAccessCpl(PCSTR Parameters); protected: BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD dwMsgMapID = 0); diff --git a/dll/shellext/stobject/hotplug.cpp b/dll/shellext/stobject/hotplug.cpp index c62d3d88047..b33f35b3adb 100644 --- a/dll/shellext/stobject/hotplug.cpp +++ b/dll/shellext/stobject/hotplug.cpp @@ -154,12 +154,7 @@ HRESULT STDMETHODCALLTYPE Hotplug_Shutdown(_In_ CSysTray * pSysTray) static void _RunHotplug(CSysTray * pSysTray) { - ShellExecuteW(pSysTray->GetHWnd(), - L"open", - L"rundll32.exe", - L"shell32.dll,Control_RunDLL hotplug.dll", - NULL, - SW_SHOWNORMAL); + pSysTray->RunDll("hotplug.dll", ""); } static void _ShowContextMenu(CSysTray * pSysTray) diff --git a/dll/shellext/stobject/mouse.cpp b/dll/shellext/stobject/mouse.cpp index 103b1235503..ff6551464a2 100644 --- a/dll/shellext/stobject/mouse.cpp +++ b/dll/shellext/stobject/mouse.cpp @@ -123,3 +123,20 @@ MouseKeys_Update(_In_ CSysTray *pSysTray) return pSysTray->NotifyIcon(uId, ID_ICON_MOUSE, g_MkStateIcon, L"MouseKeys"); } + +HRESULT STDMETHODCALLTYPE MouseKeys_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult) +{ + switch (uMsg) + { + case ID_ICON_MOUSE: + switch (lParam) + { + case WM_LBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: + pSysTray->RunAccessCpl(",,4"); + return S_OK; + } + break; + } + return S_FALSE; +} diff --git a/dll/shellext/stobject/power.cpp b/dll/shellext/stobject/power.cpp index 4ccae037bdd..981b7463b47 100644 --- a/dll/shellext/stobject/power.cpp +++ b/dll/shellext/stobject/power.cpp @@ -171,7 +171,7 @@ HRESULT STDMETHODCALLTYPE Power_Shutdown(_In_ CSysTray * pSysTray) static void _RunPower() { - ShellExecuteW(NULL, NULL, L"powercfg.cpl", NULL, NULL, SW_SHOWNORMAL); + CSysTray::RunDll("powercfg.cpl", ""); } static void _ShowContextMenu(CSysTray * pSysTray) diff --git a/dll/shellext/stobject/precomp.h b/dll/shellext/stobject/precomp.h index 3d891af31b6..750d817ef14 100644 --- a/dll/shellext/stobject/precomp.h +++ b/dll/shellext/stobject/precomp.h @@ -38,6 +38,10 @@ extern HINSTANCE g_hInstance; #define POWER_SERVICE_FLAG 0x00000001 #define HOTPLUG_SERVICE_FLAG 0x00000002 #define VOLUME_SERVICE_FLAG 0x00000004 +#define SKEYS_SERVICE_FLAG 0x20000000 +#define FKEYS_SERVICE_FLAG 0x40000000 +#define MOUSE_SERVICE_FLAG 0x80000000 +#define STANDALONESERVICEMASK 0xF0000000 #include "csystray.h" @@ -78,8 +82,13 @@ extern HRESULT STDMETHODCALLTYPE Power_Message(_In_ CSysTray * pSysTray, UINT uM extern HRESULT STDMETHODCALLTYPE MouseKeys_Init(_In_ CSysTray * pSysTray); extern HRESULT STDMETHODCALLTYPE MouseKeys_Shutdown(_In_ CSysTray * pSysTray); extern HRESULT STDMETHODCALLTYPE MouseKeys_Update(_In_ CSysTray * pSysTray); +extern HRESULT STDMETHODCALLTYPE MouseKeys_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult); +#define StickyKeys_Update(thisptr) (void)0 // TODO +#define FilterKeys_Update(thisptr) (void)0 // TODO + +#define POLL_TIMER_ID 1 // FIXME: Use callbacks instead of polling with this timer #define POWER_TIMER_ID 2 #define VOLUME_TIMER_ID 3 #define HOTPLUG_TIMER_ID 4 diff --git a/dll/shellext/stobject/volume.cpp b/dll/shellext/stobject/volume.cpp index 048197eaab1..986c6652ee3 100644 --- a/dll/shellext/stobject/volume.cpp +++ b/dll/shellext/stobject/volume.cpp @@ -220,7 +220,7 @@ static void _RunVolume(BOOL bTray) static void _RunMMCpl() { - ShellExecuteW(NULL, NULL, L"mmsys.cpl", NULL, NULL, SW_NORMAL); + CSysTray::RunDll("mmsys.cpl", ""); } static void _ShowContextMenu(CSysTray * pSysTray) diff --git a/win32ss/user/ntuser/sysparams.c b/win32ss/user/ntuser/sysparams.c index 59cc76f13f9..66e26974a9c 100644 --- a/win32ss/user/ntuser/sysparams.c +++ b/win32ss/user/ntuser/sysparams.c @@ -101,6 +101,11 @@ static const WCHAR* KEY_KDBPREF = L"Control Panel\\Accessibility\\Keyboard Prefe static const WCHAR* KEY_SCRREAD = L"Control Panel\\Accessibility\\Blind Access"; static const WCHAR* VAL_ON = L"On"; +static const WCHAR* KEY_MOUSEKEYS = L"Control Panel\\Accessibility\\MouseKeys"; +static const WCHAR* VAL_MOUSEKEYS_FLAGS = L"Flags"; +static const WCHAR* VAL_MOUSEKEYS_MAX = L"MaximumSpeed"; +static const WCHAR* VAL_MOUSEKEYS_TIMETOMAX = L"TimeToMaximumSpeed"; + /** Loading the settings ******************************************************/ static @@ -336,6 +341,10 @@ SpiUpdatePerUserSystemParameters(VOID) gspv.filterkeys.cbSize = sizeof(FILTERKEYS); gspv.togglekeys.cbSize = sizeof(TOGGLEKEYS); gspv.mousekeys.cbSize = sizeof(MOUSEKEYS); + gspv.mousekeys.dwFlags = SpiLoadInt(KEY_MOUSEKEYS, VAL_MOUSEKEYS_FLAGS, 62); + gspv.mousekeys.iMaxSpeed = SpiLoadInt(KEY_MOUSEKEYS, VAL_MOUSEKEYS_MAX, 80); + gspv.mousekeys.iTimeToMaxSpeed = SpiLoadInt(KEY_MOUSEKEYS, VAL_MOUSEKEYS_TIMETOMAX, 3000); + gspv.mousekeys.iCtrlSpeed = 8; // FIXME gspv.stickykeys.cbSize = sizeof(STICKYKEYS); gspv.serialkeys.cbSize = sizeof(SERIALKEYS); gspv.soundsentry.cbSize = sizeof(SOUNDSENTRYW); @@ -1197,7 +1206,9 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl) if (fl & SPIF_UPDATEINIFILE) { - // FIXME: What to do? + SpiStoreSzInt(KEY_MOUSEKEYS, VAL_MOUSEKEYS_FLAGS, gspv.mousekeys.dwFlags); + SpiStoreSzInt(KEY_MOUSEKEYS, VAL_MOUSEKEYS_MAX, gspv.mousekeys.iMaxSpeed); + SpiStoreSzInt(KEY_MOUSEKEYS, VAL_MOUSEKEYS_TIMETOMAX, gspv.mousekeys.iTimeToMaxSpeed); } return (UINT_PTR)KEY_DESKTOP; }