ReactOS  0.4.15-dev-980-ge160524
power.cpp
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS system libraries
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: dll/shellext/stobject/power.cpp
5  * PURPOSE: Power notification icon handler
6  * PROGRAMMERS: Eric Kohl <eric.kohl@reactos.org>
7  Shriraj Sawant a.k.a SR13 <sr.official@hotmail.com>
8  * David Quintana <gigaherz@gmail.com>
9  */
10 
11 #include "precomp.h"
12 
13 #include <devguid.h>
14 #include <winioctl.h>
15 #include <powrprof.h>
16 #include <windows.h>
17 #include <batclass.h>
18 
19 int br_icons[5] = { IDI_BATTCAP0, IDI_BATTCAP1, IDI_BATTCAP2, IDI_BATTCAP3, IDI_BATTCAP4 }; // battery mode icons.
20 int bc_icons[5] = { IDI_BATTCHA0, IDI_BATTCHA1, IDI_BATTCHA2, IDI_BATTCHA3, IDI_BATTCHA4 }; // charging mode icons.
21 
22 typedef struct _PWRSCHEMECONTEXT
23 {
28 
31 
32 
33 /*++
34 * @name Quantize
35 *
36 * This function quantizes the mentioned quantity to nearest level.
37 *
38 * @param p
39 * Should be a quantity in percentage.
40 *
41 * @return Nearest quantized level, can be directly used as array index based on context.
42 *
43  @remarks This function uses centred/symmetric logic for quantization.
44  For the case of lvl = 4, You will get following integer levels if given (p) value falls in between the range partitions:
45  0 <= p < 12.5 : returns 0; (corresponding to 0% centre)
46  12.5 <= p < 37.5 : returns 1; (corresponding to 25% centre)
47  37.5 <= p < 62.5 : returns 2; (corresponding to 50% centre)
48  62.5 <= p < 87.5 : returns 3; (corresponding to 75% centre)
49  87.5 <= p <= 100 : returns 4; (corresponding to 100% centre)
50  *--*/
52 {
53  if (p <= 12)
54  return 0;
55  else if (p > 12 && p <= 37)
56  return 1;
57  else if (p > 37 && p <= 62)
58  return 2;
59  else if (p > 62 && p <= 87)
60  return 3;
61  else
62  return 4;
63 }
64 
65 /*++
66 * @name DynamicLoadIcon
67 *
68 * Returns the respective icon as per the current battery capacity.
69 * It also does the work of setting global parameters of battery capacity and tooltips.
70 *
71 * @param hinst
72 * A handle to a instance of the module.
73 *
74 * @return The handle to respective battery icon.
75 *
76 *--*/
78 {
79  SYSTEM_POWER_STATUS PowerStatus;
80  HICON hBatIcon;
81  UINT index = -1;
82 
83  if (!GetSystemPowerStatus(&PowerStatus) ||
84  PowerStatus.ACLineStatus == AC_LINE_UNKNOWN ||
85  PowerStatus.BatteryFlag == BATTERY_FLAG_UNKNOWN)
86  {
89  return hBatIcon;
90  }
91 
92  if (((PowerStatus.BatteryFlag & BATTERY_FLAG_NO_BATTERY) == 0) &&
94  {
95  index = Quantize(PowerStatus.BatteryLifePercent);
98  }
99  else if (((PowerStatus.BatteryFlag & BATTERY_FLAG_NO_BATTERY) == 0) &&
100  ((PowerStatus.BatteryFlag & BATTERY_FLAG_CHARGING) == 0))
101  {
102  index = Quantize(PowerStatus.BatteryLifePercent);
105  }
106  else
107  {
109  g_strTooltip.LoadStringW(IDS_PWR_AC);
110  }
111 
112  return hBatIcon;
113 }
114 
116 {
117  TRACE("Power_Init\n");
119 
120  return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_POWER, g_hIconBattery, g_strTooltip);
121 }
122 
124 {
125  TRACE("Power_Update\n");
127 
128  return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_POWER, g_hIconBattery, g_strTooltip);
129 }
130 
132 {
133  TRACE("Power_Shutdown\n");
134 
135  return pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_POWER, NULL, NULL);
136 }
137 
138 static void _RunPower()
139 {
140  ShellExecuteW(NULL, NULL, L"powercfg.cpl", NULL, NULL, SW_SHOWNORMAL);
141 }
142 
143 static void _ShowContextMenu(CSysTray * pSysTray)
144 {
146  HMENU hPopup = CreatePopupMenu();
147  AppendMenuW(hPopup, MF_STRING, IDS_PWR_PROPERTIES, strOpen);
149 
150  SetForegroundWindow(pSysTray->GetHWnd());
152  POINT pt;
153  GetCursorPos(&pt);
154 
155  DWORD id = TrackPopupMenuEx(hPopup, flags,
156  pt.x, pt.y,
157  pSysTray->GetHWnd(), NULL);
158 
159  switch (id)
160  {
161  case IDS_PWR_PROPERTIES:
162  _RunPower();
163  break;
164  }
165  DestroyMenu(hPopup);
166 }
167 
168 static
169 BOOLEAN
170 CALLBACK
172  UINT uiIndex,
173  DWORD dwName,
174  LPWSTR sName,
175  DWORD dwDesc,
176  LPWSTR sDesc,
178  LPARAM lParam)
179 {
180  PPWRSCHEMECONTEXT PowerSchemeContext = (PPWRSCHEMECONTEXT)lParam;
181 
182  if (AppendMenuW(PowerSchemeContext->hPopup, MF_STRING, uiIndex + 1, sName))
183  {
184  if (PowerSchemeContext->uiFirst == 0)
185  PowerSchemeContext->uiFirst = uiIndex + 1;
186 
187  PowerSchemeContext->uiLast = uiIndex + 1;
188  }
189 
190  return TRUE;
191 }
192 
193 static
194 VOID
196  CSysTray *pSysTray)
197 {
198  PWRSCHEMECONTEXT PowerSchemeContext = {NULL, 0, 0};
199  UINT uiActiveScheme;
200  DWORD id;
201  POINT pt;
202  PowerSchemeContext.hPopup = CreatePopupMenu();
203  EnumPwrSchemes(PowerSchemesEnumProc, (LPARAM)&PowerSchemeContext);
204 
205  if (GetActivePwrScheme(&uiActiveScheme))
206  {
207  CheckMenuRadioItem(PowerSchemeContext.hPopup,
208  PowerSchemeContext.uiFirst,
209  PowerSchemeContext.uiLast,
210  uiActiveScheme + 1,
211  MF_BYCOMMAND);
212  }
213 
214  SetForegroundWindow(pSysTray->GetHWnd());
215  GetCursorPos(&pt);
216 
217  id = TrackPopupMenuEx(PowerSchemeContext.hPopup,
219  pt.x,
220  pt.y,
221  pSysTray->GetHWnd(),
222  NULL);
223 
224  DestroyMenu(PowerSchemeContext.hPopup);
225 
226  if (id != 0)
227  SetActivePwrScheme(id - 1, NULL, NULL);
228 }
229 
231 {
232  TRACE("Power_Message uMsg=%d, wParam=%x, lParam=%x\n", uMsg, wParam, lParam);
233 
234  switch (uMsg)
235  {
236  case WM_USER + 220:
237  TRACE("Power_Message: WM_USER+220\n");
238  if (wParam == POWER_SERVICE_FLAG)
239  {
240  if (lParam)
241  {
242  pSysTray->EnableService(POWER_SERVICE_FLAG, TRUE);
243  return Power_Init(pSysTray);
244  }
245  else
246  {
247  pSysTray->EnableService(POWER_SERVICE_FLAG, FALSE);
248  return Power_Shutdown(pSysTray);
249  }
250  }
251  return S_FALSE;
252 
253  case WM_USER + 221:
254  TRACE("Power_Message: WM_USER+221\n");
255  if (wParam == POWER_SERVICE_FLAG)
256  {
257  lResult = (LRESULT)pSysTray->IsServiceEnabled(POWER_SERVICE_FLAG);
258  return S_OK;
259  }
260  return S_FALSE;
261 
262  case WM_TIMER:
263  if (wParam == POWER_TIMER_ID)
264  {
265  KillTimer(pSysTray->GetHWnd(), POWER_TIMER_ID);
266  ShowPowerSchemesPopupMenu(pSysTray);
267  }
268  break;
269 
270  case ID_ICON_POWER:
271  Power_Update(pSysTray);
272 
273  switch (lParam)
274  {
275  case WM_LBUTTONDOWN:
276  SetTimer(pSysTray->GetHWnd(), POWER_TIMER_ID, GetDoubleClickTime(), NULL);
277  break;
278 
279  case WM_LBUTTONUP:
280  break;
281 
282  case WM_LBUTTONDBLCLK:
283  KillTimer(pSysTray->GetHWnd(), POWER_TIMER_ID);
284  _RunPower();
285  break;
286 
287  case WM_RBUTTONDOWN:
288  break;
289 
290  case WM_RBUTTONUP:
291  _ShowContextMenu(pSysTray);
292  break;
293 
294  case WM_RBUTTONDBLCLK:
295  break;
296 
297  case WM_MOUSEMOVE:
298  break;
299  }
300  return S_OK;
301 
302  default:
303  TRACE("Power_Message received for unknown ID %d, ignoring.\n");
304  return S_FALSE;
305  }
306 
307  return S_FALSE;
308 }
static BOOLEAN CALLBACK PowerSchemesEnumProc(UINT uiIndex, DWORD dwName, LPWSTR sName, DWORD dwDesc, LPWSTR sDesc, PPOWER_POLICY pp, LPARAM lParam)
Definition: power.cpp:171
#define POWER_SERVICE_FLAG
Definition: precomp.h:37
#define IDI_BATTCAP3
Definition: resource.h:45
#define MAKEINTRESOURCE
Definition: winuser.h:591
HRESULT STDMETHODCALLTYPE Power_Init(_In_ CSysTray *pSysTray)
Definition: power.cpp:115
static HICON
Definition: imagelist.c:84
#define MF_BYCOMMAND
Definition: winuser.h:202
struct _PWRSCHEMECONTEXT * PPWRSCHEMECONTEXT
#define WM_LBUTTONDOWN
Definition: winuser.h:1758
#define TRUE
Definition: types.h:120
#define pt(x, y)
Definition: drawing.c:79
HRESULT STDMETHODCALLTYPE Power_Update(_In_ CSysTray *pSysTray)
Definition: power.cpp:123
BOOLEAN WINAPI SetActivePwrScheme(UINT uiID, PGLOBAL_POWER_POLICY lpGlobalPowerPolicy, PPOWER_POLICY lpPowerPolicy)
Definition: powrprof.c:642
BOOL WINAPI CheckMenuRadioItem(_In_ HMENU, _In_ UINT, _In_ UINT, _In_ UINT, _In_ UINT)
#define TPM_RETURNCMD
Definition: winuser.h:2362
static void _ShowContextMenu(CSysTray *pSysTray)
Definition: power.cpp:143
BOOL WINAPI TrackPopupMenuEx(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _In_ HWND, _In_opt_ LPTPMPARAMS)
#define CALLBACK
Definition: compat.h:35
#define MF_STRING
Definition: winuser.h:138
static HICON g_hIconBattery
Definition: power.cpp:30
void __cdecl Format(UINT nFormatID,...)
Definition: cstringt.h:716
BOOL WINAPI GetSystemPowerStatus(IN LPSYSTEM_POWER_STATUS PowerStatus)
Definition: power.c:27
UINT_PTR WPARAM
Definition: windef.h:207
#define IDS_PWR_PROPERTIES
Definition: resource.h:5
#define BATTERY_FLAG_NO_BATTERY
Definition: winbase.h:500
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2635
WPARAM wParam
Definition: combotst.c:138
BOOL WINAPI AppendMenuW(_In_ HMENU, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCWSTR)
#define IDI_BATTCAP4
Definition: resource.h:46
#define IDS_PWR_CHARGING
Definition: resource.h:9
#define FALSE
Definition: types.h:117
#define BATTERY_FLAG_UNKNOWN
Definition: winbase.h:501
#define pp
Definition: hlsl.yy.c:1208
#define S_FALSE
Definition: winerror.h:2357
struct _PWRSCHEMECONTEXT PWRSCHEMECONTEXT
static UINT Quantize(BYTE p)
Definition: power.cpp:51
unsigned char BOOLEAN
#define TPM_BOTTOMALIGN
Definition: winuser.h:2360
HRESULT STDMETHODCALLTYPE Power_Message(_In_ CSysTray *pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult)
Definition: power.cpp:230
smooth NULL
Definition: ftsmooth.c:416
LONG_PTR LPARAM
Definition: windef.h:208
#define IDI_BATTCAP0
Definition: resource.h:42
#define IDI_BATTCAP2
Definition: resource.h:44
GLuint index
Definition: glext.h:6031
const char * LPCSTR
Definition: xmlstorage.h:183
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
#define WM_RBUTTONDOWN
Definition: winuser.h:1761
#define IDS_PWR_UNKNOWN_REMAINING
Definition: resource.h:10
#define TRACE(s)
Definition: solgame.cpp:4
#define AC_LINE_UNKNOWN
Definition: winbase.h:495
#define ID_ICON_POWER
Definition: precomp.h:35
LONG HRESULT
Definition: typedefs.h:79
#define WM_TIMER
Definition: winuser.h:1724
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
int bc_icons[5]
Definition: power.cpp:20
BOOLEAN WINAPI EnumPwrSchemes(PWRSCHEMESENUMPROC lpfnPwrSchemesEnumProc, LPARAM lParam)
Definition: powrprof.c:219
BOOLEAN WINAPI GetActivePwrScheme(PUINT puiID)
Definition: powrprof.c:285
#define IDI_BATTCHA3
Definition: resource.h:51
unsigned long DWORD
Definition: ntddk_ex.h:95
#define NIM_DELETE
Definition: shellapi.h:93
#define WM_RBUTTONUP
Definition: winuser.h:1762
#define TPM_NONOTIFY
Definition: winuser.h:2361
GLbitfield flags
Definition: glext.h:7161
#define IDI_BATTCHA0
Definition: resource.h:48
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
static const WCHAR L[]
Definition: oid.c:1250
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1760
#define LRESULT
Definition: ole.h:14
static VOID ShowPowerSchemesPopupMenu(CSysTray *pSysTray)
Definition: power.cpp:195
unsigned char BYTE
Definition: xxhash.c:193
#define IDI_BATTCHA2
Definition: resource.h:50
#define WM_USER
Definition: winuser.h:1877
#define IDI_BATTCAP_ERR
Definition: resource.h:53
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define _In_
Definition: no_sal2.h:204
#define IDI_BATTCAP1
Definition: resource.h:43
int br_icons[5]
Definition: power.cpp:19
#define IDI_BATTCHA4
Definition: resource.h:52
#define S_OK
Definition: intsafe.h:59
#define SW_SHOWNORMAL
Definition: winuser.h:764
#define POWER_TIMER_ID
Definition: precomp.h:77
#define WM_LBUTTONUP
Definition: winuser.h:1759
static HICON DynamicLoadIcon(HINSTANCE hinst)
Definition: power.cpp:77
HWND GetHWnd()
Definition: csystray.h:53
unsigned int UINT
Definition: ndis.h:50
#define WM_MOUSEMOVE
Definition: winuser.h:1757
#define BATTERY_FLAG_CHARGING
Definition: winbase.h:499
BOOL WINAPI SetMenuDefaultItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define IDI_POWER_AC
Definition: resource.h:54
#define NIM_ADD
Definition: shellapi.h:91
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:846
CString g_strTooltip
Definition: power.cpp:29
#define IDI_BATTCHA1
Definition: resource.h:49
UINT WINAPI GetDoubleClickTime(void)
Definition: ntwrapper.h:314
#define WM_RBUTTONDBLCLK
Definition: winuser.h:1763
HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
Definition: shlexec.cpp:2274
GLenum GLuint id
Definition: glext.h:5579
#define IDS_PWR_PERCENT_REMAINING
Definition: resource.h:8
static HINSTANCE hinst
Definition: edit.c:551
BOOL WINAPI SetForegroundWindow(_In_ HWND)
HRESULT STDMETHODCALLTYPE Power_Shutdown(_In_ CSysTray *pSysTray)
Definition: power.cpp:131
#define LoadIcon
Definition: winuser.h:5788
HINSTANCE g_hInstance
Definition: MainWindow.cpp:18
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define IDS_PWR_AC
Definition: resource.h:11
LONG_PTR LRESULT
Definition: windef.h:209
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
LPARAM lParam
Definition: combotst.c:139
#define TPM_RIGHTALIGN
Definition: winuser.h:2353
static void _RunPower()
Definition: power.cpp:138
#define NIM_MODIFY
Definition: shellapi.h:92