Bring back ext2 code from branch
[reactos.git] / reactos / 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
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 LoadString(hApplet, IDS_CPLNAME, Caption, sizeof(Caption) / sizeof(TCHAR));
135
136 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
137 psh.dwSize = sizeof(PROPSHEETHEADER);
138 psh.dwFlags = PSH_USECALLBACK | PSH_PROPTITLE;
139 psh.hwndParent = NULL;
140 psh.hInstance = hApplet;
141 psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_DESK_ICON));
142 psh.pszCaption = Caption;
143 psh.nPages = 0;
144 psh.nStartPage = 0;
145 psh.phpage = hpsp;
146
147 /* Allow shell extensions to replace the background page */
148 hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Desk"), MAX_DESK_PAGES - psh.nPages);
149
150 for (i = 0; i != sizeof(PropPages) / sizeof(PropPages[0]); i++)
151 {
152 /* Override the background page if requested by a shell extension */
153 if (PropPages[i].idDlg == IDD_BACKGROUND && hpsxa != NULL &&
154 SHReplaceFromPropSheetExtArray(hpsxa, CPLPAGE_DISPLAY_BACKGROUND, PropSheetAddPage, (LPARAM)&psh) != 0)
155 {
156 /* The shell extension added one or more pages to replace the background page.
157 Don't create the built-in page anymore! */
158 continue;
159 }
160
161 InitPropSheetPage(&psh, PropPages[i].idDlg, PropPages[i].DlgProc, PropPages[i].Callback);
162 }
163
164 /* NOTE: Don;t call SHAddFromPropSheetExtArray here because this applet only allows
165 replacing the background page but not extending the applet by more pages */
166
167 ret = (LONG)(PropertySheet(&psh) != -1);
168
169 if (hpsxa != NULL)
170 SHDestroyPropSheetExtArray(hpsxa);
171
172 return ret;
173 }
174
175
176 /* Control Panel Callback */
177 LONG CALLBACK
178 CPlApplet(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
179 {
180 int i = (int)lParam1;
181
182 switch (uMsg)
183 {
184 case CPL_INIT:
185 return TRUE;
186
187 case CPL_GETCOUNT:
188 return NUM_APPLETS;
189
190 case CPL_INQUIRE:
191 {
192 CPLINFO *CPlInfo = (CPLINFO*)lParam2;
193 CPlInfo->lData = 0;
194 CPlInfo->idIcon = Applets[i].idIcon;
195 CPlInfo->idName = Applets[i].idName;
196 CPlInfo->idInfo = Applets[i].idDescription;
197 }
198 break;
199
200 case CPL_DBLCLK:
201 Applets[i].AppletProc(hwndCPl, uMsg, lParam1, lParam2);
202 break;
203 }
204
205 return FALSE;
206 }
207
208
209 BOOL WINAPI
210 DllMain(HINSTANCE hInstDLL, DWORD dwReason, LPVOID lpvReserved)
211 {
212 UNREFERENCED_PARAMETER(lpvReserved);
213
214 switch (dwReason)
215 {
216 case DLL_PROCESS_ATTACH:
217 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
218 RegisterPreviewControl(hInstDLL);
219 // case DLL_THREAD_ATTACH:
220 hApplet = hInstDLL;
221 break;
222
223 case DLL_PROCESS_DETACH:
224 UnregisterPreviewControl(hInstDLL);
225 CoUninitialize();
226 break;
227 }
228
229 return TRUE;
230 }