diff --git a/reactos/dll/shellext/stobject/CMakeLists.txt b/reactos/dll/shellext/stobject/CMakeLists.txt index dc1d02ed714ca..2fa34e61446e9 100644 --- a/reactos/dll/shellext/stobject/CMakeLists.txt +++ b/reactos/dll/shellext/stobject/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(stobject SHARED csystray.cpp stobject.cpp stobject.rc + hotplug.cpp power.cpp volume.cpp ${CMAKE_CURRENT_BINARY_DIR}/stobject.def) diff --git a/reactos/dll/shellext/stobject/csystray.cpp b/reactos/dll/shellext/stobject/csystray.cpp index 6200254d0fd84..8551fbcf23349 100644 --- a/reactos/dll/shellext/stobject/csystray.cpp +++ b/reactos/dll/shellext/stobject/csystray.cpp @@ -12,6 +12,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(stobject); SysTrayIconHandlers_t g_IconHandlers [] = { { Volume_Init, Volume_Shutdown, Volume_Update, Volume_Message }, + { Hotplug_Init, Hotplug_Shutdown, Hotplug_Update, Hotplug_Message }, { Power_Init, Power_Shutdown, Power_Update, Power_Message } }; const int g_NumIcons = _countof(g_IconHandlers); @@ -211,13 +212,37 @@ BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM case WM_NCCREATE: case WM_NCDESTROY: return FALSE; + case WM_CREATE: InitIcons(); SetTimer(1, 2000, NULL); return TRUE; + case WM_TIMER: - UpdateIcons(); - return TRUE; + switch (wParam) + { + case 1: + UpdateIcons(); + return TRUE; + + case POWER_TIMER_ID: + Power_OnTimer(hWnd); + break; + + case VOLUME_TIMER_ID: + Volume_OnTimer(hWnd); + break; + + case HOTPLUG_TIMER_ID: + Hotplug_OnTimer(hWnd); + break; + } + break; + + case WM_DEVICECHANGE: + ERR("WM_DEVICECHANGE\n"); + break; + case WM_DESTROY: KillTimer(1); ShutdownIcons(); diff --git a/reactos/dll/shellext/stobject/hotplug.cpp b/reactos/dll/shellext/stobject/hotplug.cpp new file mode 100644 index 0000000000000..fbc22ea078082 --- /dev/null +++ b/reactos/dll/shellext/stobject/hotplug.cpp @@ -0,0 +1,184 @@ +/* + * PROJECT: ReactOS system libraries + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/shellext/stobject/hotplug.cpp + * PURPOSE: Hotplug notification icon handler + * PROGRAMMERS: Eric Kohl + * David Quintana + */ + +#include "precomp.h" + +WINE_DEFAULT_DEBUG_CHANNEL(stobject); + +static HICON g_hIconHotplug = NULL; +static BOOL g_IsRunning = FALSE; + + +HRESULT STDMETHODCALLTYPE Hotplug_Init(_In_ CSysTray * pSysTray) +{ + WCHAR strTooltip[128]; + + TRACE("Hotplug_Init\n"); + + g_hIconHotplug = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_EXTRACT)); + + LoadStringW(g_hInstance, IDS_HOTPLUG_REMOVE_1, strTooltip, _countof(strTooltip)); + + g_IsRunning = TRUE; + + return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_HOTPLUG, g_hIconHotplug, strTooltip); +} + +HRESULT STDMETHODCALLTYPE Hotplug_Update(_In_ CSysTray * pSysTray) +{ + TRACE("Hotplug_Update\n"); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE Hotplug_Shutdown(_In_ CSysTray * pSysTray) +{ + TRACE("Hotplug_Shutdown\n"); + + g_IsRunning = FALSE; + + return pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_HOTPLUG, NULL, NULL); +} + +static void RunHotplug() +{ + ShellExecuteW(NULL, NULL, L"rundll32.exe", L"shell32.dll,Control_RunDLL hotplug.dll", NULL, SW_SHOWNORMAL); +} + +static void ShowContextMenu(CSysTray *pSysTray) +{ + WCHAR szBuffer[128]; + DWORD id, msgPos; + HMENU hPopup; + + LoadStringW(g_hInstance, IDS_HOTPLUG_REMOVE_2, szBuffer, _countof(szBuffer)); + + hPopup = CreatePopupMenu(); + AppendMenuW(hPopup, MF_STRING, 1, szBuffer); + + msgPos = GetMessagePos(); + + SetForegroundWindow(pSysTray->GetHWnd()); + id = TrackPopupMenuEx(hPopup, + TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN, + GET_X_LPARAM(msgPos), + GET_Y_LPARAM(msgPos), + pSysTray->GetHWnd(), + NULL); + + DestroyMenu(hPopup); + + if (id == 1) + RunHotplug(); +} + +static +VOID +ShowHotplugPopupMenu( + HWND hWnd) +{ +#if 0 + DWORD id, msgPos; + + HMENU hPopup = CreatePopupMenu(); + + // FIXME + AppendMenuW(hPopup, MF_STRING, IDS_VOL_OPEN, strOpen); + + msgPos = GetMessagePos(); + + SetForegroundWindow(hWnd); + id = TrackPopupMenuEx(hPopup, + TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN, + GET_X_LPARAM(msgPos), + GET_Y_LPARAM(msgPos), + hWnd, + NULL); + + DestroyMenu(hPopup); + + if (id != 0) + { + // FIXME + } +#endif +} + +HRESULT STDMETHODCALLTYPE Hotplug_Message(_In_ CSysTray *pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult) +{ + TRACE("Hotplug_Message uMsg=%d, wParam=%x, lParam=%x\n", uMsg, wParam, lParam); + + switch (uMsg) + { + case WM_USER + 220: + TRACE("Hotplug_Message: WM_USER+220\n"); + if (wParam == 2) + { + if (lParam == FALSE) + return Hotplug_Init(pSysTray); + else + return Hotplug_Shutdown(pSysTray); + } + return S_FALSE; + + case WM_USER + 221: + TRACE("Hotplug_Message: WM_USER+221\n"); + if (wParam == 2) + { + lResult = (LRESULT)g_IsRunning; + return S_OK; + } + return S_FALSE; + + case ID_ICON_HOTPLUG: + Hotplug_Update(pSysTray); + + switch (lParam) + { + case WM_LBUTTONDOWN: + SetTimer(pSysTray->GetHWnd(), HOTPLUG_TIMER_ID, 500, NULL); + break; + + case WM_LBUTTONUP: + break; + + case WM_LBUTTONDBLCLK: + KillTimer(pSysTray->GetHWnd(), HOTPLUG_TIMER_ID); + RunHotplug(); + break; + + case WM_RBUTTONDOWN: + break; + + case WM_RBUTTONUP: + ShowContextMenu(pSysTray); + break; + + case WM_RBUTTONDBLCLK: + break; + + case WM_MOUSEMOVE: + break; + } + return S_OK; + + default: + TRACE("Hotplug_Message received for unknown ID %d, ignoring.\n"); + return S_FALSE; + } + + return S_FALSE; +} + +VOID +Hotplug_OnTimer(HWND hWnd) +{ + TRACE("Hotplug_OnTimer\n!"); + KillTimer(hWnd, HOTPLUG_TIMER_ID); + ShowHotplugPopupMenu(hWnd); +} diff --git a/reactos/dll/shellext/stobject/power.cpp b/reactos/dll/shellext/stobject/power.cpp index c36bedd07f987..24b5feb4162cd 100644 --- a/reactos/dll/shellext/stobject/power.cpp +++ b/reactos/dll/shellext/stobject/power.cpp @@ -10,12 +10,6 @@ #include "precomp.h" #include "powrprof.h" -#include -#include - -#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) -#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) - WINE_DEFAULT_DEBUG_CHANNEL(stobject); typedef struct _PWRSCHEMECONTEXT @@ -25,9 +19,7 @@ typedef struct _PWRSCHEMECONTEXT UINT uiLast; } PWRSCHEMECONTEXT, *PPWRSCHEMECONTEXT; -//static HICON g_hIconBattery = NULL; -static HICON g_hIconAC = NULL; - +static HICON g_hIconBattery = NULL; static BOOL g_IsRunning = FALSE; @@ -37,53 +29,18 @@ HRESULT STDMETHODCALLTYPE Power_Init(_In_ CSysTray * pSysTray) TRACE("Power_Init\n"); -// g_hIconBattery = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_BATTERY)); - g_hIconAC = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_BATTERY)); - - - HICON icon; -// if (g_IsMute) -// icon = g_hIconBattery; -// else - icon = g_hIconAC; + g_hIconBattery = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_BATTERY)); LoadStringW(g_hInstance, IDS_PWR_AC, strTooltip, _countof(strTooltip)); g_IsRunning = TRUE; - return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_POWER, icon, strTooltip); + return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_POWER, g_hIconBattery, strTooltip); } HRESULT STDMETHODCALLTYPE Power_Update(_In_ CSysTray * pSysTray) { -// BOOL PrevState; - TRACE("Power_Update\n"); - -#if 0 - PrevState = g_IsMute; - Volume_IsMute(); - - if (PrevState != g_IsMute) - { - WCHAR strTooltip[128]; - HICON icon; - if (g_IsMute) { - icon = g_hIconMute; - LoadStringW(g_hInstance, IDS_VOL_MUTED, strTooltip, _countof(strTooltip)); - } - else { - icon = g_hIconVolume; - LoadStringW(g_hInstance, IDS_VOL_VOLUME, strTooltip, _countof(strTooltip)); - } - - return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_POWER, icon, strTooltip); - } - else - { - return S_OK; - } -#endif return S_OK; } @@ -96,36 +53,37 @@ HRESULT STDMETHODCALLTYPE Power_Shutdown(_In_ CSysTray * pSysTray) return pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_POWER, NULL, NULL); } -static void _RunPower() +static void RunPower() { - ShellExecuteW(NULL, NULL, L"powercfg.cpl", NULL, NULL, SW_SHOWNORMAL); + ShellExecuteW(NULL, NULL, L"rundll32.exe", L"shell32.dll,Control_RunDLL powercfg.cpl", NULL, SW_SHOWNORMAL); } -static void _ShowContextMenu(CSysTray * pSysTray) +static void ShowContextMenu(CSysTray * pSysTray) { - WCHAR strOpen[128]; + WCHAR szBuffer[128]; + DWORD id, msgPos; + HMENU hPopup; - LoadStringW(g_hInstance, IDS_PWR_PROPERTIES, strOpen, _countof(strOpen)); + LoadStringW(g_hInstance, IDS_PWR_PROPERTIES, szBuffer, _countof(szBuffer)); - HMENU hPopup = CreatePopupMenu(); - AppendMenuW(hPopup, MF_STRING, IDS_PWR_PROPERTIES, strOpen); + hPopup = CreatePopupMenu(); + AppendMenuW(hPopup, MF_STRING, IDS_PWR_PROPERTIES, szBuffer); + SetMenuDefaultItem(hPopup, IDS_PWR_PROPERTIES, FALSE); - DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN; - DWORD msgPos = GetMessagePos(); + msgPos = GetMessagePos(); SetForegroundWindow(pSysTray->GetHWnd()); - DWORD id = TrackPopupMenuEx(hPopup, flags, - GET_X_LPARAM(msgPos), GET_Y_LPARAM(msgPos), - pSysTray->GetHWnd(), NULL); + id = TrackPopupMenuEx(hPopup, + TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN, + GET_X_LPARAM(msgPos), + GET_Y_LPARAM(msgPos), + pSysTray->GetHWnd(), + NULL); DestroyMenu(hPopup); - switch (id) - { - case IDS_PWR_PROPERTIES: - _RunPower(); - break; - } + if (id == IDS_PWR_PROPERTIES) + RunPower(); } static @@ -156,7 +114,7 @@ PowerSchemesEnumProc( static VOID ShowPowerSchemesPopupMenu( - CSysTray *pSysTray) + HWND hWnd) { PWRSCHEMECONTEXT PowerSchemeContext = {NULL, 0, 0}; UINT uiActiveScheme; @@ -176,12 +134,12 @@ ShowPowerSchemesPopupMenu( msgPos = GetMessagePos(); - SetForegroundWindow(pSysTray->GetHWnd()); + SetForegroundWindow(hWnd); id = TrackPopupMenuEx(PowerSchemeContext.hPopup, TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN, GET_X_LPARAM(msgPos), GET_Y_LPARAM(msgPos), - pSysTray->GetHWnd(), + hWnd, NULL); DestroyMenu(PowerSchemeContext.hPopup); @@ -222,21 +180,22 @@ HRESULT STDMETHODCALLTYPE Power_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPA switch (lParam) { case WM_LBUTTONDOWN: + SetTimer(pSysTray->GetHWnd(), POWER_TIMER_ID, 500, NULL); break; case WM_LBUTTONUP: - ShowPowerSchemesPopupMenu(pSysTray); break; case WM_LBUTTONDBLCLK: - _RunPower(); + KillTimer(pSysTray->GetHWnd(), POWER_TIMER_ID); + RunPower(); break; case WM_RBUTTONDOWN: break; case WM_RBUTTONUP: - _ShowContextMenu(pSysTray); + ShowContextMenu(pSysTray); break; case WM_RBUTTONDBLCLK: @@ -254,3 +213,11 @@ HRESULT STDMETHODCALLTYPE Power_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPA return S_FALSE; } + +VOID +Power_OnTimer(HWND hWnd) +{ + TRACE("Power_OnTimer\n!"); + KillTimer(hWnd, POWER_TIMER_ID); + ShowPowerSchemesPopupMenu(hWnd); +} diff --git a/reactos/dll/shellext/stobject/precomp.h b/reactos/dll/shellext/stobject/precomp.h index 66790be94b465..fd2ea78836a77 100644 --- a/reactos/dll/shellext/stobject/precomp.h +++ b/reactos/dll/shellext/stobject/precomp.h @@ -38,8 +38,12 @@ extern HINSTANCE g_hInstance; -#define ID_ICON_VOLUME (WM_APP + 0x4CB) -#define ID_ICON_POWER (WM_APP + 0x4CC) +#define ID_ICON_VOLUME (WM_APP + 0x4CB) +#define ID_ICON_HOTPLUG (WM_APP + 0x4CC) +#define ID_ICON_POWER (WM_APP + 0x4CD) + +#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) +#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) #include "csystray.h" @@ -65,8 +69,20 @@ extern HRESULT STDMETHODCALLTYPE Volume_Init(_In_ CSysTray * pSysTray); extern HRESULT STDMETHODCALLTYPE Volume_Shutdown(_In_ CSysTray * pSysTray); extern HRESULT STDMETHODCALLTYPE Volume_Update(_In_ CSysTray * pSysTray); extern HRESULT STDMETHODCALLTYPE Volume_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult); +extern VOID Volume_OnTimer(HWND hWnd); + +extern HRESULT STDMETHODCALLTYPE Hotplug_Init(_In_ CSysTray * pSysTray); +extern HRESULT STDMETHODCALLTYPE Hotplug_Shutdown(_In_ CSysTray * pSysTray); +extern HRESULT STDMETHODCALLTYPE Hotplug_Update(_In_ CSysTray * pSysTray); +extern HRESULT STDMETHODCALLTYPE Hotplug_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult); +extern VOID Hotplug_OnTimer(HWND hWnd); extern HRESULT STDMETHODCALLTYPE Power_Init(_In_ CSysTray * pSysTray); extern HRESULT STDMETHODCALLTYPE Power_Shutdown(_In_ CSysTray * pSysTray); extern HRESULT STDMETHODCALLTYPE Power_Update(_In_ CSysTray * pSysTray); extern HRESULT STDMETHODCALLTYPE Power_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult); +extern VOID Power_OnTimer(HWND hWnd); + +#define POWER_TIMER_ID 2 +#define VOLUME_TIMER_ID 3 +#define HOTPLUG_TIMER_ID 4 \ No newline at end of file diff --git a/reactos/dll/shellext/stobject/stobject.cpp b/reactos/dll/shellext/stobject/stobject.cpp index fc866f39ef3f5..f5b31e249e6a3 100644 --- a/reactos/dll/shellext/stobject/stobject.cpp +++ b/reactos/dll/shellext/stobject/stobject.cpp @@ -4,7 +4,7 @@ * FILE: dll/shellext/stobject/stobject.cpp * PURPOSE: COM registration services for STobject.dll * PROGRAMMERS: Robert Naumann - David Quintana + * David Quintana */ #include "precomp.h" diff --git a/reactos/dll/shellext/stobject/volume.cpp b/reactos/dll/shellext/stobject/volume.cpp index f848468af19bd..f82e6e0eeeb05 100644 --- a/reactos/dll/shellext/stobject/volume.cpp +++ b/reactos/dll/shellext/stobject/volume.cpp @@ -11,9 +11,6 @@ #include #include -#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) -#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) - WINE_DEFAULT_DEBUG_CHANNEL(stobject); HICON g_hIconVolume; @@ -116,7 +113,7 @@ static HRESULT __stdcall Volume_FindMixerControl(CSysTray * pSysTray) return S_OK; } -HRESULT Volume_IsMute() +HRESULT Volume_IsMute(VOID) { #if 0 MIXERCONTROLDETAILS mixerControlDetails; @@ -220,10 +217,10 @@ HRESULT Volume_OnDeviceChange(_In_ CSysTray * pSysTray, WPARAM wParam, LPARAM lP return Volume_FindMixerControl(pSysTray); } -static void _RunVolume() +static void _RunVolume(BOOL bSmall) { // FIXME: ensure we are loading the right one - ShellExecuteW(NULL, NULL, L"sndvol32.exe", NULL, NULL, SW_SHOWNORMAL); + ShellExecuteW(NULL, NULL, L"sndvol32.exe", bSmall ? L"/t" : NULL, NULL, SW_SHOWNORMAL); } static void _RunMMCpl() @@ -241,6 +238,7 @@ static void _ShowContextMenu(CSysTray * pSysTray) HMENU hPopup = CreatePopupMenu(); AppendMenuW(hPopup, MF_STRING, IDS_VOL_OPEN, strOpen); AppendMenuW(hPopup, MF_STRING, IDS_VOL_ADJUST, strAdjust); + SetMenuDefaultItem(hPopup, IDS_VOL_OPEN, FALSE); DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN; DWORD msgPos = GetMessagePos(); @@ -255,7 +253,7 @@ static void _ShowContextMenu(CSysTray * pSysTray) switch (id) { case IDS_VOL_OPEN: - _RunVolume(); + _RunVolume(FALSE); break; case IDS_VOL_ADJUST: _RunMMCpl(); @@ -298,14 +296,15 @@ HRESULT STDMETHODCALLTYPE Volume_Message(_In_ CSysTray * pSysTray, UINT uMsg, WP switch (lParam) { case WM_LBUTTONDOWN: + SetTimer(pSysTray->GetHWnd(), VOLUME_TIMER_ID, 500, NULL); break; case WM_LBUTTONUP: - TRACE("TODO: display volume slider\n"); break; case WM_LBUTTONDBLCLK: - _RunVolume(); + KillTimer(pSysTray->GetHWnd(), VOLUME_TIMER_ID); + _RunVolume(FALSE); break; case WM_RBUTTONDOWN: @@ -330,3 +329,11 @@ HRESULT STDMETHODCALLTYPE Volume_Message(_In_ CSysTray * pSysTray, UINT uMsg, WP return S_FALSE; } + +VOID +Volume_OnTimer(HWND hWnd) +{ + TRACE("Volume_OnTimer\n!"); + KillTimer(hWnd, VOLUME_TIMER_ID); + _RunVolume(TRUE); +}