mirror of
https://github.com/reactos/reactos.git
synced 2024-09-27 21:16:34 +00:00
[SHELL32][CONTROL] Added basic IOpenControlPanel support (#6248)
Add a basic IOpenControlPanel implementation that supports Vista canonical registry names. Implements `control.exe /name company.name [/page id]` and `IOpenControlPanel` handling of Vista-style canonical registry names. The documented `Microsoft.*` names don't work because they are simply not in our registry but "[Executable Control Panel Items](https://learn.microsoft.com/en-us/windows/win32/shell/how-to-register-an-executable-control-panel-item-registration-)" registered by 3rd-party ISVs will function correctly in control.exe and the COM API. Notes: - `IOpenControlPanel` is implemented in CControlPanelFolder.cpp because it is supposed to have tighter integration with that shell folder than it does in this PR. - `IOpenControlPanel` is also supposed to handle .cpl files with canonical names registered under [`Extended Properties`](https://learn.microsoft.com/en-us/windows/win32/shell/how-to-register-dll-control-panel-item-registration-#step-3) but the control panel folder does not implement `IShellFolder2::GetDetailsEx` yet, so it will have to wait. - These "Executable Control Panel Items" are also supposed to be displayed in the control panel itself but this PR does not address that. The `ITEMIDLIST` format for those needs investigation... - The Wow64 handling is perhaps not correct but it does not matter, `ShellExecuteEx` gets to deal with whatever is in the `...\shell\open\command` key. `CControlPanelFolder` would have to take more care when it starts reading those keys so it knows when to append "(32-bit)" to the display name. - `%s%s` because .cpl canonical names don't have the `::` prefix according to Geoff Chappell. - Always returns `CPVIEW_CLASSIC` because our `CControlPanelFolder` does not support the category view.
This commit is contained in:
parent
fb43301bad
commit
d41dec2e07
|
@ -2,5 +2,7 @@
|
||||||
add_rc_deps(control.rc ${CMAKE_CURRENT_SOURCE_DIR}/resources/config.ico)
|
add_rc_deps(control.rc ${CMAKE_CURRENT_SOURCE_DIR}/resources/config.ico)
|
||||||
add_executable(control control.c control.rc)
|
add_executable(control control.c control.rc)
|
||||||
set_module_type(control win32gui UNICODE)
|
set_module_type(control win32gui UNICODE)
|
||||||
|
add_delay_importlibs(control ole32)
|
||||||
|
target_link_libraries(control uuid)
|
||||||
add_importlibs(control advapi32 shell32 user32 msvcrt kernel32)
|
add_importlibs(control advapi32 shell32 user32 msvcrt kernel32)
|
||||||
add_cd_file(TARGET control DESTINATION reactos/system32 FOR all)
|
add_cd_file(TARGET control DESTINATION reactos/system32 FOR all)
|
||||||
|
|
|
@ -4,12 +4,14 @@
|
||||||
* PURPOSE: ReactOS System Control Panel
|
* PURPOSE: ReactOS System Control Panel
|
||||||
* COPYRIGHT: Copyright 2004 Gero Kuehn (reactos.filter@gkware.com)
|
* COPYRIGHT: Copyright 2004 Gero Kuehn (reactos.filter@gkware.com)
|
||||||
* Copyright 2008 Colin Finck (colin@reactos.org)
|
* Copyright 2008 Colin Finck (colin@reactos.org)
|
||||||
* Copyright 2014 Hermès Bélusca-Maïto (hermes.belusca-maito@reactos.org)
|
* Copyright 2014 Hermès Bélusca-Maïto (hermes.belusca-maito@reactos.org)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define WIN32_NO_STATUS
|
#define WIN32_NO_STATUS
|
||||||
|
#define COBJMACROS
|
||||||
|
|
||||||
|
|
||||||
#include <windef.h>
|
#include <windef.h>
|
||||||
#include <winbase.h>
|
#include <winbase.h>
|
||||||
|
@ -17,6 +19,9 @@
|
||||||
#include <winreg.h>
|
#include <winreg.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
|
#include <objbase.h>
|
||||||
|
#include <shobjidl.h>
|
||||||
|
#include <shlguid.h>
|
||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
|
@ -34,6 +39,35 @@ VOID
|
||||||
WINAPI
|
WINAPI
|
||||||
Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow);
|
Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow);
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
IsSwitch(LPCWSTR Switch, LPCWSTR Arg)
|
||||||
|
{
|
||||||
|
if (*Arg == '/' || *Arg == '-')
|
||||||
|
{
|
||||||
|
return !lstrcmpiW(Arg+1, Switch);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT
|
||||||
|
OpenControlPanelItem(LPCWSTR Name, LPCWSTR Page)
|
||||||
|
{
|
||||||
|
HRESULT hr = CoInitialize(0);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
IOpenControlPanel *pOCP;
|
||||||
|
hr = CoCreateInstance(&CLSID_OpenControlPanel, NULL, CLSCTX_INPROC_SERVER,
|
||||||
|
&IID_IOpenControlPanel, (void**)&pOCP);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
hr = IOpenControlPanel_Open(pOCP, Name, Page, NULL);
|
||||||
|
IOpenControlPanel_Release(pOCP);
|
||||||
|
}
|
||||||
|
CoUninitialize();
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
static INT
|
static INT
|
||||||
OpenShellFolder(LPWSTR lpFolderCLSID)
|
OpenShellFolder(LPWSTR lpFolderCLSID)
|
||||||
{
|
{
|
||||||
|
@ -73,11 +107,16 @@ wWinMain(HINSTANCE hInstance,
|
||||||
INT nCmdShow)
|
INT nCmdShow)
|
||||||
{
|
{
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
|
LPWSTR *argv;
|
||||||
|
int argc;
|
||||||
|
|
||||||
/* Show the control panel window if no argument or "panel" was passed */
|
/* Show the control panel window if no argument or "panel" was passed */
|
||||||
if (*lpCmdLine == 0 || !_wcsicmp(lpCmdLine, L"panel"))
|
if (*lpCmdLine == 0 || !_wcsicmp(lpCmdLine, L"panel"))
|
||||||
return OpenShellFolder(L"");
|
return OpenShellFolder(L"");
|
||||||
|
|
||||||
|
/* Map legacy control panels */
|
||||||
|
if (!_wcsicmp(lpCmdLine, L"sticpl.cpl")) lpCmdLine = (LPWSTR) L"scannercamera";
|
||||||
|
|
||||||
/* Check one of the built-in control panel handlers */
|
/* Check one of the built-in control panel handlers */
|
||||||
if (!_wcsicmp(lpCmdLine, L"admintools")) return OpenShellFolder(L"\\::{D20EA4E1-3957-11d2-A40B-0C5020524153}");
|
if (!_wcsicmp(lpCmdLine, L"admintools")) return OpenShellFolder(L"\\::{D20EA4E1-3957-11d2-A40B-0C5020524153}");
|
||||||
else if (!_wcsicmp(lpCmdLine, L"color")) return RunControlPanel(L"desk.cpl,,2");
|
else if (!_wcsicmp(lpCmdLine, L"color")) return RunControlPanel(L"desk.cpl,,2");
|
||||||
|
@ -99,6 +138,28 @@ wWinMain(HINSTANCE hInstance,
|
||||||
else if (!_wcsicmp(lpCmdLine, L"userpasswords")) return RunControlPanel(L"nusrmgr.cpl"); /* Graphical User Account Manager */
|
else if (!_wcsicmp(lpCmdLine, L"userpasswords")) return RunControlPanel(L"nusrmgr.cpl"); /* Graphical User Account Manager */
|
||||||
else if (!_wcsicmp(lpCmdLine, L"userpasswords2")) return RUNDLL(L"netplwiz.dll,UsersRunDll"); /* Dialog based advanced User Account Manager */
|
else if (!_wcsicmp(lpCmdLine, L"userpasswords2")) return RUNDLL(L"netplwiz.dll,UsersRunDll"); /* Dialog based advanced User Account Manager */
|
||||||
|
|
||||||
|
/* https://learn.microsoft.com/en-us/windows/win32/shell/executing-control-panel-items#windows-vista-canonical-names */
|
||||||
|
argv = CommandLineToArgvW(lpCmdLine, &argc);
|
||||||
|
if (argv)
|
||||||
|
{
|
||||||
|
UINT argi = 0;
|
||||||
|
HRESULT hr = -1;
|
||||||
|
if (argc >= 2 && IsSwitch(L"name", argv[argi + 0]))
|
||||||
|
{
|
||||||
|
LPCWSTR pszPage = NULL;
|
||||||
|
if (argc >= 4 && IsSwitch(L"page", argv[argi + 2]))
|
||||||
|
{
|
||||||
|
pszPage = argv[argi + 3];
|
||||||
|
}
|
||||||
|
hr = OpenControlPanelItem(argv[argi + 1], pszPage);
|
||||||
|
}
|
||||||
|
LocalFree(argv);
|
||||||
|
if (hr != -1)
|
||||||
|
{
|
||||||
|
return SUCCEEDED(hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* It is none of them, so look for a handler in the registry */
|
/* It is none of them, so look for a handler in the registry */
|
||||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||||
L"Software\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls",
|
L"Software\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls",
|
||||||
|
|
|
@ -773,3 +773,144 @@ HRESULT WINAPI CCPLItemMenu::HandleMenuMsg(
|
||||||
|
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* COpenControlPanel
|
||||||
|
*/
|
||||||
|
|
||||||
|
static HRESULT GetParsingName(PCIDLIST_ABSOLUTE pidl, PWSTR*Name)
|
||||||
|
{
|
||||||
|
PIDLIST_ABSOLUTE pidlFree = NULL;
|
||||||
|
if (IS_INTRESOURCE(pidl))
|
||||||
|
{
|
||||||
|
HRESULT hr = SHGetSpecialFolderLocation(NULL, (UINT)(SIZE_T)pidl, &pidlFree);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
pidl = pidlFree;
|
||||||
|
}
|
||||||
|
HRESULT hr = SHGetNameFromIDList(pidl, SIGDN_DESKTOPABSOLUTEPARSING, Name);
|
||||||
|
ILFree(pidlFree);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT CreateCplAbsoluteParsingPath(LPCWSTR Prefix, LPCWSTR InFolderParse, PWSTR Buf, UINT cchBuf)
|
||||||
|
{
|
||||||
|
PWSTR cpfolder;
|
||||||
|
HRESULT hr = GetParsingName((PCIDLIST_ABSOLUTE)CSIDL_CONTROLS, &cpfolder);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
hr = StringCchPrintfW(Buf, cchBuf, L"%s\\%s%s", cpfolder, Prefix, InFolderParse);
|
||||||
|
SHFree(cpfolder);
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT FindExeCplClass(LPCWSTR Canonical, HKEY hKey, BOOL Wow64, LPWSTR clsid)
|
||||||
|
{
|
||||||
|
HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
|
||||||
|
HKEY hNSKey;
|
||||||
|
WCHAR key[MAX_PATH], buf[MAX_PATH];
|
||||||
|
wsprintfW(key, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\%s\\NameSpace",
|
||||||
|
Wow64 ? L"ControlPanelWOW64" : L"ControlPanel");
|
||||||
|
LSTATUS error = RegOpenKeyExW(hKey, key, 0, KEY_READ, &hNSKey);
|
||||||
|
if (error)
|
||||||
|
return HRESULT_FROM_WIN32(error);
|
||||||
|
for (DWORD i = 0; RegEnumKeyW(hNSKey, i, key, _countof(key)) == ERROR_SUCCESS; ++i)
|
||||||
|
{
|
||||||
|
IID validate;
|
||||||
|
if (SUCCEEDED(IIDFromString(key, &validate)))
|
||||||
|
{
|
||||||
|
wsprintfW(buf, L"CLSID\\%s", key);
|
||||||
|
DWORD cb = sizeof(buf);
|
||||||
|
if (RegGetValueW(HKEY_CLASSES_ROOT, buf, L"System.ApplicationName",
|
||||||
|
RRF_RT_REG_SZ, NULL, buf, &cb) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if (!lstrcmpiW(buf, Canonical))
|
||||||
|
{
|
||||||
|
lstrcpyW(clsid, key);
|
||||||
|
hr = S_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RegCloseKey(hNSKey);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT FindExeCplClass(LPCWSTR Canonical, LPWSTR clsid)
|
||||||
|
{
|
||||||
|
HRESULT hr = E_FAIL;
|
||||||
|
if (FAILED(hr))
|
||||||
|
hr = FindExeCplClass(Canonical, HKEY_CURRENT_USER, FALSE, clsid);
|
||||||
|
if (FAILED(hr))
|
||||||
|
hr = FindExeCplClass(Canonical, HKEY_CURRENT_USER, TRUE, clsid);
|
||||||
|
if (FAILED(hr))
|
||||||
|
hr = FindExeCplClass(Canonical, HKEY_LOCAL_MACHINE, FALSE, clsid);
|
||||||
|
if (FAILED(hr))
|
||||||
|
hr = FindExeCplClass(Canonical, HKEY_LOCAL_MACHINE, TRUE, clsid);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT WINAPI COpenControlPanel::Open(LPCWSTR pszName, LPCWSTR pszPage, IUnknown *punkSite)
|
||||||
|
{
|
||||||
|
WCHAR path[MAX_PATH], clspath[MAX_PATH];
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
SHELLEXECUTEINFOW sei = { sizeof(sei), SEE_MASK_FLAG_DDEWAIT };
|
||||||
|
sei.lpFile = path;
|
||||||
|
sei.nShow = SW_SHOW;
|
||||||
|
if (!pszName)
|
||||||
|
{
|
||||||
|
GetSystemDirectoryW(path, _countof(path));
|
||||||
|
PathAppendW(path, L"control.exe");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LPWSTR clsid = clspath + wsprintfW(clspath, L"CLSID\\");
|
||||||
|
if (SUCCEEDED(hr = FindExeCplClass(pszName, clsid)))
|
||||||
|
{
|
||||||
|
if (SUCCEEDED(hr = CreateCplAbsoluteParsingPath(L"::", clsid, path, _countof(path))))
|
||||||
|
{
|
||||||
|
// NT6 will execute "::{26EE0668-A00A-44D7-9371-BEB064C98683}\0\::{clsid}[\pszPage]"
|
||||||
|
// but we don't support parsing that so we force the class instead.
|
||||||
|
sei.fMask |= SEE_MASK_CLASSNAME;
|
||||||
|
sei.lpClass = clspath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
DWORD error = ShellExecuteExW(&sei) ? ERROR_SUCCESS : GetLastError();
|
||||||
|
hr = HRESULT_FROM_WIN32(error);
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT WINAPI COpenControlPanel::GetPath(LPCWSTR pszName, LPWSTR pszPath, UINT cchPath)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
if (!pszName)
|
||||||
|
{
|
||||||
|
PWSTR cpfolder;
|
||||||
|
if (SUCCEEDED(hr = GetParsingName((PCIDLIST_ABSOLUTE)CSIDL_CONTROLS, &cpfolder)))
|
||||||
|
{
|
||||||
|
hr = StringCchCopyW(pszPath, cchPath, cpfolder);
|
||||||
|
SHFree(cpfolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WCHAR clsid[38 + 1];
|
||||||
|
if (SUCCEEDED(hr = FindExeCplClass(pszName, clsid)))
|
||||||
|
{
|
||||||
|
hr = CreateCplAbsoluteParsingPath(L"::", clsid, pszPath, cchPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT WINAPI COpenControlPanel::GetCurrentView(CPVIEW *pView)
|
||||||
|
{
|
||||||
|
*pView = CPVIEW_CLASSIC;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -111,4 +111,25 @@ public:
|
||||||
END_COM_MAP()
|
END_COM_MAP()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class COpenControlPanel :
|
||||||
|
public CComCoClass<COpenControlPanel, &CLSID_OpenControlPanel>,
|
||||||
|
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||||
|
public IOpenControlPanel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// IOpenControlPanel
|
||||||
|
virtual HRESULT WINAPI Open(LPCWSTR pszName, LPCWSTR pszPage, IUnknown *punkSite);
|
||||||
|
virtual HRESULT WINAPI GetPath(LPCWSTR pszName, LPWSTR pszPath, UINT cchPath);
|
||||||
|
virtual HRESULT WINAPI GetCurrentView(CPVIEW *pView);
|
||||||
|
|
||||||
|
static HRESULT WINAPI UpdateRegistry(BOOL bRegister) { return S_OK; } // CControlPanelFolder does it for us
|
||||||
|
DECLARE_NOT_AGGREGATABLE(COpenControlPanel)
|
||||||
|
|
||||||
|
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||||
|
|
||||||
|
BEGIN_COM_MAP(COpenControlPanel)
|
||||||
|
COM_INTERFACE_ENTRY_IID(IID_IOpenControlPanel, IOpenControlPanel)
|
||||||
|
END_COM_MAP()
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* _SHFLDR_CPANEL_H_ */
|
#endif /* _SHFLDR_CPANEL_H_ */
|
||||||
|
|
|
@ -51,3 +51,25 @@ HKLM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HKCR
|
||||||
|
{
|
||||||
|
NoRemove CLSID
|
||||||
|
{
|
||||||
|
ForceRemove {06622D85-6856-4460-8DE1-A81921B41C4B} = s 'COpenControlPanel'
|
||||||
|
{
|
||||||
|
val AppID = s '{06622D85-6856-4460-8DE1-A81921B41C4B}'
|
||||||
|
InprocServer32 = s '%MODULE%'
|
||||||
|
{
|
||||||
|
val ThreadingModel = s 'Apartment'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NoRemove AppID
|
||||||
|
{
|
||||||
|
ForceRemove {06622D85-6856-4460-8DE1-A81921B41C4B} = s 'COpenControlPanel'
|
||||||
|
{
|
||||||
|
val DllSurrogate = s ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -280,6 +280,7 @@ BEGIN_OBJECT_MAP(ObjectMap)
|
||||||
OBJECT_ENTRY(CLSID_Shell, CShellDispatch)
|
OBJECT_ENTRY(CLSID_Shell, CShellDispatch)
|
||||||
OBJECT_ENTRY(CLSID_DragDropHelper, CDropTargetHelper)
|
OBJECT_ENTRY(CLSID_DragDropHelper, CDropTargetHelper)
|
||||||
OBJECT_ENTRY(CLSID_ControlPanel, CControlPanelFolder)
|
OBJECT_ENTRY(CLSID_ControlPanel, CControlPanelFolder)
|
||||||
|
OBJECT_ENTRY(CLSID_OpenControlPanel, COpenControlPanel)
|
||||||
OBJECT_ENTRY(CLSID_MyDocuments, CMyDocsFolder)
|
OBJECT_ENTRY(CLSID_MyDocuments, CMyDocsFolder)
|
||||||
OBJECT_ENTRY(CLSID_NetworkPlaces, CNetFolder)
|
OBJECT_ENTRY(CLSID_NetworkPlaces, CNetFolder)
|
||||||
OBJECT_ENTRY(CLSID_FontsFolderShortcut, CFontsFolder)
|
OBJECT_ENTRY(CLSID_FontsFolderShortcut, CFontsFolder)
|
||||||
|
|
|
@ -231,6 +231,7 @@ DEFINE_GUID(CLSID_NewMenu, 0xd969A300, 0xe7FF, 0x11D0, 0xA9, 0x3B,
|
||||||
DEFINE_GUID(IID_IShellFolderViewCB, 0x2047E320, 0xF2A9, 0x11CE, 0xAE, 0x65, 0x8, 0x00, 0x2B, 0x2E, 0x12, 0x62);
|
DEFINE_GUID(IID_IShellFolderViewCB, 0x2047E320, 0xF2A9, 0x11CE, 0xAE, 0x65, 0x8, 0x00, 0x2B, 0x2E, 0x12, 0x62);
|
||||||
DEFINE_GUID(CLSID_InternetButtons, 0x1E796980, 0x9CC5, 0x11D1, 0xA8, 0x3F, 0x0, 0xC0, 0x4F, 0xC9, 0x9D, 0x61);
|
DEFINE_GUID(CLSID_InternetButtons, 0x1E796980, 0x9CC5, 0x11D1, 0xA8, 0x3F, 0x0, 0xC0, 0x4F, 0xC9, 0x9D, 0x61);
|
||||||
DEFINE_GUID(CLSID_MenuDeskBar, 0xECD4FC4F, 0x521C, 0x11D0, 0xB7, 0x92, 0x00, 0xA0, 0xC9, 0x03, 0x12, 0xE1);
|
DEFINE_GUID(CLSID_MenuDeskBar, 0xECD4FC4F, 0x521C, 0x11D0, 0xB7, 0x92, 0x00, 0xA0, 0xC9, 0x03, 0x12, 0xE1);
|
||||||
|
DEFINE_GUID(CLSID_OpenControlPanel, 0x06622D85, 0x6856, 0x4460, 0x8D, 0xE1, 0xA8, 0x19, 0x21, 0xB4, 0x1C, 0x4B);
|
||||||
|
|
||||||
DEFINE_GUID(SID_SMenuBandChild, 0xed9cc020, 0x08b9, 0x11d1, 0x98, 0x23, 0x0, 0xc0, 0x4f, 0xd9, 0x19, 0x72);
|
DEFINE_GUID(SID_SMenuBandChild, 0xed9cc020, 0x08b9, 0x11d1, 0x98, 0x23, 0x0, 0xc0, 0x4f, 0xd9, 0x19, 0x72);
|
||||||
DEFINE_GUID(SID_SMenuBandParent, 0x8c278eec, 0x3eab, 0x11d1, 0x8c, 0xb0, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0);
|
DEFINE_GUID(SID_SMenuBandParent, 0x8c278eec, 0x3eab, 0x11d1, 0x8c, 0xb0, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0xd0);
|
||||||
|
|
|
@ -2360,6 +2360,37 @@ interface IExplorerCommandProvider : IUnknown
|
||||||
[out, iid_is(riid)] void **ppv);
|
[out, iid_is(riid)] void **ppv);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* IOpenControlPanel interface (Vista+)
|
||||||
|
*/
|
||||||
|
[
|
||||||
|
object,
|
||||||
|
uuid(D11AD862-66DE-4DF4-BF6C-1F5621996AF1),
|
||||||
|
pointer_default(unique)
|
||||||
|
]
|
||||||
|
interface IOpenControlPanel : IUnknown
|
||||||
|
{
|
||||||
|
typedef [v1_enum] enum CPVIEW
|
||||||
|
{
|
||||||
|
CPVIEW_CLASSIC = 0,
|
||||||
|
CPVIEW_CATEGORY = 1,
|
||||||
|
CPVIEW_ALLITEMS = CPVIEW_CLASSIC,
|
||||||
|
CPVIEW_HOME = CPVIEW_CATEGORY
|
||||||
|
} CPVIEW;
|
||||||
|
|
||||||
|
HRESULT Open(
|
||||||
|
[in, optional] LPCWSTR pszName,
|
||||||
|
[in, optional] LPCWSTR pszPage,
|
||||||
|
[in, optional] IUnknown *punkSite);
|
||||||
|
HRESULT GetPath(
|
||||||
|
[in, optional] LPCWSTR pszName,
|
||||||
|
[out, string, size_is(cchPath)] LPWSTR pszPath,
|
||||||
|
[in] UINT cchPath);
|
||||||
|
HRESULT GetCurrentView(
|
||||||
|
[out] CPVIEW *pView);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // __REACTOS__
|
#endif // __REACTOS__
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
Loading…
Reference in a new issue