ReactOS 0.4.16-dev-755-g88f105e
traydeskbtn.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Explorer
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Show Desktop tray button implementation
5 * COPYRIGHT: Copyright 2006-2007 Thomas Weidenmueller <w3seek@reactos.org>
6 * Copyright 2018-2022 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
7 * Copyright 2023 Ethan Rodensky <splitwirez@gmail.com>
8 */
9
10#include "precomp.h"
11#include <commoncontrols.h>
12#include <uxtheme.h>
13
14#define IDI_SHELL32_DESKTOP 35
15#define IDI_IMAGERES_DESKTOP 110
16
17#define SHOW_DESKTOP_TIMER_ID 999
18#define SHOW_DESKTOP_TIMER_INTERVAL 200
19
21 m_nClickedTime(0),
22 m_inset({2, 2}),
23 m_icon(NULL),
24 m_highContrastMode(FALSE),
25 m_drawWithDedicatedBackground(FALSE),
26 m_bHovering(FALSE),
27 m_hWndTaskbar(NULL),
28 m_bPressed(FALSE),
29 m_bHorizontal(FALSE)
30{
31}
32
34{
36 {
38 {
39 if (GetSystemMetrics(SM_TABLETPC))
40 {
41 //TODO: DPI scaling - return logical-to-physical conversion of 24, not fixed value
42 return 24;
43 }
44 else
45 return 15;
46 }
47 else
48 {
49 INT CurMargin = m_bHorizontal
52 return max(16 + CurMargin, 18) + 6;
53 }
54 }
55 else
56 {
59 }
60}
61
63{
66
67 if (!m_hWnd)
68 return E_FAIL;
69
70 // Get desktop icon
71 bool bIconRetrievalFailed = ExtractIconExW(L"imageres.dll", -IDI_IMAGERES_DESKTOP, NULL, &m_icon, 1) == UINT_MAX;
72 if (bIconRetrievalFailed || !m_icon)
73 ExtractIconExW(L"shell32.dll", -IDI_SHELL32_DESKTOP, NULL, &m_icon, 1);
74
75 // Get appropriate size at which to display desktop icon
78
79 // Create tooltip
81
82 TOOLINFOW ti = { 0 };
83 ti.cbSize = TTTOOLINFOW_V1_SIZE;
84 ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
85 ti.hwnd = m_hWnd;
86 ti.uId = reinterpret_cast<UINT_PTR>(m_hWnd);
87 ti.hinst = hExplorerInstance;
89
90 m_tooltip.AddTool(&ti);
91
92 // Prep visual style
94
95 // Get HWND of Taskbar
98 return E_FAIL;
99
100 return S_OK;
101}
102
104{
105 // The actual action can be delayed as an expected behaviour.
106 // But a too late action is an unexpected behaviour.
107 LONG nTime0 = m_nClickedTime;
108 LONG nTime1 = ::GetMessageTime();
109 if (nTime1 - nTime0 >= 600) // Ignore after 0.6 sec
110 return 0;
111
112 // Show/Hide Desktop
114
115 return 0;
116}
117
118// This function is called from OnLButtonDown and parent.
120{
121 // The actual action can be delayed as an expected behaviour.
123 PostMessage(TSDB_CLICK, 0, 0);
124}
125
127{
130 Invalidate(TRUE);
131
132 POINT pt;
134 if (PtInButton(&pt))
135 Click(); // Left-click
136 return 0;
137}
138
140{
142 SetCapture();
143 Invalidate(TRUE);
144 return 0;
145}
146
148{
149 LRESULT ret = OnThemeChanged(uMsg, wParam, lParam, bHandled);
151 return ret;
152}
153
155{
156 HIGHCONTRAST hcInfo;
157 hcInfo.cbSize = sizeof(hcInfo);
158 if (SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(hcInfo), &hcInfo, FALSE))
160
161 if (m_hTheme)
162 {
164 m_hTheme = NULL;
165 }
167 {
170 }
171
173
174 Invalidate(TRUE);
175 return 0;
176}
177
179{
181 return 0;
182}
183
185{
186 if (setTheme)
187 SetWindowTheme(m_hWnd, m_bHorizontal ? L"ShowDesktop" : L"VerticalShowDesktop", NULL);
188
190 {
193 }
194 else
195 {
197 }
198
199 MARGINS contentMargins;
200 if (GetThemeMargins(GetWindowTheme(GetParent().m_hWnd), NULL, TNP_BACKGROUND, 0, TMT_CONTENTMARGINS, NULL, &contentMargins) == S_OK)
201 {
202 m_inset.cx = max(0, contentMargins.cxRightWidth - 5);
203 m_inset.cy = max(0, contentMargins.cyBottomHeight - 5);
204 }
205 else
206 {
207 m_inset.cx = 2;
208 m_inset.cy = 2;
209 }
210
212 if (IsThemeActive())
213 {
214 m_hTheme = OpenThemeData(m_hWnd, L"Button");
215 if (m_hTheme != NULL)
217 }
218}
219
221{
222 RECT rc;
223 GetClientRect(&rc);
224
225 PAINTSTRUCT ps;
226 HDC hdc = BeginPaint(&ps);
227 OnDraw(hdc, &rc);
228 EndPaint(&ps);
229
230 return 0;
231}
232
234{
236 return 0;
237
238 RECT rc;
239 GetClientRect(&rc);
240
241 HDC hdc = (HDC)wParam;
242 OnDraw(hdc, &rc);
243
244 return 0;
245}
246
248{
249 if (!ppt || !IsWindow())
250 return FALSE;
251
252 RECT rc;
253 GetWindowRect(&rc);
255 ::InflateRect(&rc, max(cxEdge, 1), max(cyEdge, 1));
256
257 return m_bHorizontal
258 ? (ppt->x > rc.left)
259 : (ppt->y > rc.top);
260}
261
263{
264 if (m_bHovering)
265 return;
266
268 Invalidate(TRUE);
269
271
273}
274
276{
278 return 0;
279}
280
282{
284 return 0;
285
286 POINT pt;
288 if (!PtInButton(&pt)) // The end of hovering?
289 {
292 Invalidate(TRUE);
293
295 }
296
297 return 0;
298}
299
301{
302 if (m_hTheme)
303 {
305 m_hTheme = NULL;
306 }
308 {
311 }
312
313 return 0;
314}
315
317{
318 RECT rc = { prc->left, prc->top, prc->right, prc->bottom };
319 LPRECT lpRc = &rc;
320 HBRUSH hbrBackground = NULL;
321
322 if (m_hTheme)
323 {
324 HTHEME theme;
325 int part = 0;
326 int state = 0;
328 {
329 theme = m_hTheme;
330
331 if (m_bPressed)
333 else if (m_bHovering)
334 state = PBS_HOT;
335 else
337 }
338 else
339 {
340 part = TP_BUTTON;
341 theme = m_hFallbackTheme;
342
343 if (m_bPressed)
345 else if (m_bHovering)
346 state = TS_HOT;
347 else
349
350 if (m_bHorizontal)
351 rc.right -= m_inset.cx;
352 else
353 rc.bottom -= m_inset.cy;
354 }
355
358
359 ::DrawThemeBackground(theme, hdc, part, state, lpRc, lpRc);
360 }
361 else
362 {
365
366 if (m_bPressed || m_bHovering)
367 {
369 DrawEdge(hdc, lpRc, edge, BF_RECT);
370 }
371 }
372
374 {
375 /* Prepare to draw icon */
376
377 // Determine X-position of icon's top-left corner
378 int iconX = rc.left;
379 iconX += (rc.right - iconX) / 2;
380 iconX -= m_szIcon.cx / 2;
381
382 // Determine Y-position of icon's top-left corner
383 int iconY = rc.top;
384 iconY += (rc.bottom - iconY) / 2;
385 iconY -= m_szIcon.cy / 2;
386
387 // Ok now actually draw the icon itself
388 if (m_icon)
389 {
390 DrawIconEx(hdc, iconX, iconY,
391 m_icon, 0, 0,
393 }
394 }
395}
Arabic default style
Definition: afstyles.h:94
static int state
Definition: maze.c:121
@ Create
Definition: registry.c:563
HINSTANCE hExplorerInstance
Definition: explorer.cpp:24
#define IDS_TRAYDESKBTN_TOOLTIP
Definition: resource.h:108
BOOL AddTool(IN CONST TTTOOLINFOW *pInfo)
Definition: rosctrls.h:637
HWND Create(HWND hWndParent, DWORD dwStyles=WS_POPUP|TTS_NOPREFIX, DWORD dwExStyles=WS_EX_TOPMOST)
Definition: rosctrls.h:616
LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
VOID EnsureWindowTheme(BOOL setTheme)
LRESULT OnClick(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
LRESULT OnWindowPosChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
BOOL PtInButton(LPPOINT pt) const
HRESULT DoCreate(HWND hwndParent)
Definition: traydeskbtn.cpp:62
LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
LRESULT OnPrintClient(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
BOOL m_drawWithDedicatedBackground
Definition: traydeskbtn.h:28
VOID OnDraw(HDC hdc, LPRECT prc)
LRESULT OnThemeChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
LRESULT OnSettingChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
INT WidthOrHeight() const
Definition: traydeskbtn.cpp:33
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
static HWND hwndParent
Definition: cryptui.c:300
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HRESULT WINAPI DrawThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect)
Definition: draw.c:128
BOOL WINAPI IsThemeBackgroundPartiallyTransparent(HTHEME hTheme, int iPartId, int iStateId)
Definition: draw.c:1927
HRESULT WINAPI DrawThemeParentBackground(HWND hwnd, HDC hdc, RECT *prc)
Definition: draw.c:72
HRESULT WINAPI GetThemeMargins(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, RECT *prc, MARGINS *pMargins)
Definition: property.c:216
HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR classlist)
Definition: system.c:850
BOOL WINAPI IsThemePartDefined(HTHEME hTheme, int iPartId, int iStateId)
Definition: system.c:1002
HTHEME WINAPI GetWindowTheme(HWND hwnd)
Definition: system.c:866
BOOL WINAPI IsThemeActive(void)
Definition: system.c:621
HRESULT WINAPI CloseThemeData(HTHEME hTheme)
Definition: system.c:965
#define pt(x, y)
Definition: drawing.c:79
HBRUSH hbrBackground
Definition: enumwnd.c:12
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
UINT WINAPI ExtractIconExW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIcons)
Definition: iconcache.cpp:855
#define S_OK
Definition: intsafe.h:52
#define UINT_MAX
Definition: intsafe.h:152
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:88
static HTHEME(WINAPI *pOpenThemeDataEx)(HWND
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
_Out_ LPRECT prc
Definition: ntgdi.h:1658
#define L(x)
Definition: ntvdm.h:50
#define WS_CHILD
Definition: pedump.c:617
#define WS_POPUP
Definition: pedump.c:616
#define WS_VISIBLE
Definition: pedump.c:620
long LONG
Definition: pedump.c:60
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
#define BS_DEFPUSHBUTTON
Definition: pedump.c:652
#define TOOLINFOW
Definition: commctrl.h:1715
#define TTTOOLINFOW_V1_SIZE
Definition: commctrl.h:1721
#define TTF_IDISHWND
Definition: commctrl.h:1764
#define TTF_SUBCLASS
Definition: commctrl.h:1767
#define TTS_ALWAYSTIP
Definition: commctrl.h:1757
#define TTS_NOPREFIX
Definition: commctrl.h:1758
Definition: misc.c:279
int cyBottomHeight
Definition: misc.c:283
int cyTopHeight
Definition: misc.c:282
int cxRightWidth
Definition: misc.c:281
int cxLeftWidth
Definition: misc.c:280
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
#define max(a, b)
Definition: svc.c:63
#define SHOW_DESKTOP_TIMER_INTERVAL
Definition: traydeskbtn.cpp:18
#define IDI_SHELL32_DESKTOP
Definition: traydeskbtn.cpp:14
#define SHOW_DESKTOP_TIMER_ID
Definition: traydeskbtn.cpp:17
#define IDI_IMAGERES_DESKTOP
Definition: traydeskbtn.cpp:15
#define TSDB_CLICK
Definition: traydeskbtn.h:14
int32_t INT
Definition: typedefs.h:58
#define TRAYCMD_TOGGLE_DESKTOP
Definition: undocshell.h:907
HRESULT WINAPI SetWindowTheme(_In_ HWND hwnd, _In_ LPCWSTR pszSubAppName, _In_ LPCWSTR pszSubIdList)
Definition: uxthemesupp.c:69
@ TP_BUTTON
Definition: vsstyle.h:1394
@ PBS_PRESSED
Definition: vsstyle.h:88
@ PBS_NORMAL
Definition: vsstyle.h:86
@ PBS_HOT
Definition: vsstyle.h:87
@ BP_PUSHBUTTON
Definition: vsstyle.h:74
@ TS_PRESSED
Definition: vsstyle.h:1407
@ TS_NORMAL
Definition: vsstyle.h:1405
@ TS_HOT
Definition: vsstyle.h:1406
#define TMT_CONTENTMARGINS
Definition: vssym32.h:324
@ TNP_BACKGROUND
Definition: vssym32.h:543
int ret
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define DI_NORMAL
Definition: wingdi.h:72
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
HWND WINAPI SetCapture(_In_ HWND hWnd)
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define HCF_HIGHCONTRASTON
Definition: winuser.h:2137
#define BDR_SUNKENOUTER
Definition: winuser.h:443
#define SM_CYEDGE
Definition: winuser.h:1012
BOOL WINAPI ReleaseCapture(void)
Definition: message.c:2890
#define SM_CXEDGE
Definition: winuser.h:1011
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
HBRUSH WINAPI GetSysColorBrush(_In_ int)
#define WM_COMMAND
Definition: winuser.h:1743
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2756
#define SM_CYSMICON
Definition: winuser.h:1016
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
#define SM_CYBORDER
Definition: winuser.h:968
#define SM_CXSMICON
Definition: winuser.h:1015
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
BOOL WINAPI DrawEdge(_In_ HDC, _Inout_ LPRECT, _In_ UINT, _In_ UINT)
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
#define SM_CXBORDER
Definition: winuser.h:967
BOOL WINAPI DrawIconEx(_In_ HDC, _In_ int, _In_ int, _In_ HICON, _In_ int, _In_ int, _In_ UINT, _In_opt_ HBRUSH, _In_ UINT)
Definition: cursoricon.c:2114
#define BDR_RAISEDINNER
Definition: winuser.h:444
#define SendMessage
Definition: winuser.h:5855
LONG WINAPI GetMessageTime(void)
Definition: message.c:1361
#define PostMessage
Definition: winuser.h:5844
HWND WINAPI GetParent(_In_ HWND)
#define PRF_CHECKVISIBLE
Definition: winuser.h:2526
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
#define SystemParametersInfo
Definition: winuser.h:5870
BOOL WINAPI InflateRect(_Inout_ LPRECT, _In_ int, _In_ int)
#define BF_RECT
Definition: winuser.h:462
BOOL WINAPI IsWindowVisible(_In_ HWND)
int WINAPI GetSystemMetrics(_In_ int)
#define WM_NCPAINT
Definition: winuser.h:1690
#define COLOR_3DFACE
Definition: winuser.h:932