xref: /reactos/base/shell/explorer/trayprop.cpp (revision 9cfd8dd9)
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 
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 
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)
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 
100     ~CTaskBarSettingsPage()
101     {
102         if (m_hbmpTaskbar)
103             DeleteObject(m_hbmpTaskbar);
104     }
105 
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 
119     LRESULT OnCtrlCommand(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
120     {
121         _UpdateDialog();
122         SetModified(TRUE);
123         return 0;
124     }
125 
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 
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)
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 
199     ~CStartMenuSettingsPage()
200     {
201         if (m_hbmpStartBitmap)
202             DeleteObject(m_hbmpStartBitmap);
203     }
204 
205     LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
206     {
207         // fix me: start menu style (classic/modern) should be read somewhere from the registry.
208         CheckDlgButton(IDC_TASKBARPROP_STARTMENUCLASSIC, BST_CHECKED); // HACK: This has to be read from registry!!!!!!!
209         _UpdateDialog();
210 
211         return TRUE;
212     }
213 
214     LRESULT OnStartMenuCustomize(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
215     {
216         ShowCustomizeClassic(hExplorerInstance, m_hWnd);
217         return 0;
218     }
219 
220     int OnApply()
221     {
222         //TODO
223         return PSNRET_NOERROR;
224     }
225 };
226 
227 class CNotifySettingsPage : public CPropertyPageImpl<CNotifySettingsPage>
228 {
229 private:
230     HBITMAP m_hbmpTray;
231     HWND m_hwndTaskbar;
232 
233     void _UpdateDialog()
234     {
235         BOOL bShowClock = IsDlgButtonChecked(IDC_TASKBARPROP_CLOCK);
236         BOOL bShowSeconds = IsDlgButtonChecked(IDC_TASKBARPROP_SECONDS);
237         BOOL bHideInactive = IsDlgButtonChecked(IDC_TASKBARPROP_HIDEICONS);
238         UINT uImageId;
239 
240         HWND hwndCustomizeNotifyButton = GetDlgItem(IDC_TASKBARPROP_ICONCUST);
241         HWND hwndSeconds = GetDlgItem(IDC_TASKBARPROP_SECONDS);
242         HWND hwndTrayBitmap = GetDlgItem(IDC_TASKBARPROP_NOTIFICATIONBITMAP);
243 
244         ::EnableWindow(hwndCustomizeNotifyButton, bHideInactive);
245         ::EnableWindow(hwndSeconds, bShowClock);
246         if (!bShowSeconds)
247             CheckDlgButton(IDC_TASKBARPROP_SECONDS, BST_UNCHECKED);
248 
249         if (bHideInactive && bShowClock && bShowSeconds)
250             uImageId = IDB_SYSTRAYPROP_HIDE_SECONDS;
251         else if (bHideInactive && bShowClock && !bShowSeconds)
252             uImageId = IDB_SYSTRAYPROP_HIDE_CLOCK;
253         else if (bHideInactive && !bShowClock)
254             uImageId = IDB_SYSTRAYPROP_HIDE_NOCLOCK;
255         else if (!bHideInactive && bShowClock && bShowSeconds)
256             uImageId = IDB_SYSTRAYPROP_SHOW_SECONDS;
257         else if (!bHideInactive && bShowClock && !bShowSeconds)
258             uImageId = IDB_SYSTRAYPROP_SHOW_CLOCK;
259         else if (!bHideInactive && !bShowClock)
260             uImageId = IDB_SYSTRAYPROP_SHOW_NOCLOCK;
261 
262         SetBitmap(hwndTrayBitmap, &m_hbmpTray, uImageId);
263     }
264 
265 public:
266     enum { IDD = IDD_TASKBARPROP_NOTIFY };
267 
268     BEGIN_MSG_MAP(CNotifySettingsPage)
269         MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
270         COMMAND_ID_HANDLER(IDC_TASKBARPROP_ICONCUST, OnCustomizeTrayIcons)
271         COMMAND_RANGE_HANDLER(IDC_TASKBARPROP_NOTIFY_FIRST_CMD, IDC_TASKBARPROP_NOTIFY_LAST_CMD, OnCtrlCommand)
272         CHAIN_MSG_MAP(CPropertyPageImpl<CNotifySettingsPage>)
273     END_MSG_MAP()
274 
275     CNotifySettingsPage(HWND hwnd):
276         m_hbmpTray(NULL),
277         m_hwndTaskbar(hwnd)
278     {
279     }
280 
281     ~CNotifySettingsPage()
282     {
283         if (m_hbmpTray)
284             DeleteObject(m_hbmpTray);
285     }
286 
287     LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
288     {
289         CheckDlgButton(IDC_TASKBARPROP_CLOCK, (!g_TaskbarSettings.sr.HideClock) ? BST_CHECKED : BST_UNCHECKED);
290         CheckDlgButton(IDC_TASKBARPROP_SECONDS, g_TaskbarSettings.bShowSeconds ? BST_CHECKED : BST_UNCHECKED);
291         CheckDlgButton(IDC_TASKBARPROP_HIDEICONS, g_TaskbarSettings.bHideInactiveIcons ? BST_CHECKED : BST_UNCHECKED);
292         CheckDlgButton(IDC_TASKBARPROP_DESKTOP, g_TaskbarSettings.bShowDesktopButton ? BST_CHECKED : BST_UNCHECKED);
293 
294         _UpdateDialog();
295         return TRUE;
296     }
297 
298     LRESULT OnCustomizeTrayIcons(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
299     {
300         ShowCustomizeNotifyIcons(hExplorerInstance, m_hWnd);
301         return 0;
302     }
303 
304     LRESULT OnCtrlCommand(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
305     {
306         _UpdateDialog();
307         SetModified(TRUE);
308         return 0;
309     }
310 
311     int OnApply()
312     {
313         TaskbarSettings newSettings = g_TaskbarSettings;
314 
315         newSettings.sr.HideClock = !IsDlgButtonChecked(IDC_TASKBARPROP_CLOCK);
316         newSettings.bShowSeconds = IsDlgButtonChecked(IDC_TASKBARPROP_SECONDS);
317         newSettings.bHideInactiveIcons = IsDlgButtonChecked(IDC_TASKBARPROP_HIDEICONS);
318         newSettings.bShowDesktopButton = IsDlgButtonChecked(IDC_TASKBARPROP_DESKTOP);
319 
320         SendMessage(m_hwndTaskbar, TWM_SETTINGSCHANGED, 0, (LPARAM)&newSettings);
321 
322         return PSNRET_NOERROR;
323     }
324 };
325 
326 static int CALLBACK
327 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam)
328 {
329     // NOTE: This callback is needed to set large icon correctly.
330     HICON hIcon;
331     switch (uMsg)
332     {
333         case PSCB_INITIALIZED:
334         {
335             hIcon = LoadIconW(hExplorerInstance, MAKEINTRESOURCEW(IDI_STARTMENU));
336             SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
337             break;
338         }
339     }
340     return 0;
341 }
342 
343 VOID
344 DisplayTrayProperties(IN HWND hwndOwner, IN HWND hwndTaskbar)
345 {
346     PROPSHEETHEADER psh;
347     CSimpleArray<HPROPSHEETPAGE> hpsp;
348     CTaskBarSettingsPage tbSettingsPage(hwndTaskbar);
349     CStartMenuSettingsPage smSettingsPage;
350     CNotifySettingsPage naSettingsPage(hwndTaskbar);
351     CStringW caption;
352 
353     caption.LoadStringW(IDS_TASKBAR_STARTMENU_PROP_CAPTION);
354 
355     hpsp.Add(tbSettingsPage.Create());
356     hpsp.Add(smSettingsPage.Create());
357     hpsp.Add(naSettingsPage.Create());
358 
359     ZeroMemory(&psh, sizeof(psh));
360     psh.dwSize = sizeof(psh);
361     psh.dwFlags =  PSH_PROPTITLE | PSH_USEICONID | PSH_USECALLBACK;
362     psh.hwndParent = hwndOwner;
363     psh.hInstance = hExplorerInstance;
364     psh.pszIcon = MAKEINTRESOURCEW(IDI_STARTMENU);
365     psh.pszCaption = caption.GetString();
366     psh.nPages = hpsp.GetSize();
367     psh.nStartPage = 0;
368     psh.phpage = hpsp.GetData();
369     psh.pfnCallback = PropSheetProc;
370 
371     PropertySheet(&psh);
372 }
373