xref: /reactos/base/shell/explorer/trayprop.cpp (revision b5218987)
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     HBITMAP m_hbmpTray;
52     HWND m_hwndTaskbar;
53 
54     void UpdateDialog()
55     {
56         BOOL bLock = IsDlgButtonChecked(IDC_TASKBARPROP_LOCK);
57         BOOL bHide = IsDlgButtonChecked(IDC_TASKBARPROP_HIDE);
58         BOOL bGroup = IsDlgButtonChecked(IDC_TASKBARPROP_GROUP);
59         BOOL bShowQL = IsDlgButtonChecked(IDC_TASKBARPROP_SHOWQL);
60         BOOL bShowClock = IsDlgButtonChecked(IDC_TASKBARPROP_CLOCK);
61         BOOL bShowSeconds = IsDlgButtonChecked(IDC_TASKBARPROP_SECONDS);
62         BOOL bHideInactive = IsDlgButtonChecked(IDC_TASKBARPROP_HIDEICONS);
63         UINT uImageId;
64 
65         HWND hwndCustomizeNotifyButton = GetDlgItem(IDC_TASKBARPROP_ICONCUST);
66         HWND hwndSeconds = GetDlgItem(IDC_TASKBARPROP_SECONDS);
67         HWND hwndTaskbarBitmap = GetDlgItem(IDC_TASKBARPROP_TASKBARBITMAP);
68         HWND hwndTrayBitmap = GetDlgItem(IDC_TASKBARPROP_NOTIFICATIONBITMAP);
69 
70         if (bHide)
71             uImageId = IDB_TASKBARPROP_AUTOHIDE;
72         else if (bLock  && bGroup  && bShowQL)
73             uImageId = IDB_TASKBARPROP_LOCK_GROUP_QL;
74         else if (bLock  && !bGroup && !bShowQL)
75             uImageId = IDB_TASKBARPROP_LOCK_NOGROUP_NOQL;
76         else if (bLock  && bGroup  && !bShowQL)
77             uImageId = IDB_TASKBARPROP_LOCK_GROUP_NOQL;
78         else if (bLock  && !bGroup && bShowQL)
79             uImageId = IDB_TASKBARPROP_LOCK_NOGROUP_QL;
80         else if (!bLock && !bGroup && !bShowQL)
81             uImageId = IDB_TASKBARPROP_NOLOCK_NOGROUP_NOQL;
82         else if (!bLock && bGroup  && !bShowQL)
83             uImageId = IDB_TASKBARPROP_NOLOCK_GROUP_NOQL;
84         else if (!bLock && !bGroup && bShowQL)
85             uImageId = IDB_TASKBARPROP_NOLOCK_NOGROUP_QL;
86         else if (!bLock && bGroup  && bShowQL)
87             uImageId = IDB_TASKBARPROP_NOLOCK_GROUP_QL;
88         else
89             ASSERT(FALSE);
90 
91         SetBitmap(hwndTaskbarBitmap, &m_hbmpTaskbar, uImageId);
92 
93         ::EnableWindow(hwndCustomizeNotifyButton, bHideInactive);
94         ::EnableWindow(hwndSeconds, bShowClock);
95         if (!bShowSeconds)
96             CheckDlgButton(IDC_TASKBARPROP_SECONDS, BST_UNCHECKED);
97 
98         if (bHideInactive && bShowClock && bShowSeconds)
99             uImageId = IDB_SYSTRAYPROP_HIDE_SECONDS;
100         else if (bHideInactive && bShowClock && !bShowSeconds)
101             uImageId = IDB_SYSTRAYPROP_HIDE_CLOCK;
102         else if (bHideInactive && !bShowClock)
103             uImageId = IDB_SYSTRAYPROP_HIDE_NOCLOCK;
104         else if (!bHideInactive && bShowClock && bShowSeconds)
105             uImageId = IDB_SYSTRAYPROP_SHOW_SECONDS;
106         else if (!bHideInactive && bShowClock && !bShowSeconds)
107             uImageId = IDB_SYSTRAYPROP_SHOW_CLOCK;
108         else if (!bHideInactive && !bShowClock)
109             uImageId = IDB_SYSTRAYPROP_SHOW_NOCLOCK;
110         else
111             ASSERT(FALSE);
112 
113         SetBitmap(hwndTrayBitmap, &m_hbmpTray, uImageId);
114     }
115 
116 public:
117     enum { IDD = IDD_TASKBARPROP_TASKBAR };
118 
119     BEGIN_MSG_MAP(CTaskBarSettingsPage)
120         MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
121         COMMAND_ID_HANDLER(IDC_TASKBARPROP_ICONCUST, OnCustomizeTrayIcons)
122         COMMAND_RANGE_HANDLER(IDC_TASKBARPROP_FIRST_CMD, IDC_TASKBARPROP_LAST_CMD, OnCtrlCommand)
123         CHAIN_MSG_MAP(CPropertyPageImpl<CTaskBarSettingsPage>)
124     END_MSG_MAP()
125 
126     CTaskBarSettingsPage(HWND hwnd):
127         m_hbmpTaskbar(NULL),
128         m_hbmpTray(NULL),
129         m_hwndTaskbar(hwnd)
130     {
131     }
132 
133     ~CTaskBarSettingsPage()
134     {
135         if (m_hbmpTaskbar)
136             DeleteObject(m_hbmpTaskbar);
137         if (m_hbmpTray)
138             DeleteObject(m_hbmpTray);
139     }
140 
141     LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
142     {
143         CheckDlgButton(IDC_TASKBARPROP_LOCK, g_TaskbarSettings.bLock ? BST_CHECKED : BST_UNCHECKED);
144         CheckDlgButton(IDC_TASKBARPROP_HIDE, g_TaskbarSettings.sr.AutoHide ? BST_CHECKED : BST_UNCHECKED);
145         CheckDlgButton(IDC_TASKBARPROP_ONTOP, g_TaskbarSettings.sr.AlwaysOnTop ? BST_CHECKED : BST_UNCHECKED);
146         CheckDlgButton(IDC_TASKBARPROP_GROUP, g_TaskbarSettings.bGroupButtons ? BST_CHECKED : BST_UNCHECKED);
147         //CheckDlgButton(IDC_TASKBARPROP_SHOWQL, g_TaskbarSettings.bShowQuickLaunch ? BST_CHECKED : BST_UNCHECKED);
148         CheckDlgButton(IDC_TASKBARPROP_CLOCK, (!g_TaskbarSettings.sr.HideClock) ? BST_CHECKED : BST_UNCHECKED);
149         CheckDlgButton(IDC_TASKBARPROP_SECONDS, g_TaskbarSettings.bShowSeconds ? BST_CHECKED : BST_UNCHECKED);
150         CheckDlgButton(IDC_TASKBARPROP_HIDEICONS, g_TaskbarSettings.bHideInactiveIcons ? BST_CHECKED : BST_UNCHECKED);
151 
152         UpdateDialog();
153         return TRUE;
154     }
155 
156     LRESULT OnCustomizeTrayIcons(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
157     {
158         ShowCustomizeNotifyIcons(hExplorerInstance, m_hWnd);
159         return 0;
160     }
161 
162     LRESULT OnCtrlCommand(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
163     {
164         UpdateDialog();
165         SetModified(TRUE);
166         return 0;
167     }
168 
169     int OnApply()
170     {
171         TaskbarSettings newSettings;
172         memcpy(&newSettings, &g_TaskbarSettings, sizeof(TaskbarSettings));
173 
174         newSettings.bLock = IsDlgButtonChecked(IDC_TASKBARPROP_LOCK);
175         newSettings.sr.AutoHide = IsDlgButtonChecked(IDC_TASKBARPROP_HIDE);
176         newSettings.sr.AlwaysOnTop = IsDlgButtonChecked(IDC_TASKBARPROP_ONTOP);
177         newSettings.bGroupButtons = IsDlgButtonChecked(IDC_TASKBARPROP_GROUP);
178         //newSettings.bShowQuickLaunch = IsDlgButtonChecked(IDC_TASKBARPROP_SHOWQL);
179         newSettings.sr.HideClock = !IsDlgButtonChecked(IDC_TASKBARPROP_CLOCK);
180         newSettings.bShowSeconds = IsDlgButtonChecked(IDC_TASKBARPROP_SECONDS);
181         newSettings.bHideInactiveIcons = IsDlgButtonChecked(IDC_TASKBARPROP_HIDEICONS);
182 
183         SendMessage(m_hwndTaskbar, TWM_SETTINGSCHANGED, 0, (LPARAM)&newSettings);
184 
185         return PSNRET_NOERROR;
186     }
187 };
188 
189 class CStartMenuSettingsPage : public CPropertyPageImpl<CStartMenuSettingsPage>
190 {
191 private:
192     HBITMAP m_hbmpStartBitmap;
193 
194     void UpdateDialog()
195     {
196         HWND hwndCustomizeClassic = GetDlgItem(IDC_TASKBARPROP_STARTMENUCLASSICCUST);
197         HWND hwndCustomizeModern = GetDlgItem(IDC_TASKBARPROP_STARTMENUCUST);
198         HWND hwndStartBitmap = GetDlgItem(IDC_TASKBARPROP_STARTMENU_BITMAP);
199         HWND hwndModernRadioBtn = GetDlgItem(IDC_TASKBARPROP_STARTMENU);
200         HWND hwndModernText = GetDlgItem(IDC_TASKBARPROP_STARTMENUMODERNTEXT);
201         BOOL policyNoSimpleStartMenu = SHRestricted(REST_NOSTARTPANEL) != 0;
202         BOOL bModern = FALSE;
203 
204         /* If NoSimpleStartMenu, disable ability to use Modern Start Menu */
205         if (policyNoSimpleStartMenu)
206         {
207             /* Switch to classic */
208             CheckDlgButton(IDC_TASKBARPROP_STARTMENUCLASSIC, BST_CHECKED);
209 
210             /* Disable radio button */
211             ::EnableWindow(hwndModernRadioBtn, FALSE);
212 
213             /* Hide controls related to modern menu */
214             ::ShowWindow(hwndModernRadioBtn, SW_HIDE);
215             ::ShowWindow(hwndModernText, SW_HIDE);
216             ::ShowWindow(hwndCustomizeModern, SW_HIDE);
217         }
218         /* If no restrictions, then get bModern from dialog */
219         else
220         {
221             bModern = IsDlgButtonChecked(IDC_TASKBARPROP_STARTMENU);
222         }
223 
224         ::EnableWindow(hwndCustomizeModern, bModern);
225         ::EnableWindow(hwndCustomizeClassic, !bModern);
226 
227         UINT uImageId = bModern ? IDB_STARTPREVIEW : IDB_STARTPREVIEW_CLASSIC;
228         SetBitmap(hwndStartBitmap, &m_hbmpStartBitmap, uImageId);
229     }
230 
231 public:
232     enum { IDD = IDD_TASKBARPROP_STARTMENU };
233 
234     BEGIN_MSG_MAP(CTaskBarSettingsPage)
235         MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
236         COMMAND_ID_HANDLER(IDC_TASKBARPROP_STARTMENUCLASSICCUST, OnStartMenuCustomize)
237         CHAIN_MSG_MAP(CPropertyPageImpl<CStartMenuSettingsPage>)
238     END_MSG_MAP()
239 
240     CStartMenuSettingsPage():
241         m_hbmpStartBitmap(NULL)
242     {
243     }
244 
245     ~CStartMenuSettingsPage()
246     {
247         if (m_hbmpStartBitmap)
248             DeleteObject(m_hbmpStartBitmap);
249     }
250 
251     LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
252     {
253         // fix me: start menu style (classic/modern) should be read somewhere from the registry.
254         CheckDlgButton(IDC_TASKBARPROP_STARTMENUCLASSIC, BST_CHECKED); // HACK: This has to be read from registry!!!!!!!
255         UpdateDialog();
256 
257         return TRUE;
258     }
259 
260     LRESULT OnStartMenuCustomize(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
261     {
262         ShowCustomizeClassic(hExplorerInstance, m_hWnd);
263         return 0;
264     }
265 
266     int OnApply()
267     {
268         //TODO
269         return PSNRET_NOERROR;
270     }
271 };
272 
273 static int CALLBACK
274 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam)
275 {
276     // NOTE: This callback is needed to set large icon correctly.
277     HICON hIcon;
278     switch (uMsg)
279     {
280         case PSCB_INITIALIZED:
281         {
282             hIcon = LoadIconW(hExplorerInstance, MAKEINTRESOURCEW(IDI_STARTMENU));
283             SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
284             break;
285         }
286     }
287     return 0;
288 }
289 
290 VOID
291 DisplayTrayProperties(IN HWND hwndOwner, IN HWND hwndTaskbar)
292 {
293     PROPSHEETHEADER psh;
294     HPROPSHEETPAGE hpsp[2];
295     CTaskBarSettingsPage tbSettingsPage(hwndTaskbar);
296     CStartMenuSettingsPage smSettingsPage;
297     CStringW caption;
298 
299     caption.LoadStringW(IDS_TASKBAR_STARTMENU_PROP_CAPTION);
300 
301     hpsp[0] = tbSettingsPage.Create();
302     hpsp[1] = smSettingsPage.Create();
303 
304     ZeroMemory(&psh, sizeof(psh));
305     psh.dwSize = sizeof(psh);
306     psh.dwFlags =  PSH_PROPTITLE | PSH_USEICONID | PSH_USECALLBACK;
307     psh.hwndParent = hwndOwner;
308     psh.hInstance = hExplorerInstance;
309     psh.pszIcon = MAKEINTRESOURCEW(IDI_STARTMENU);
310     psh.pszCaption = caption.GetString();
311     psh.nPages = _countof(hpsp);
312     psh.nStartPage = 0;
313     psh.phpage = hpsp;
314     psh.pfnCallback = PropSheetProc;
315 
316     PropertySheet(&psh);
317 }
318