Author: ekohl Date: Thu Mar 23 19:51:53 2017 New Revision: 74225
URL: http://svn.reactos.org/svn/reactos?rev=74225&view=rev Log: [STOBJECT] Implement code to show and hide the power and volume icons in the notification area aka systray. Control panel applications send WM_USR+220 messages to the systray window in order to show or hide an icon in the systray. The wParam parameter identifies the icon: 1=power, 4=volume. The lParam parameter indicates the new icon status: 0:show, 1:hide. Control panel applications also send WM_USER+221 messages to the systray window in order to retrieve the current status of a systray icon. The wParam parameter identifies the icon, just like in the WM_SUER+220 messages. The lParam parameter is ignored. The return value indicates the status of the icon: 1:visible, 0:hidden.
Added: trunk/reactos/dll/shellext/stobject/power.cpp (with props) Modified: trunk/reactos/dll/shellext/stobject/CMakeLists.txt trunk/reactos/dll/shellext/stobject/csystray.cpp trunk/reactos/dll/shellext/stobject/csystray.h trunk/reactos/dll/shellext/stobject/precomp.h trunk/reactos/dll/shellext/stobject/volume.cpp
Modified: trunk/reactos/dll/shellext/stobject/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/stobject/CMake... ============================================================================== --- trunk/reactos/dll/shellext/stobject/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/dll/shellext/stobject/CMakeLists.txt [iso-8859-1] Thu Mar 23 19:51:53 2017 @@ -21,6 +21,7 @@ csystray.cpp stobject.cpp stobject.rc + power.cpp volume.cpp ${CMAKE_CURRENT_BINARY_DIR}/stobject.def)
Modified: trunk/reactos/dll/shellext/stobject/csystray.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/stobject/csyst... ============================================================================== --- trunk/reactos/dll/shellext/stobject/csystray.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/shellext/stobject/csystray.cpp [iso-8859-1] Thu Mar 23 19:51:53 2017 @@ -11,9 +11,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(stobject);
SysTrayIconHandlers_t g_IconHandlers [] = { - { Volume_Init, Volume_Shutdown, Volume_Update, Volume_Message } + { Volume_Init, Volume_Shutdown, Volume_Update, Volume_Message }, + { Power_Init, Power_Shutdown, Power_Update, Power_Message } }; -const int g_NumIcons = _countof(g_IconHandlers); +const int g_NumIcons = _countof(g_IconHandlers);
CSysTray::CSysTray() {} CSysTray::~CSysTray() {} @@ -79,11 +80,11 @@ return S_OK; }
-HRESULT CSysTray::ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - for (int i = 0; i < g_NumIcons; i++) - { - HRESULT hr = g_IconHandlers[i].pfnMessage(this, uMsg, wParam, lParam); +HRESULT CSysTray::ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult) +{ + for (int i = 0; i < g_NumIcons; i++) + { + HRESULT hr = g_IconHandlers[i].pfnMessage(this, uMsg, wParam, lParam, lResult); if (FAILED(hr)) return hr;
@@ -225,7 +226,7 @@
TRACE("SysTray message received %u (%08p %08p)\n", uMsg, wParam, lParam);
- hr = ProcessIconMessage(uMsg, wParam, lParam); + hr = ProcessIconMessage(uMsg, wParam, lParam, lResult); if (FAILED(hr)) return FALSE;
Modified: trunk/reactos/dll/shellext/stobject/csystray.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/stobject/csyst... ============================================================================== --- trunk/reactos/dll/shellext/stobject/csystray.h [iso-8859-1] (original) +++ trunk/reactos/dll/shellext/stobject/csystray.h [iso-8859-1] Thu Mar 23 19:51:53 2017 @@ -4,7 +4,7 @@ * FILE: dll/shellext/stobject/csystray.h * PURPOSE: Systray shell service object * PROGRAMMERS: Robert Naumann - David Quintana gigaherz@gmail.com + * David Quintana gigaherz@gmail.com */ #pragma once
@@ -37,7 +37,7 @@ HRESULT InitIcons(); HRESULT ShutdownIcons(); HRESULT UpdateIcons(); - HRESULT ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); + HRESULT ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult);
HRESULT InitNetShell(); HRESULT ShutdownNetShell();
Added: trunk/reactos/dll/shellext/stobject/power.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/stobject/power... ============================================================================== --- trunk/reactos/dll/shellext/stobject/power.cpp (added) +++ trunk/reactos/dll/shellext/stobject/power.cpp [iso-8859-1] Thu Mar 23 19:51:53 2017 @@ -0,0 +1,185 @@ +/* + * PROJECT: ReactOS system libraries + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/shellext/stobject/power.cpp + * PURPOSE: Power notification icon handler + * PROGRAMMERS: Eric Kohl eric.kohl@reactos.org + * David Quintana gigaherz@gmail.com + */ + +#include "precomp.h" + +#include <mmsystem.h> +#include <mmddk.h> + +#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) +#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) + +WINE_DEFAULT_DEBUG_CHANNEL(stobject); + +//static HICON g_hIconBattery = NULL; +static HICON g_hIconAC = NULL; + +static BOOL g_IsRunning = FALSE; + + +HRESULT STDMETHODCALLTYPE Power_Init(_In_ CSysTray * pSysTray) +{ + WCHAR strTooltip[128]; + + 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; + + LoadStringW(g_hInstance, IDS_PWR_AC, strTooltip, _countof(strTooltip)); + + g_IsRunning = TRUE; + + return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_POWER, icon, 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; +} + +HRESULT STDMETHODCALLTYPE Power_Shutdown(_In_ CSysTray * pSysTray) +{ + TRACE("Power_Shutdown\n"); + + g_IsRunning = FALSE; + + return pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_POWER, NULL, NULL); +} + +static void _RunPower() +{ + ShellExecuteW(NULL, NULL, L"powercfg.cpl", NULL, NULL, SW_SHOWNORMAL); +} + +static void _ShowContextMenu(CSysTray * pSysTray) +{ + WCHAR strOpen[128]; + + LoadStringW(g_hInstance, IDS_PWR_PROPERTIES, strOpen, _countof(strOpen)); + + HMENU hPopup = CreatePopupMenu(); + AppendMenuW(hPopup, MF_STRING, IDS_PWR_PROPERTIES, strOpen); + + DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN; + DWORD msgPos = GetMessagePos(); + + SetForegroundWindow(pSysTray->GetHWnd()); + DWORD id = TrackPopupMenuEx(hPopup, flags, + GET_X_LPARAM(msgPos), GET_Y_LPARAM(msgPos), + pSysTray->GetHWnd(), NULL); + + DestroyMenu(hPopup); + + switch (id) + { + case IDS_PWR_PROPERTIES: + _RunPower(); + break; + } +} + +HRESULT STDMETHODCALLTYPE Power_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult) +{ + TRACE("Power_Message uMsg=%d, wParam=%x, lParam=%x\n", uMsg, wParam, lParam); + + switch (uMsg) + { + case WM_USER + 220: + TRACE("Power_Message: WM_USER+220\n"); + if (wParam == 1) + { + if (lParam == FALSE) + return Power_Init(pSysTray); + else + return Power_Shutdown(pSysTray); + } + return S_FALSE; + + case WM_USER + 221: + TRACE("Power_Message: WM_USER+221\n"); + if (wParam == 1) + { + lResult = (LRESULT)g_IsRunning; + return S_OK; + } + return S_FALSE; + + case ID_ICON_POWER: + Power_Update(pSysTray); + + switch (lParam) + { + case WM_LBUTTONDOWN: + break; + + case WM_LBUTTONUP: + TRACE("TODO: display power options!\n"); + break; + + case WM_LBUTTONDBLCLK: + _RunPower(); + break; + + case WM_RBUTTONDOWN: + break; + + case WM_RBUTTONUP: + _ShowContextMenu(pSysTray); + + case WM_RBUTTONDBLCLK: + break; + + case WM_MOUSEMOVE: + break; + } + return S_OK; + + default: + TRACE("Power_Message received for unknown ID %d, ignoring.\n"); + return S_FALSE; + } + + return S_FALSE; +}
Propchange: trunk/reactos/dll/shellext/stobject/power.cpp ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/dll/shellext/stobject/precomp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/stobject/preco... ============================================================================== --- trunk/reactos/dll/shellext/stobject/precomp.h [iso-8859-1] (original) +++ trunk/reactos/dll/shellext/stobject/precomp.h [iso-8859-1] Thu Mar 23 19:51:53 2017 @@ -39,13 +39,14 @@ extern HINSTANCE g_hInstance;
#define ID_ICON_VOLUME (WM_APP + 0x4CB) +#define ID_ICON_POWER (WM_APP + 0x4CC)
#include "csystray.h"
typedef HRESULT(STDMETHODCALLTYPE * PFNSTINIT) (_In_ CSysTray * pSysTray); typedef HRESULT(STDMETHODCALLTYPE * PFNSTSHUTDOWN) (_In_ CSysTray * pSysTray); typedef HRESULT(STDMETHODCALLTYPE * PFNSTUPDATE) (_In_ CSysTray * pSysTray); -typedef HRESULT(STDMETHODCALLTYPE * PFNSTMESSAGE) (_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam); +typedef HRESULT(STDMETHODCALLTYPE * PFNSTMESSAGE) (_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult);
struct SysTrayIconHandlers_t { @@ -63,4 +64,9 @@ 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); +extern HRESULT STDMETHODCALLTYPE Volume_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult); + +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);
Modified: trunk/reactos/dll/shellext/stobject/volume.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/stobject/volum... ============================================================================== --- trunk/reactos/dll/shellext/stobject/volume.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/shellext/stobject/volume.cpp [iso-8859-1] Thu Mar 23 19:51:53 2017 @@ -26,7 +26,8 @@
UINT g_mmDeviceChange;
-BOOL g_IsMute = FALSE; +static BOOL g_IsMute = FALSE; +static BOOL g_IsRunning = FALSE;
static HRESULT __stdcall Volume_FindMixerControl(CSysTray * pSysTray) { @@ -161,6 +162,8 @@
Volume_IsMute();
+ g_IsRunning = TRUE; + HICON icon; if (g_IsMute) icon = g_hIconMute; @@ -184,11 +187,13 @@ { WCHAR strTooltip[128]; HICON icon; - if (g_IsMute) { + if (g_IsMute) + { icon = g_hIconMute; LoadStringW(g_hInstance, IDS_VOL_MUTED, strTooltip, _countof(strTooltip)); } - else { + else + { icon = g_hIconVolume; LoadStringW(g_hInstance, IDS_VOL_VOLUME, strTooltip, _countof(strTooltip)); } @@ -204,6 +209,8 @@ HRESULT STDMETHODCALLTYPE Volume_Shutdown(_In_ CSysTray * pSysTray) { TRACE("Volume_Shutdown\n"); + + g_IsRunning = FALSE;
return pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_VOLUME, NULL, NULL); } @@ -256,40 +263,70 @@ } }
-HRESULT STDMETHODCALLTYPE Volume_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam) +HRESULT STDMETHODCALLTYPE Volume_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult) { if (uMsg == g_mmDeviceChange) return Volume_OnDeviceChange(pSysTray, wParam, lParam);
- if (uMsg != ID_ICON_VOLUME) - { - TRACE("Volume_Message received for unknown ID %d, ignoring.\n"); - return S_FALSE; - } - - TRACE("Volume_Message uMsg=%d, w=%x, l=%x\n", uMsg, wParam, lParam); - - Volume_Update(pSysTray); - - switch (lParam) - { - case WM_LBUTTONDOWN: - break; - case WM_LBUTTONUP: - TRACE("TODO: display volume slider\n"); - break; - case WM_LBUTTONDBLCLK: - _RunVolume(); - break; - case WM_RBUTTONDOWN: - break; - case WM_RBUTTONUP: - _ShowContextMenu(pSysTray); - case WM_RBUTTONDBLCLK: - break; - case WM_MOUSEMOVE: - break; - } - - return S_OK; -} + switch (uMsg) + { + case WM_USER + 220: + TRACE("Volume_Message: WM_USER+220\n"); + if (wParam == 4) + { + if (lParam == FALSE) + return Volume_Init(pSysTray); + else + return Volume_Shutdown(pSysTray); + } + return S_FALSE; + + case WM_USER + 221: + TRACE("Volume_Message: WM_USER+221\n"); + if (wParam == 4) + { + lResult = (LRESULT)g_IsRunning; + return S_OK; + } + return S_FALSE; + + case ID_ICON_VOLUME: + TRACE("Volume_Message uMsg=%d, w=%x, l=%x\n", uMsg, wParam, lParam); + + Volume_Update(pSysTray); + + switch (lParam) + { + case WM_LBUTTONDOWN: + break; + + case WM_LBUTTONUP: + TRACE("TODO: display volume slider\n"); + break; + + case WM_LBUTTONDBLCLK: + _RunVolume(); + break; + + case WM_RBUTTONDOWN: + break; + + case WM_RBUTTONUP: + _ShowContextMenu(pSysTray); + break; + + case WM_RBUTTONDBLCLK: + break; + + case WM_MOUSEMOVE: + break; + } + return S_OK; + + default: + TRACE("Volume_Message received for unknown ID %d, ignoring.\n"); + return S_FALSE; + } + + return S_FALSE; +}