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