Add a (not yet functional) control to allow the user to arrange the monitors
[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 static BOOL CALLBACK
38 PropSheetAddPage(HPROPSHEETPAGE hpage, LPARAM lParam)
39 {
40 PROPSHEETHEADER *ppsh = (PROPSHEETHEADER *)lParam;
41 if (ppsh != NULL && ppsh->nPages < MAX_DESK_PAGES)
42 {
43 ppsh->phpage[ppsh->nPages++] = hpage;
44 return TRUE;
45 }
46
47 return FALSE;
48 }
49
50 static BOOL
51 InitPropSheetPage(PROPSHEETHEADER *ppsh, WORD idDlg, DLGPROC DlgProc, LPFNPSPCALLBACK pfnCallback)
52 {
53 HPROPSHEETPAGE hPage;
54 PROPSHEETPAGE psp;
55
56 if (ppsh->nPages < MAX_DESK_PAGES)
57 {
58 ZeroMemory(&psp, sizeof(psp));
59 psp.dwSize = sizeof(psp);
60 psp.dwFlags = PSP_DEFAULT;
61 if (pfnCallback != NULL)
62 psp.dwFlags |= PSP_USECALLBACK;
63 psp.hInstance = hApplet;
64 psp.pszTemplate = MAKEINTRESOURCE(idDlg);
65 psp.pfnDlgProc = DlgProc;
66 psp.pfnCallback = pfnCallback;
67
68 hPage = CreatePropertySheetPage(&psp);
69 if (hPage != NULL)
70 {
71 return PropSheetAddPage(hPage, (LPARAM)ppsh);
72 }
73 }
74
75 return FALSE;
76 }
77
78 static const struct
79 {
80 WORD idDlg;
81 DLGPROC DlgProc;
82 LPFNPSPCALLBACK Callback;
83 } PropPages[] =
84 {
85 { IDD_BACKGROUND, BackgroundPageProc, NULL },
86 { IDD_SCREENSAVER, ScreenSaverPageProc, NULL },
87 { IDD_APPEARANCE, AppearancePageProc, NULL },
88 { IDD_SETTINGS, SettingsPageProc, SettingsPageCallbackProc },
89 };
90
91 /* Display Applet */
92 static LONG APIENTRY
93 DisplayApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
94 {
95 HPROPSHEETPAGE hpsp[MAX_DESK_PAGES];
96 PROPSHEETHEADER psh;
97 HPSXA hpsxa;
98 TCHAR Caption[1024];
99 LONG ret;
100 UINT i;
101
102 UNREFERENCED_PARAMETER(lParam);
103 UNREFERENCED_PARAMETER(wParam);
104 UNREFERENCED_PARAMETER(uMsg);
105 UNREFERENCED_PARAMETER(hwnd);
106
107 LoadString(hApplet, IDS_CPLNAME, Caption, sizeof(Caption) / sizeof(TCHAR));
108
109 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
110 psh.dwSize = sizeof(PROPSHEETHEADER);
111 psh.dwFlags = PSH_USECALLBACK | PSH_PROPTITLE;
112 psh.hwndParent = NULL;
113 psh.hInstance = hApplet;
114 psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_DESK_ICON));
115 psh.pszCaption = Caption;
116 psh.nPages = 0;
117 psh.nStartPage = 0;
118 psh.phpage = hpsp;
119
120 /* Allow shell extensions to replace the background page */
121 hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Desk"), MAX_DESK_PAGES - psh.nPages);
122
123 for (i = 0; i != sizeof(PropPages) / sizeof(PropPages[0]); i++)
124 {
125 /* Override the background page if requested by a shell extension */
126 if (PropPages[i].idDlg == IDD_BACKGROUND && hpsxa != NULL &&
127 SHReplaceFromPropSheetExtArray(hpsxa, CPLPAGE_DISPLAY_BACKGROUND, PropSheetAddPage, (LPARAM)&psh) != 0)
128 {
129 /* The shell extension added one or more pages to replace the background page.
130 Don't create the built-in page anymore! */
131 continue;
132 }
133
134 InitPropSheetPage(&psh, PropPages[i].idDlg, PropPages[i].DlgProc, PropPages[i].Callback);
135 }
136
137 /* NOTE: Don;t call SHAddFromPropSheetExtArray here because this applet only allows
138 replacing the background page but not extending the applet by more pages */
139
140 ret = (LONG)(PropertySheet(&psh) != -1);
141
142 if (hpsxa != NULL)
143 SHDestroyPropSheetExtArray(hpsxa);
144
145 return ret;
146 }
147
148
149 /* Control Panel Callback */
150 LONG CALLBACK
151 CPlApplet(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
152 {
153 int i = (int)lParam1;
154
155 switch (uMsg)
156 {
157 case CPL_INIT:
158 return TRUE;
159
160 case CPL_GETCOUNT:
161 return NUM_APPLETS;
162
163 case CPL_INQUIRE:
164 {
165 CPLINFO *CPlInfo = (CPLINFO*)lParam2;
166 CPlInfo->lData = 0;
167 CPlInfo->idIcon = Applets[i].idIcon;
168 CPlInfo->idName = Applets[i].idName;
169 CPlInfo->idInfo = Applets[i].idDescription;
170 }
171 break;
172
173 case CPL_DBLCLK:
174 Applets[i].AppletProc(hwndCPl, uMsg, lParam1, lParam2);
175 break;
176 }
177
178 return FALSE;
179 }
180
181
182 BOOL WINAPI
183 DllMain(HINSTANCE hInstDLL, DWORD dwReason, LPVOID lpvReserved)
184 {
185 UNREFERENCED_PARAMETER(lpvReserved);
186
187 switch (dwReason)
188 {
189 case DLL_PROCESS_ATTACH:
190 RegisterPreviewControl(hInstDLL);
191 // case DLL_THREAD_ATTACH:
192 hApplet = hInstDLL;
193 break;
194
195 case DLL_PROCESS_DETACH:
196 UnregisterPreviewControl(hInstDLL);
197 break;
198 }
199
200 return TRUE;
201 }