xref: /reactos/base/shell/explorer/trayprop.cpp (revision 71a3be24)
1 /*
2  * ReactOS Explorer
3  *
4  * Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
5  *                  2015 Robert Naumann <gonzomdx@gmail.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21 
22 #include "precomp.h"
23 
SetBitmap(HWND hwnd,HBITMAP * hbmp,UINT uImageId)24 static void SetBitmap(HWND hwnd, HBITMAP* hbmp, UINT uImageId)
25 {
26     if (*hbmp)
27         DeleteObject(*hbmp);
28 
29     *hbmp = (HBITMAP)LoadImageW(hExplorerInstance,
30                                 MAKEINTRESOURCEW(uImageId),
31                                 IMAGE_BITMAP,
32                                 0,
33                                 0,
34                                 LR_DEFAULTCOLOR);
35 
36     if (*hbmp && hwnd)
37     {
38         BITMAP bm;
39         GetObject(*hbmp, sizeof(bm), &bm);
40         ::SetWindowPos(hwnd, NULL, 0, 0, bm.bmWidth + 2, bm.bmHeight + 2,
41                        SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
42         SendMessage(hwnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)*hbmp);
43     }
44 
45 }
46 
47 class CTaskBarSettingsPage : public CPropertyPageImpl<CTaskBarSettingsPage>
48 {
49 private:
50     HBITMAP m_hbmpTaskbar;
51     HWND m_hwndTaskbar;
52 
_UpdateDialog()53     void _UpdateDialog()
54     {
55         BOOL bLock = IsDlgButtonChecked(IDC_TASKBARPROP_LOCK);
56         BOOL bHide = IsDlgButtonChecked(IDC_TASKBARPROP_HIDE);
57         BOOL bGroup = IsDlgButtonChecked(IDC_TASKBARPROP_GROUP);
58         BOOL bShowQL = IsDlgButtonChecked(IDC_TASKBARPROP_SHOWQL);
59         UINT uImageId;
60 
61         HWND hwndTaskbarBitmap = GetDlgItem(IDC_TASKBARPROP_TASKBARBITMAP);
62 
63         if (bHide)
64             uImageId = IDB_TASKBARPROP_AUTOHIDE;
65         else if (bLock  && bGroup  && bShowQL)
66             uImageId = IDB_TASKBARPROP_LOCK_GROUP_QL;
67         else if (bLock  && !bGroup && !bShowQL)
68             uImageId = IDB_TASKBARPROP_LOCK_NOGROUP_NOQL;
69         else if (bLock  && bGroup  && !bShowQL)
70             uImageId = IDB_TASKBARPROP_LOCK_GROUP_NOQL;
71         else if (bLock  && !bGroup && bShowQL)
72             uImageId = IDB_TASKBARPROP_LOCK_NOGROUP_QL;
73         else if (!bLock && !bGroup && !bShowQL)
74             uImageId = IDB_TASKBARPROP_NOLOCK_NOGROUP_NOQL;
75         else if (!bLock && bGroup  && !bShowQL)
76             uImageId = IDB_TASKBARPROP_NOLOCK_GROUP_NOQL;
77         else if (!bLock && !bGroup && bShowQL)
78             uImageId = IDB_TASKBARPROP_NOLOCK_NOGROUP_QL;
79         else if (!bLock && bGroup  && bShowQL)
80             uImageId = IDB_TASKBARPROP_NOLOCK_GROUP_QL;
81 
82         SetBitmap(hwndTaskbarBitmap, &m_hbmpTaskbar, uImageId);
83     }
84 
85 public:
86     enum { IDD = IDD_TASKBARPROP_TASKBAR };
87 
88     BEGIN_MSG_MAP(CTaskBarSettingsPage)
MESSAGE_HANDLER(WM_INITDIALOG,OnInitDialog)89         MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
90         COMMAND_RANGE_HANDLER(IDC_TASKBARPROP_FIRST_CMD, IDC_TASKBARPROP_LAST_CMD, OnCtrlCommand)
91         CHAIN_MSG_MAP(CPropertyPageImpl<CTaskBarSettingsPage>)
92     END_MSG_MAP()
93 
94     CTaskBarSettingsPage(HWND hwnd):
95         m_hbmpTaskbar(NULL),
96         m_hwndTaskbar(hwnd)
97     {
98     }
99 
~CTaskBarSettingsPage()100     ~CTaskBarSettingsPage()
101     {
102         if (m_hbmpTaskbar)
103             DeleteObject(m_hbmpTaskbar);
104     }
105 
OnInitDialog(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)106     LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
107     {
108         CheckDlgButton(IDC_TASKBARPROP_LOCK, g_TaskbarSettings.bLock ? BST_CHECKED : BST_UNCHECKED);
109         CheckDlgButton(IDC_TASKBARPROP_HIDE, g_TaskbarSettings.sr.AutoHide ? BST_CHECKED : BST_UNCHECKED);
110         CheckDlgButton(IDC_TASKBARPROP_ONTOP, g_TaskbarSettings.sr.AlwaysOnTop ? BST_CHECKED : BST_UNCHECKED);
111         CheckDlgButton(IDC_TASKBARPROP_GROUP, g_TaskbarSettings.bGroupButtons ? BST_CHECKED : BST_UNCHECKED);
112         //CheckDlgButton(IDC_TASKBARPROP_SHOWQL, g_TaskbarSettings.bShowQuickLaunch ? BST_CHECKED : BST_UNCHECKED);
113         CheckDlgButton(IDC_TASKBARPROP_SMALLICONS, g_TaskbarSettings.bSmallIcons ? BST_CHECKED : BST_UNCHECKED);
114 
115         _UpdateDialog();
116         return TRUE;
117     }
118 
OnCtrlCommand(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)119     LRESULT OnCtrlCommand(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
120     {
121         _UpdateDialog();
122         SetModified(TRUE);
123         return 0;
124     }
125 
OnApply()126     int OnApply()
127     {
128         TaskbarSettings newSettings = g_TaskbarSettings;
129 
130         newSettings.bLock = IsDlgButtonChecked(IDC_TASKBARPROP_LOCK);
131         newSettings.sr.AutoHide = IsDlgButtonChecked(IDC_TASKBARPROP_HIDE);
132         newSettings.sr.AlwaysOnTop = IsDlgButtonChecked(IDC_TASKBARPROP_ONTOP);
133         newSettings.bGroupButtons = IsDlgButtonChecked(IDC_TASKBARPROP_GROUP);
134         //newSettings.bShowQuickLaunch = IsDlgButtonChecked(IDC_TASKBARPROP_SHOWQL);
135         newSettings.bSmallIcons = IsDlgButtonChecked(IDC_TASKBARPROP_SMALLICONS);
136 
137         SendMessage(m_hwndTaskbar, TWM_SETTINGSCHANGED, 0, (LPARAM)&newSettings);
138 
139         return PSNRET_NOERROR;
140     }
141 };
142 
143 class CStartMenuSettingsPage : public CPropertyPageImpl<CStartMenuSettingsPage>
144 {
145 private:
146     HBITMAP m_hbmpStartBitmap;
147 
_UpdateDialog()148     void _UpdateDialog()
149     {
150         HWND hwndCustomizeClassic = GetDlgItem(IDC_TASKBARPROP_STARTMENUCLASSICCUST);
151         HWND hwndCustomizeModern = GetDlgItem(IDC_TASKBARPROP_STARTMENUCUST);
152         HWND hwndStartBitmap = GetDlgItem(IDC_TASKBARPROP_STARTMENU_BITMAP);
153         HWND hwndModernRadioBtn = GetDlgItem(IDC_TASKBARPROP_STARTMENU);
154         HWND hwndModernText = GetDlgItem(IDC_TASKBARPROP_STARTMENUMODERNTEXT);
155         BOOL policyNoSimpleStartMenu = SHRestricted(REST_NOSTARTPANEL) != 0;
156         BOOL bModern = FALSE;
157 
158         /* If NoSimpleStartMenu, disable ability to use Modern Start Menu */
159         if (policyNoSimpleStartMenu)
160         {
161             /* Switch to classic */
162             CheckDlgButton(IDC_TASKBARPROP_STARTMENUCLASSIC, BST_CHECKED);
163 
164             /* Disable radio button */
165             ::EnableWindow(hwndModernRadioBtn, FALSE);
166 
167             /* Hide controls related to modern menu */
168             ::ShowWindow(hwndModernRadioBtn, SW_HIDE);
169             ::ShowWindow(hwndModernText, SW_HIDE);
170             ::ShowWindow(hwndCustomizeModern, SW_HIDE);
171         }
172         /* If no restrictions, then get bModern from dialog */
173         else
174         {
175             bModern = IsDlgButtonChecked(IDC_TASKBARPROP_STARTMENU);
176         }
177 
178         ::EnableWindow(hwndCustomizeModern, bModern);
179         ::EnableWindow(hwndCustomizeClassic, !bModern);
180 
181         UINT uImageId = bModern ? IDB_STARTPREVIEW : IDB_STARTPREVIEW_CLASSIC;
182         SetBitmap(hwndStartBitmap, &m_hbmpStartBitmap, uImageId);
183     }
184 
185 public:
186     enum { IDD = IDD_TASKBARPROP_STARTMENU };
187 
188     BEGIN_MSG_MAP(CTaskBarSettingsPage)
MESSAGE_HANDLER(WM_INITDIALOG,OnInitDialog)189         MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
190         COMMAND_ID_HANDLER(IDC_TASKBARPROP_STARTMENUCLASSICCUST, OnStartMenuCustomize)
191         CHAIN_MSG_MAP(CPropertyPageImpl<CStartMenuSettingsPage>)
192     END_MSG_MAP()
193 
194     CStartMenuSettingsPage():
195         m_hbmpStartBitmap(NULL)
196     {
197     }
198 
~CStartMenuSettingsPage()199     ~CStartMenuSettingsPage()
200     {
201         if (m_hbmpStartBitmap)
202             DeleteObject(m_hbmpStartBitmap);
203     }
204 
OnInitDialog(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)205     LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
206     {
207         BOOL modern = SHELL_GetSetting(SSF_STARTPANELON, fStartPanelOn);
208         CheckDlgButton(modern ? IDC_TASKBARPROP_STARTMENU : IDC_TASKBARPROP_STARTMENUCLASSIC, BST_CHECKED);
209         _UpdateDialog();
210         return TRUE;
211     }
212 
OnStartMenuCustomize(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)213     LRESULT OnStartMenuCustomize(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
214     {
215         ShowCustomizeClassic(hExplorerInstance, m_hWnd);
216         return 0;
217     }
218 
OnApply()219     int OnApply()
220     {
221         SHELLSTATE ss;
222         ss.fStartPanelOn = !IsDlgButtonChecked(IDC_TASKBARPROP_STARTMENUCLASSIC);
223         SHGetSetSettings(&ss, SSF_STARTPANELON, TRUE);
224         return PSNRET_NOERROR;
225     }
226 };
227 
228 class CNotifySettingsPage : public CPropertyPageImpl<CNotifySettingsPage>
229 {
230 private:
231     HBITMAP m_hbmpTray;
232     HWND m_hwndTaskbar;
233 
_UpdateDialog()234     void _UpdateDialog()
235     {
236         BOOL bShowClock = IsDlgButtonChecked(IDC_TASKBARPROP_CLOCK);
237         BOOL bShowSeconds = IsDlgButtonChecked(IDC_TASKBARPROP_SECONDS);
238         BOOL bHideInactive = IsDlgButtonChecked(IDC_TASKBARPROP_HIDEICONS);
239         UINT uImageId;
240 
241         HWND hwndCustomizeNotifyButton = GetDlgItem(IDC_TASKBARPROP_ICONCUST);
242         HWND hwndSeconds = GetDlgItem(IDC_TASKBARPROP_SECONDS);
243         HWND hwndTrayBitmap = GetDlgItem(IDC_TASKBARPROP_NOTIFICATIONBITMAP);
244 
245         ::EnableWindow(hwndCustomizeNotifyButton, bHideInactive);
246         ::EnableWindow(hwndSeconds, bShowClock);
247         if (!bShowSeconds)
248             CheckDlgButton(IDC_TASKBARPROP_SECONDS, BST_UNCHECKED);
249 
250         if (bHideInactive && bShowClock && bShowSeconds)
251             uImageId = IDB_SYSTRAYPROP_HIDE_SECONDS;
252         else if (bHideInactive && bShowClock && !bShowSeconds)
253             uImageId = IDB_SYSTRAYPROP_HIDE_CLOCK;
254         else if (bHideInactive && !bShowClock)
255             uImageId = IDB_SYSTRAYPROP_HIDE_NOCLOCK;
256         else if (!bHideInactive && bShowClock && bShowSeconds)
257             uImageId = IDB_SYSTRAYPROP_SHOW_SECONDS;
258         else if (!bHideInactive && bShowClock && !bShowSeconds)
259             uImageId = IDB_SYSTRAYPROP_SHOW_CLOCK;
260         else if (!bHideInactive && !bShowClock)
261             uImageId = IDB_SYSTRAYPROP_SHOW_NOCLOCK;
262 
263         SetBitmap(hwndTrayBitmap, &m_hbmpTray, uImageId);
264     }
265 
266 public:
267     enum { IDD = IDD_TASKBARPROP_NOTIFY };
268 
269     BEGIN_MSG_MAP(CNotifySettingsPage)
MESSAGE_HANDLER(WM_INITDIALOG,OnInitDialog)270         MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
271         COMMAND_ID_HANDLER(IDC_TASKBARPROP_ICONCUST, OnCustomizeTrayIcons)
272         COMMAND_RANGE_HANDLER(IDC_TASKBARPROP_NOTIFY_FIRST_CMD, IDC_TASKBARPROP_NOTIFY_LAST_CMD, OnCtrlCommand)
273         CHAIN_MSG_MAP(CPropertyPageImpl<CNotifySettingsPage>)
274     END_MSG_MAP()
275 
276     CNotifySettingsPage(HWND hwnd):
277         m_hbmpTray(NULL),
278         m_hwndTaskbar(hwnd)
279     {
280     }
281 
~CNotifySettingsPage()282     ~CNotifySettingsPage()
283     {
284         if (m_hbmpTray)
285             DeleteObject(m_hbmpTray);
286     }
287 
OnInitDialog(UINT uMsg,WPARAM wParam,LPARAM lParam,BOOL & bHandled)288     LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
289     {
290         CheckDlgButton(IDC_TASKBARPROP_CLOCK, (!g_TaskbarSettings.sr.HideClock) ? BST_CHECKED : BST_UNCHECKED);
291         CheckDlgButton(IDC_TASKBARPROP_SECONDS, g_TaskbarSettings.bShowSeconds ? BST_CHECKED : BST_UNCHECKED);
292         CheckDlgButton(IDC_TASKBARPROP_HIDEICONS, g_TaskbarSettings.bHideInactiveIcons ? BST_CHECKED : BST_UNCHECKED);
293         CheckDlgButton(IDC_TASKBARPROP_DESKTOP, g_TaskbarSettings.bShowDesktopButton ? BST_CHECKED : BST_UNCHECKED);
294 
295         _UpdateDialog();
296         return TRUE;
297     }
298 
OnCustomizeTrayIcons(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)299     LRESULT OnCustomizeTrayIcons(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
300     {
301         ShowCustomizeNotifyIcons(hExplorerInstance, m_hWnd);
302         return 0;
303     }
304 
OnCtrlCommand(WORD wNotifyCode,WORD wID,HWND hWndCtl,BOOL & bHandled)305     LRESULT OnCtrlCommand(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
306     {
307         _UpdateDialog();
308         SetModified(TRUE);
309         return 0;
310     }
311 
OnApply()312     int OnApply()
313     {
314         TaskbarSettings newSettings = g_TaskbarSettings;
315 
316         newSettings.sr.HideClock = !IsDlgButtonChecked(IDC_TASKBARPROP_CLOCK);
317         newSettings.bShowSeconds = IsDlgButtonChecked(IDC_TASKBARPROP_SECONDS);
318         newSettings.bHideInactiveIcons = IsDlgButtonChecked(IDC_TASKBARPROP_HIDEICONS);
319         newSettings.bShowDesktopButton = IsDlgButtonChecked(IDC_TASKBARPROP_DESKTOP);
320 
321         SendMessage(m_hwndTaskbar, TWM_SETTINGSCHANGED, 0, (LPARAM)&newSettings);
322 
323         return PSNRET_NOERROR;
324     }
325 };
326 
327 static int CALLBACK
PropSheetProc(HWND hwndDlg,UINT uMsg,LPARAM lParam)328 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam)
329 {
330     // NOTE: This callback is needed to set large icon correctly.
331     HICON hIcon;
332     switch (uMsg)
333     {
334         case PSCB_INITIALIZED:
335         {
336             hIcon = LoadIconW(hExplorerInstance, MAKEINTRESOURCEW(IDI_STARTMENU));
337             SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
338             break;
339         }
340     }
341     return 0;
342 }
343 
344 VOID
DisplayTrayProperties(IN HWND hwndOwner,IN HWND hwndTaskbar)345 DisplayTrayProperties(IN HWND hwndOwner, IN HWND hwndTaskbar)
346 {
347     PROPSHEETHEADER psh;
348     CSimpleArray<HPROPSHEETPAGE> hpsp;
349     CTaskBarSettingsPage tbSettingsPage(hwndTaskbar);
350     CStartMenuSettingsPage smSettingsPage;
351     CNotifySettingsPage naSettingsPage(hwndTaskbar);
352     CStringW caption;
353 
354     caption.LoadStringW(IDS_TASKBAR_STARTMENU_PROP_CAPTION);
355 
356     hpsp.Add(tbSettingsPage.Create());
357     hpsp.Add(smSettingsPage.Create());
358     hpsp.Add(naSettingsPage.Create());
359 
360     ZeroMemory(&psh, sizeof(psh));
361     psh.dwSize = sizeof(psh);
362     psh.dwFlags =  PSH_PROPTITLE | PSH_USEICONID | PSH_USECALLBACK;
363     psh.hwndParent = hwndOwner;
364     psh.hInstance = hExplorerInstance;
365     psh.pszIcon = MAKEINTRESOURCEW(IDI_STARTMENU);
366     psh.pszCaption = caption.GetString();
367     psh.nPages = hpsp.GetSize();
368     psh.nStartPage = 0;
369     psh.phpage = hpsp.GetData();
370     psh.pfnCallback = PropSheetProc;
371 
372     PropertySheet(&psh);
373 }
374