mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[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. svn path=/trunk/; revision=74225
This commit is contained in:
parent
b8b7eedce2
commit
a9265410de
6 changed files with 271 additions and 41 deletions
|
@ -21,6 +21,7 @@ add_library(stobject SHARED
|
|||
csystray.cpp
|
||||
stobject.cpp
|
||||
stobject.rc
|
||||
power.cpp
|
||||
volume.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/stobject.def)
|
||||
|
||||
|
|
|
@ -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 @@ HRESULT CSysTray::UpdateIcons()
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CSysTray::ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM 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);
|
||||
HRESULT hr = g_IconHandlers[i].pfnMessage(this, uMsg, wParam, lParam, lResult);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
|
@ -225,7 +226,7 @@ BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
|
|||
|
||||
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;
|
||||
|
||||
|
|
|
@ -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 @@ class CSysTray :
|
|||
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();
|
||||
|
|
185
reactos/dll/shellext/stobject/power.cpp
Normal file
185
reactos/dll/shellext/stobject/power.cpp
Normal file
|
@ -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;
|
||||
}
|
|
@ -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 const int g_NumIcons;
|
|||
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);
|
||||
|
|
|
@ -26,7 +26,8 @@ DWORD g_muteControlID;
|
|||
|
||||
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 @@ HRESULT STDMETHODCALLTYPE Volume_Init(_In_ CSysTray * pSysTray)
|
|||
|
||||
Volume_IsMute();
|
||||
|
||||
g_IsRunning = TRUE;
|
||||
|
||||
HICON icon;
|
||||
if (g_IsMute)
|
||||
icon = g_hIconMute;
|
||||
|
@ -184,11 +187,13 @@ HRESULT STDMETHODCALLTYPE Volume_Update(_In_ CSysTray * pSysTray)
|
|||
{
|
||||
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));
|
||||
}
|
||||
|
@ -205,6 +210,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 @@ static void _ShowContextMenu(CSysTray * pSysTray)
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
switch (uMsg)
|
||||
{
|
||||
TRACE("Volume_Message received for unknown ID %d, ignoring.\n");
|
||||
return S_FALSE;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue