#include <devguid.h>
#include <commctrl.h>
#include <prsht.h>
+#include <shlobj.h>
#include <cpl.h>
+#include <regstr.h>
#include "main.h"
#include "resource.h"
#define ID_BLINK_TIMER 345
-
typedef struct _SPEED_DATA
{
INT nKeyboardDelay;
RECT rcCursor;
} SPEED_DATA, *PSPEED_DATA;
-
/* Property page dialog callback */
static INT_PTR CALLBACK
KeyboardSpeedProc(IN HWND hwndDlg,
LONG APIENTRY
KeyboardApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
{
- PROPSHEETPAGE psp[2];
+ HPROPSHEETPAGE hpsp[MAX_CPL_PAGES];
PROPSHEETHEADER psh;
+ HPSXA hpsxa;
TCHAR szCaption[256];
+ LONG ret;
UNREFERENCED_PARAMETER(lParam);
UNREFERENCED_PARAMETER(wParam);
ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
psh.dwSize = sizeof(PROPSHEETHEADER);
- psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE;
+ psh.dwFlags = PSH_PROPTITLE;
psh.hwndParent = NULL;
psh.hInstance = hApplet;
psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_CPLICON_2));
psh.pszCaption = szCaption;
- psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
psh.nStartPage = 0;
- psh.ppsp = psp;
+ psh.phpage = hpsp;
+
+ /* Load additional pages provided by shell extensions */
+ hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Keyboard"), MAX_CPL_PAGES - psh.nPages);
+
+ /* NOTE: The speed page (CPLPAGE_KEYBOARD_SPEED) cannot be replaced by
+ shell extensions since Win2k! */
+ InitPropSheetPage(&psh, IDD_KEYBSPEED, KeyboardSpeedProc);
+ InitPropSheetPage(&psh, IDD_HARDWARE, KeybHardwareProc);
+
+ if (hpsxa != NULL)
+ SHAddFromPropSheetExtArray(hpsxa, PropSheetAddPage, (LPARAM)&psh);
+
+ ret = (LONG)(PropertySheet(&psh) != -1);
- InitPropSheetPage(&psp[0], IDD_KEYBSPEED, KeyboardSpeedProc);
- InitPropSheetPage(&psp[1], IDD_HARDWARE, KeybHardwareProc);
+ if (hpsxa != NULL)
+ SHDestroyPropSheetExtArray(hpsxa);
- return (LONG)(PropertySheet(&psh) != -1);
+ return ret;
}
/* EOF */
#include <devguid.h>
#include <commctrl.h>
#include <cpl.h>
+#include <cplext.h>
#include "main.h"
#include "resource.h"
};
-VOID
-InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc)
+BOOL
+InitPropSheetPage(PROPSHEETHEADER *ppsh, WORD idDlg, DLGPROC DlgProc)
{
- ZeroMemory(psp, sizeof(PROPSHEETPAGE));
- psp->dwSize = sizeof(PROPSHEETPAGE);
- psp->dwFlags = PSP_DEFAULT;
- psp->hInstance = hApplet;
- psp->pszTemplate = MAKEINTRESOURCE(idDlg);
- psp->pfnDlgProc = DlgProc;
+ HPROPSHEETPAGE hPage;
+ PROPSHEETPAGE psp;
+
+ if (ppsh->nPages < MAX_CPL_PAGES)
+ {
+ ZeroMemory(&psp, sizeof(psp));
+ psp.dwSize = sizeof(psp);
+ psp.dwFlags = PSP_DEFAULT;
+ psp.hInstance = hApplet;
+ psp.pszTemplate = MAKEINTRESOURCE(idDlg);
+ psp.pfnDlgProc = DlgProc;
+
+ hPage = CreatePropertySheetPage(&psp);
+ if (hPage != NULL)
+ {
+ return PropSheetAddPage(hPage, (LPARAM)ppsh);
+ }
+ }
+
+ return FALSE;
+}
+
+BOOL CALLBACK
+PropSheetAddPage(HPROPSHEETPAGE hpage, LPARAM lParam)
+{
+ PROPSHEETHEADER *ppsh = (PROPSHEETHEADER *)lParam;
+ if (ppsh != NULL && ppsh->nPages < MAX_CPL_PAGES)
+ {
+ ppsh->phpage[ppsh->nPages++] = hpage;
+ return TRUE;
+ }
+
+ return FALSE;
}
extern HINSTANCE hApplet;
+#define MAX_CPL_PAGES 32
/* keyboard.c */
/* main.c */
-VOID
-InitPropSheetPage(PROPSHEETPAGE *psp,
- WORD idDlg,
- DLGPROC DlgProc);
+BOOL
+InitPropSheetPage(PROPSHEETHEADER *ppsh, WORD idDlg, DLGPROC DlgProc);
+BOOL CALLBACK
+PropSheetAddPage(HPROPSHEETPAGE hpage, LPARAM lParam);
/* mouse.c */
<library>comctl32</library>
<library>devmgr</library>
<library>comdlg32</library>
+ <library>shell32</library>
<library>gdi32</library>
<library>msvcrt</library>
<file>keyboard.c</file>
#include <tchar.h>
#include <math.h>
#include <limits.h>
+#include <shlobj.h>
+#include <cplext.h>
+#include <regstr.h>
#include <stdio.h>
#define MAX_DOUBLE_CLICK_SPEED 900
#define DEFAULT_WHEEL_SCROLL_LINES 3
-
typedef struct _BUTTON_DATA
{
ULONG g_SwapMouseButtons;
return FALSE;
}
+static const struct
+{
+ WORD idDlg;
+ DLGPROC DlgProc;
+ UINT uiReplaceWith;
+} PropPages[] =
+{
+ { IDD_PAGE_BUTTON, ButtonProc, CPLPAGE_MOUSE_BUTTONS },
+ { IDD_PAGE_POINTER, PointerProc, 0 },
+ { IDD_PAGE_OPTION, OptionProc, CPLPAGE_MOUSE_PTRMOTION },
+ { IDD_PAGE_WHEEL, WheelProc, CPLPAGE_MOUSE_WHEEL },
+ { IDD_HARDWARE, MouseHardwareProc, 0 },
+};
LONG APIENTRY
MouseApplet(HWND hwnd, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
{
- PROPSHEETPAGE psp[5];
+ HPROPSHEETPAGE hpsp[MAX_CPL_PAGES];
PROPSHEETHEADER psh;
+ HPSXA hpsxa;
TCHAR Caption[256];
+ UINT i;
+ LONG ret;
UNREFERENCED_PARAMETER(lParam1);
UNREFERENCED_PARAMETER(lParam2);
ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
psh.dwSize = sizeof(PROPSHEETHEADER);
- psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE;
+ psh.dwFlags = PSH_PROPTITLE;
psh.hwndParent = NULL;
psh.hInstance = hApplet;
psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_CPLICON_1));
psh.pszCaption = Caption;
- psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
psh.nStartPage = 0;
- psh.ppsp = psp;
-
- InitPropSheetPage(&psp[0], IDD_PAGE_BUTTON, ButtonProc);
- InitPropSheetPage(&psp[1], IDD_PAGE_POINTER, PointerProc);
- InitPropSheetPage(&psp[2], IDD_PAGE_OPTION, OptionProc);
- InitPropSheetPage(&psp[3], IDD_PAGE_WHEEL, WheelProc);
- InitPropSheetPage(&psp[4], IDD_HARDWARE, MouseHardwareProc);
- return (LONG)(PropertySheet(&psh) != -1);
+ psh.phpage = hpsp;
+
+ /* Load additional pages provided by shell extensions */
+ hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Mouse"), MAX_CPL_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].uiReplaceWith != 0 && hpsxa != NULL &&
+ SHReplaceFromPropSheetExtArray(hpsxa, PropPages[i].uiReplaceWith, 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);
+ }
+
+ if (hpsxa != NULL)
+ SHAddFromPropSheetExtArray(hpsxa, PropSheetAddPage, (LPARAM)&psh);
+
+ ret = (LONG)(PropertySheet(&psh) != -1);
+
+ if (hpsxa != NULL)
+ SHDestroyPropSheetExtArray(hpsxa);
+
+ return ret;
}
/* EOF */