* PROJECT: ReactOS Display Control Panel
* FILE: lib/cpl/desk/desk.c
* PURPOSE: ReactOS Display Control Panel
- *
+ *
* PROGRAMMERS: Trevor McCort (lycan359@gmail.com)
*/
static LONG APIENTRY DisplayApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam);
-extern INT_PTR CALLBACK BackgroundPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
-extern INT_PTR CALLBACK ScreenSaverPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
-extern INT_PTR CALLBACK AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
-extern INT_PTR CALLBACK SettingsPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK BackgroundPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK ScreenSaverPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK AppearancePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK SettingsPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+UINT CALLBACK SettingsPageCallbackProc(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp);
HINSTANCE hApplet = 0;
+HWND hCPLWindow;
/* Applets */
-APPLET Applets[NUM_APPLETS] =
+APPLET Applets[NUM_APPLETS] =
{
{
IDC_DESK_ICON,
}
};
+HMENU
+LoadPopupMenu(IN HINSTANCE hInstance,
+ IN LPCTSTR lpMenuName)
+{
+ HMENU hMenu, hSubMenu = NULL;
+
+ hMenu = LoadMenu(hInstance,
+ lpMenuName);
+
+ if (hMenu != NULL)
+ {
+ hSubMenu = GetSubMenu(hMenu,
+ 0);
+ if (hSubMenu != NULL &&
+ !RemoveMenu(hMenu,
+ 0,
+ MF_BYPOSITION))
+ {
+ hSubMenu = NULL;
+ }
+
+ DestroyMenu(hMenu);
+ }
+
+ return hSubMenu;
+}
-static VOID
-InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc)
+static BOOL CALLBACK
+PropSheetAddPage(HPROPSHEETPAGE hpage, LPARAM lParam)
{
- ZeroMemory(psp, sizeof(PROPSHEETPAGE));
- psp->dwSize = sizeof(PROPSHEETPAGE);
- psp->dwFlags = PSP_DEFAULT;
- psp->hInstance = hApplet;
- psp->pszTemplate = MAKEINTRESOURCE(idDlg);
- psp->pfnDlgProc = DlgProc;
+ PROPSHEETHEADER *ppsh = (PROPSHEETHEADER *)lParam;
+ if (ppsh != NULL && ppsh->nPages < MAX_DESK_PAGES)
+ {
+ ppsh->phpage[ppsh->nPages++] = hpage;
+ return TRUE;
+ }
+
+ return FALSE;
}
+static BOOL
+InitPropSheetPage(PROPSHEETHEADER *ppsh, WORD idDlg, DLGPROC DlgProc, LPFNPSPCALLBACK pfnCallback)
+{
+ HPROPSHEETPAGE hPage;
+ PROPSHEETPAGE psp;
+
+ if (ppsh->nPages < MAX_DESK_PAGES)
+ {
+ ZeroMemory(&psp, sizeof(psp));
+ psp.dwSize = sizeof(psp);
+ psp.dwFlags = PSP_DEFAULT;
+ if (pfnCallback != NULL)
+ psp.dwFlags |= PSP_USECALLBACK;
+ psp.hInstance = hApplet;
+ psp.pszTemplate = MAKEINTRESOURCE(idDlg);
+ psp.pfnDlgProc = DlgProc;
+ psp.pfnCallback = pfnCallback;
+
+ hPage = CreatePropertySheetPage(&psp);
+ if (hPage != NULL)
+ {
+ return PropSheetAddPage(hPage, (LPARAM)ppsh);
+ }
+ }
+
+ return FALSE;
+}
+
+static const struct
+{
+ WORD idDlg;
+ DLGPROC DlgProc;
+ LPFNPSPCALLBACK Callback;
+} PropPages[] =
+{
+ { IDD_BACKGROUND, BackgroundPageProc, NULL },
+ { IDD_SCREENSAVER, ScreenSaverPageProc, NULL },
+ { IDD_APPEARANCE, AppearancePageProc, NULL },
+ { IDD_SETTINGS, SettingsPageProc, SettingsPageCallbackProc },
+};
/* Display Applet */
static LONG APIENTRY
DisplayApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
{
- PROPSHEETPAGE psp[4];
+ HPROPSHEETPAGE hpsp[MAX_DESK_PAGES];
PROPSHEETHEADER psh;
+ HPSXA hpsxa;
TCHAR Caption[1024];
+ LONG ret;
+ UINT i;
UNREFERENCED_PARAMETER(lParam);
UNREFERENCED_PARAMETER(wParam);
ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
psh.dwSize = sizeof(PROPSHEETHEADER);
- psh.dwFlags = PSH_PROPSHEETPAGE | PSH_USECALLBACK | PSH_PROPTITLE;
- psh.hwndParent = NULL;
+ psh.dwFlags = PSH_USECALLBACK | PSH_PROPTITLE;
+ psh.hwndParent = hCPLWindow;
psh.hInstance = hApplet;
psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_DESK_ICON));
psh.pszCaption = Caption;
- psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
+ psh.nPages = 0;
psh.nStartPage = 0;
- psh.ppsp = psp;
+ psh.phpage = hpsp;
+
+ /* Allow shell extensions to replace the background page */
+ hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Desk"), MAX_DESK_PAGES - psh.nPages);
+
+ for (i = 0; i != sizeof(PropPages) / sizeof(PropPages[0]); i++)
+ {
+ /* Override the background page if requested by a shell extension */
+ if (PropPages[i].idDlg == IDD_BACKGROUND && hpsxa != NULL &&
+ SHReplaceFromPropSheetExtArray(hpsxa, CPLPAGE_DISPLAY_BACKGROUND, PropSheetAddPage, (LPARAM)&psh) != 0)
+ {
+ /* The shell extension added one or more pages to replace the background page.
+ Don't create the built-in page anymore! */
+ continue;
+ }
+
+ InitPropSheetPage(&psh, PropPages[i].idDlg, PropPages[i].DlgProc, PropPages[i].Callback);
+ }
+
+ /* NOTE: Don't call SHAddFromPropSheetExtArray here because this applet only allows
+ replacing the background page but not extending the applet by more pages */
+
+ ret = (LONG)(PropertySheet(&psh) != -1);
- InitPropSheetPage(&psp[0], IDD_BACKGROUND, (DLGPROC) BackgroundPageProc);
- InitPropSheetPage(&psp[1], IDD_SCREENSAVER, (DLGPROC) ScreenSaverPageProc);
- InitPropSheetPage(&psp[2], IDD_APPEARANCE, (DLGPROC) AppearancePageProc);
- InitPropSheetPage(&psp[3], IDD_SETTINGS, (DLGPROC) SettingsPageProc);
+ if (hpsxa != NULL)
+ SHDestroyPropSheetExtArray(hpsxa);
- return (LONG)(PropertySheet(&psh) != -1);
+ return ret;
}
break;
case CPL_DBLCLK:
+ hCPLWindow = hwndCPl;
Applets[i].AppletProc(hwndCPl, uMsg, lParam1, lParam2);
break;
}
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
+ CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
RegisterPreviewControl(hInstDLL);
// case DLL_THREAD_ATTACH:
hApplet = hInstDLL;
case DLL_PROCESS_DETACH:
UnregisterPreviewControl(hInstDLL);
+ CoUninitialize();
break;
}