[STOBJECT]
[reactos.git] / reactos / dll / shellext / stobject / power.cpp
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 * David Quintana <gigaherz@gmail.com>
8 */
9
10 #include "precomp.h"
11 #include "powrprof.h"
12
13 #include <mmsystem.h>
14 #include <mmddk.h>
15
16 #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
17 #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
18
19 WINE_DEFAULT_DEBUG_CHANNEL(stobject);
20
21 typedef struct _PWRSCHEMECONTEXT
22 {
23 HMENU hPopup;
24 UINT uiFirst;
25 UINT uiLast;
26 } PWRSCHEMECONTEXT, *PPWRSCHEMECONTEXT;
27
28 //static HICON g_hIconBattery = NULL;
29 static HICON g_hIconAC = NULL;
30
31 static BOOL g_IsRunning = FALSE;
32
33
34 HRESULT STDMETHODCALLTYPE Power_Init(_In_ CSysTray * pSysTray)
35 {
36 WCHAR strTooltip[128];
37
38 TRACE("Power_Init\n");
39
40 // g_hIconBattery = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_BATTERY));
41 g_hIconAC = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_BATTERY));
42
43
44 HICON icon;
45 // if (g_IsMute)
46 // icon = g_hIconBattery;
47 // else
48 icon = g_hIconAC;
49
50 LoadStringW(g_hInstance, IDS_PWR_AC, strTooltip, _countof(strTooltip));
51
52 g_IsRunning = TRUE;
53
54 return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_POWER, icon, strTooltip);
55 }
56
57 HRESULT STDMETHODCALLTYPE Power_Update(_In_ CSysTray * pSysTray)
58 {
59 // BOOL PrevState;
60
61 TRACE("Power_Update\n");
62
63 #if 0
64 PrevState = g_IsMute;
65 Volume_IsMute();
66
67 if (PrevState != g_IsMute)
68 {
69 WCHAR strTooltip[128];
70 HICON icon;
71 if (g_IsMute) {
72 icon = g_hIconMute;
73 LoadStringW(g_hInstance, IDS_VOL_MUTED, strTooltip, _countof(strTooltip));
74 }
75 else {
76 icon = g_hIconVolume;
77 LoadStringW(g_hInstance, IDS_VOL_VOLUME, strTooltip, _countof(strTooltip));
78 }
79
80 return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_POWER, icon, strTooltip);
81 }
82 else
83 {
84 return S_OK;
85 }
86 #endif
87 return S_OK;
88 }
89
90 HRESULT STDMETHODCALLTYPE Power_Shutdown(_In_ CSysTray * pSysTray)
91 {
92 TRACE("Power_Shutdown\n");
93
94 g_IsRunning = FALSE;
95
96 return pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_POWER, NULL, NULL);
97 }
98
99 static void _RunPower()
100 {
101 ShellExecuteW(NULL, NULL, L"powercfg.cpl", NULL, NULL, SW_SHOWNORMAL);
102 }
103
104 static void _ShowContextMenu(CSysTray * pSysTray)
105 {
106 WCHAR strOpen[128];
107
108 LoadStringW(g_hInstance, IDS_PWR_PROPERTIES, strOpen, _countof(strOpen));
109
110 HMENU hPopup = CreatePopupMenu();
111 AppendMenuW(hPopup, MF_STRING, IDS_PWR_PROPERTIES, strOpen);
112
113 DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN;
114 DWORD msgPos = GetMessagePos();
115
116 SetForegroundWindow(pSysTray->GetHWnd());
117 DWORD id = TrackPopupMenuEx(hPopup, flags,
118 GET_X_LPARAM(msgPos), GET_Y_LPARAM(msgPos),
119 pSysTray->GetHWnd(), NULL);
120
121 DestroyMenu(hPopup);
122
123 switch (id)
124 {
125 case IDS_PWR_PROPERTIES:
126 _RunPower();
127 break;
128 }
129 }
130
131 static
132 BOOLEAN
133 CALLBACK
134 PowerSchemesEnumProc(
135 UINT uiIndex,
136 DWORD dwName,
137 LPWSTR sName,
138 DWORD dwDesc,
139 LPWSTR sDesc,
140 PPOWER_POLICY pp,
141 LPARAM lParam)
142 {
143 PPWRSCHEMECONTEXT PowerSchemeContext = (PPWRSCHEMECONTEXT)lParam;
144
145 if (AppendMenuW(PowerSchemeContext->hPopup, MF_STRING, uiIndex + 1, sName))
146 {
147 if (PowerSchemeContext->uiFirst == 0)
148 PowerSchemeContext->uiFirst = uiIndex + 1;
149
150 PowerSchemeContext->uiLast = uiIndex + 1;
151 }
152
153 return TRUE;
154 }
155
156 static
157 VOID
158 ShowPowerSchemesPopupMenu(
159 CSysTray *pSysTray)
160 {
161 PWRSCHEMECONTEXT PowerSchemeContext = {NULL, 0, 0};
162 UINT uiActiveScheme;
163 DWORD id, msgPos;
164
165 PowerSchemeContext.hPopup = CreatePopupMenu();
166 EnumPwrSchemes(PowerSchemesEnumProc, (LPARAM)&PowerSchemeContext);
167
168 if (GetActivePwrScheme(&uiActiveScheme))
169 {
170 CheckMenuRadioItem(PowerSchemeContext.hPopup,
171 PowerSchemeContext.uiFirst,
172 PowerSchemeContext.uiLast,
173 uiActiveScheme + 1,
174 MF_BYCOMMAND);
175 }
176
177 msgPos = GetMessagePos();
178
179 SetForegroundWindow(pSysTray->GetHWnd());
180 id = TrackPopupMenuEx(PowerSchemeContext.hPopup,
181 TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN,
182 GET_X_LPARAM(msgPos),
183 GET_Y_LPARAM(msgPos),
184 pSysTray->GetHWnd(),
185 NULL);
186
187 DestroyMenu(PowerSchemeContext.hPopup);
188
189 if (id != 0)
190 SetActivePwrScheme(id - 1, NULL, NULL);
191 }
192
193 HRESULT STDMETHODCALLTYPE Power_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult)
194 {
195 TRACE("Power_Message uMsg=%d, wParam=%x, lParam=%x\n", uMsg, wParam, lParam);
196
197 switch (uMsg)
198 {
199 case WM_USER + 220:
200 TRACE("Power_Message: WM_USER+220\n");
201 if (wParam == 1)
202 {
203 if (lParam == FALSE)
204 return Power_Init(pSysTray);
205 else
206 return Power_Shutdown(pSysTray);
207 }
208 return S_FALSE;
209
210 case WM_USER + 221:
211 TRACE("Power_Message: WM_USER+221\n");
212 if (wParam == 1)
213 {
214 lResult = (LRESULT)g_IsRunning;
215 return S_OK;
216 }
217 return S_FALSE;
218
219 case ID_ICON_POWER:
220 Power_Update(pSysTray);
221
222 switch (lParam)
223 {
224 case WM_LBUTTONDOWN:
225 break;
226
227 case WM_LBUTTONUP:
228 ShowPowerSchemesPopupMenu(pSysTray);
229 break;
230
231 case WM_LBUTTONDBLCLK:
232 _RunPower();
233 break;
234
235 case WM_RBUTTONDOWN:
236 break;
237
238 case WM_RBUTTONUP:
239 _ShowContextMenu(pSysTray);
240 break;
241
242 case WM_RBUTTONDBLCLK:
243 break;
244
245 case WM_MOUSEMOVE:
246 break;
247 }
248 return S_OK;
249
250 default:
251 TRACE("Power_Message received for unknown ID %d, ignoring.\n");
252 return S_FALSE;
253 }
254
255 return S_FALSE;
256 }