Allow loading shell extensions

svn path=/trunk/; revision=29207
This commit is contained in:
Thomas Bluemel 2007-09-26 04:30:57 +00:00
parent 9f930ed173
commit 6648bd3f85
5 changed files with 113 additions and 32 deletions

View file

@ -28,14 +28,15 @@
#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;
@ -48,7 +49,6 @@ typedef struct _SPEED_DATA
RECT rcCursor;
} SPEED_DATA, *PSPEED_DATA;
/* Property page dialog callback */
static INT_PTR CALLBACK
KeyboardSpeedProc(IN HWND hwndDlg,
@ -296,9 +296,11 @@ KeybHardwareProc(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);
@ -309,19 +311,31 @@ KeyboardApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam)
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;
InitPropSheetPage(&psp[0], IDD_KEYBSPEED, KeyboardSpeedProc);
InitPropSheetPage(&psp[1], IDD_HARDWARE, KeybHardwareProc);
/* Load additional pages provided by shell extensions */
hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Keyboard"), MAX_CPL_PAGES - psh.nPages);
return (LONG)(PropertySheet(&psh) != -1);
/* 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);
if (hpsxa != NULL)
SHDestroyPropSheetExtArray(hpsxa);
return ret;
}
/* EOF */

View file

@ -30,6 +30,7 @@
#include <devguid.h>
#include <commctrl.h>
#include <cpl.h>
#include <cplext.h>
#include "main.h"
#include "resource.h"
@ -49,15 +50,42 @@ APPLET Applets[NUM_APPLETS] =
};
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;
}

View file

@ -26,6 +26,7 @@ typedef struct _APPLET
extern HINSTANCE hApplet;
#define MAX_CPL_PAGES 32
/* keyboard.c */
@ -34,11 +35,11 @@ KeyboardApplet(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lParam);
/* 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 */

View file

@ -13,6 +13,7 @@
<library>comctl32</library>
<library>devmgr</library>
<library>comdlg32</library>
<library>shell32</library>
<library>gdi32</library>
<library>msvcrt</library>
<file>keyboard.c</file>

View file

@ -38,6 +38,9 @@
#include <tchar.h>
#include <math.h>
#include <limits.h>
#include <shlobj.h>
#include <cplext.h>
#include <regstr.h>
#include <stdio.h>
@ -54,7 +57,6 @@
#define MAX_DOUBLE_CLICK_SPEED 900
#define DEFAULT_WHEEL_SCROLL_LINES 3
typedef struct _BUTTON_DATA
{
ULONG g_SwapMouseButtons;
@ -1794,13 +1796,29 @@ WheelProc(IN HWND hwndDlg,
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);
@ -1811,21 +1829,40 @@ MouseApplet(HWND hwnd, UINT uMsg, LPARAM lParam1, LPARAM 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;
psh.phpage = hpsp;
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);
/* 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 */