- Update to r53061
[reactos.git] / dll / cpl / desk / desk.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS Display Control Panel
5 * FILE: lib/cpl/desk/desk.c
6 * PURPOSE: ReactOS Display Control Panel
7 *
8 * PROGRAMMERS: Trevor McCort (lycan359@gmail.com)
9 */
10
11 #include "desk.h"
12
13 #define NUM_APPLETS (1)
14
15 static LONG APIENTRY DisplayApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam);
16
17 INT_PTR CALLBACK BackgroundPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
18 INT_PTR CALLBACK ScreenSaverPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
19 INT_PTR CALLBACK AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
20 INT_PTR CALLBACK SettingsPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
21 UINT CALLBACK SettingsPageCallbackProc(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp);
22
23 HINSTANCE hApplet = 0;
24 HWND hCPLWindow;
25
26 /* Applets */
27 APPLET Applets[NUM_APPLETS] =
28 {
29 {
30 IDC_DESK_ICON,
31 IDS_CPLNAME,
32 IDS_CPLDESCRIPTION,
33 DisplayApplet
34 }
35 };
36
37 HMENU
38 LoadPopupMenu(IN HINSTANCE hInstance,
39 IN LPCTSTR lpMenuName)
40 {
41 HMENU hMenu, hSubMenu = NULL;
42
43 hMenu = LoadMenu(hInstance,
44 lpMenuName);
45
46 if (hMenu != NULL)
47 {
48 hSubMenu = GetSubMenu(hMenu,
49 0);
50 if (hSubMenu != NULL &&
51 !RemoveMenu(hMenu,
52 0,
53 MF_BYPOSITION))
54 {
55 hSubMenu = NULL;
56 }
57
58 DestroyMenu(hMenu);
59 }
60
61 return hSubMenu;
62 }
63
64 static BOOL CALLBACK
65 PropSheetAddPage(HPROPSHEETPAGE hpage, LPARAM lParam)
66 {
67 PROPSHEETHEADER *ppsh = (PROPSHEETHEADER *)lParam;
68 if (ppsh != NULL && ppsh->nPages < MAX_DESK_PAGES)
69 {
70 ppsh->phpage[ppsh->nPages++] = hpage;
71 return TRUE;
72 }
73
74 return FALSE;
75 }
76
77 static BOOL
78 InitPropSheetPage(PROPSHEETHEADER *ppsh, WORD idDlg, DLGPROC DlgProc, LPFNPSPCALLBACK pfnCallback)
79 {
80 HPROPSHEETPAGE hPage;
81 PROPSHEETPAGE psp;
82
83 if (ppsh->nPages < MAX_DESK_PAGES)
84 {
85 ZeroMemory(&psp, sizeof(psp));
86 psp.dwSize = sizeof(psp);
87 psp.dwFlags = PSP_DEFAULT;
88 if (pfnCallback != NULL)
89 psp.dwFlags |= PSP_USECALLBACK;
90 psp.hInstance = hApplet;
91 psp.pszTemplate = MAKEINTRESOURCE(idDlg);
92 psp.pfnDlgProc = DlgProc;
93 psp.pfnCallback = pfnCallback;
94
95 hPage = CreatePropertySheetPage(&psp);
96 if (hPage != NULL)
97 {
98 return PropSheetAddPage(hPage, (LPARAM)ppsh);
99 }
100 }
101
102 return FALSE;
103 }
104
105 static const struct
106 {
107 WORD idDlg;
108 DLGPROC DlgProc;
109 LPFNPSPCALLBACK Callback;
110 } PropPages[] =
111 {
112 { IDD_BACKGROUND, BackgroundPageProc, NULL },
113 { IDD_SCREENSAVER, ScreenSaverPageProc, NULL },
114 { IDD_APPEARANCE, AppearancePageProc, NULL },
115 { IDD_SETTINGS, SettingsPageProc, SettingsPageCallbackProc },
116 };
117
118 /* Display Applet */
119 static LONG APIENTRY
120 DisplayApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
121 {
122 HPROPSHEETPAGE hpsp[MAX_DESK_PAGES];
123 PROPSHEETHEADER psh;
124 HPSXA hpsxa;
125 TCHAR Caption[1024];
126 LONG ret;
127 UINT i;
128
129 UNREFERENCED_PARAMETER(lParam);
130 UNREFERENCED_PARAMETER(wParam);
131 UNREFERENCED_PARAMETER(uMsg);
132 UNREFERENCED_PARAMETER(hwnd);
133
134 g_GlobalData.desktop_color = GetSysColor(COLOR_DESKTOP);
135
136 LoadString(hApplet, IDS_CPLNAME, Caption, sizeof(Caption) / sizeof(TCHAR));
137
138 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
139 psh.dwSize = sizeof(PROPSHEETHEADER);
140 psh.dwFlags = PSH_USECALLBACK | PSH_PROPTITLE;
141 psh.hwndParent = hCPLWindow;
142 psh.hInstance = hApplet;
143 psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_DESK_ICON));
144 psh.pszCaption = Caption;
145 psh.nPages = 0;
146 psh.nStartPage = 0;
147 psh.phpage = hpsp;
148
149 /* Allow shell extensions to replace the background page */
150 hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Desk"), MAX_DESK_PAGES - psh.nPages);
151
152 for (i = 0; i != sizeof(PropPages) / sizeof(PropPages[0]); i++)
153 {
154 /* Override the background page if requested by a shell extension */
155 if (PropPages[i].idDlg == IDD_BACKGROUND && hpsxa != NULL &&
156 SHReplaceFromPropSheetExtArray(hpsxa, CPLPAGE_DISPLAY_BACKGROUND, PropSheetAddPage, (LPARAM)&psh) != 0)
157 {
158 /* The shell extension added one or more pages to replace the background page.
159 Don't create the built-in page anymore! */
160 continue;
161 }
162
163 InitPropSheetPage(&psh, PropPages[i].idDlg, PropPages[i].DlgProc, PropPages[i].Callback);
164 }
165
166 /* NOTE: Don't call SHAddFromPropSheetExtArray here because this applet only allows
167 replacing the background page but not extending the applet by more pages */
168
169 ret = (LONG)(PropertySheet(&psh) != -1);
170
171 if (hpsxa != NULL)
172 SHDestroyPropSheetExtArray(hpsxa);
173
174 return ret;
175 }
176
177
178 /* Control Panel Callback */
179 LONG CALLBACK
180 CPlApplet(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
181 {
182 int i = (int)lParam1;
183
184 switch (uMsg)
185 {
186 case CPL_INIT:
187 return TRUE;
188
189 case CPL_GETCOUNT:
190 return NUM_APPLETS;
191
192 case CPL_INQUIRE:
193 {
194 CPLINFO *CPlInfo = (CPLINFO*)lParam2;
195 CPlInfo->lData = 0;
196 CPlInfo->idIcon = Applets[i].idIcon;
197 CPlInfo->idName = Applets[i].idName;
198 CPlInfo->idInfo = Applets[i].idDescription;
199 }
200 break;
201
202 case CPL_DBLCLK:
203 hCPLWindow = hwndCPl;
204 Applets[i].AppletProc(hwndCPl, uMsg, lParam1, lParam2);
205 break;
206 }
207
208 return FALSE;
209 }
210
211
212 BOOL WINAPI
213 DllMain(HINSTANCE hInstDLL, DWORD dwReason, LPVOID lpvReserved)
214 {
215 UNREFERENCED_PARAMETER(lpvReserved);
216
217 switch (dwReason)
218 {
219 case DLL_PROCESS_ATTACH:
220 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
221 RegisterPreviewControl(hInstDLL);
222 // case DLL_THREAD_ATTACH:
223 hApplet = hInstDLL;
224 break;
225
226 case DLL_PROCESS_DETACH:
227 UnregisterPreviewControl(hInstDLL);
228 CoUninitialize();
229 break;
230 }
231
232 return TRUE;
233 }