Author: gadamopoulos
Date: Fri Apr 3 11:40:00 2015
New Revision: 67016
URL:
http://svn.reactos.org/svn/reactos?rev=67016&view=rev
Log:
[SHELL32]
- CControlPanelFolder: Factor out CCPLItemMenu class. Use it if the user selected a cpl
item and use the default context menu otherwise.
- CControlPanelFolder: Use ExpandEnvironmentStrings when enumerating applets from the
registry. Patch by Christoph.
- CCPLItemMenu: Call Control_RunDLLA directly so as to be able to run control panel
applets that don't use the cpl extension.
CORE-7755 CORE-9466
Modified:
trunk/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp
trunk/reactos/dll/win32/shell32/folders/CControlPanelFolder.h
Modified: trunk/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp [iso-8859-1]
(original)
+++ trunk/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp [iso-8859-1] Fri Apr
3 11:40:00 2015
@@ -190,9 +190,15 @@
{
DWORD nameLen = MAX_PATH;
DWORD valueLen = MAX_PATH;
+ char buffer[MAX_PATH];
if (RegEnumValueA(hkey, idx, name, &nameLen, NULL, NULL,
(LPBYTE)&value, &valueLen) != ERROR_SUCCESS)
break;
+
+ if (ExpandEnvironmentStringsA(value, buffer, MAX_PATH))
+ {
+ strcpy(value, buffer);
+ }
if (RegisterCPanelApp(value))
++cnt;
@@ -285,9 +291,6 @@
CControlPanelFolder::CControlPanelFolder()
{
pidlRoot = NULL; /* absolute pidl */
- dwAttributes = 0; /* attributes returned by GetAttributesOf FIXME: use it */
- apidl = NULL;
- cidl = 0;
}
CControlPanelFolder::~CControlPanelFolder()
@@ -521,14 +524,21 @@
*ppvOut = NULL;
if (IsEqualIID(riid, IID_IContextMenu) && (cidl >= 1)) {
- // TODO
- // create a seperate item struct
- //
- pObj = (IContextMenu *)this;
- this->apidl = apidl;
- this->cidl = cidl;
- pObj->AddRef();
- hr = S_OK;
+
+ /* HACK: We should use callbacks from CDefaultContextMenu instead of creating
one on our own */
+ BOOL bHasCpl = FALSE;
+ for (UINT i = 0; i < cidl; i++)
+ {
+ if(_ILIsCPanelStruct(apidl[i]))
+ {
+ bHasCpl = TRUE;
+ }
+ }
+
+ if (bHasCpl)
+ hr = ShellObjectCreatorInit<CCPLItemMenu>(cidl, apidl, riid,
&pObj);
+ else
+ hr = CDefFolderMenu_Create2(pidlRoot, hwndOwner, cidl, apidl,
(IShellFolder*)this, NULL, 0, NULL, (IContextMenu**)&pObj);
} else if (IsEqualIID(riid, IID_IDataObject) && (cidl >= 1)) {
hr = IDataObject_Constructor(hwndOwner, pidlRoot, apidl, cidl, (IDataObject
**)&pObj);
} else if (IsEqualIID(riid, IID_IExtractIconA) && (cidl == 1)) {
@@ -777,14 +787,29 @@
return S_OK;
}
-/**************************************************************************
-* IContextMenu2 Implementation
-*/
-
-/**************************************************************************
-* ICPanel_IContextMenu_QueryContextMenu()
-*/
-HRESULT WINAPI CControlPanelFolder::QueryContextMenu(
+
+CCPLItemMenu::CCPLItemMenu()
+{
+ m_apidl = NULL;
+ m_cidl = 0;
+}
+
+HRESULT WINAPI CCPLItemMenu::Initialize(UINT cidl, PCUITEMID_CHILD_ARRAY apidl)
+{
+ m_cidl = cidl;
+ m_apidl = const_cast<PCUITEMID_CHILD_ARRAY>(_ILCopyaPidl(apidl, m_cidl));
+ if (m_cidl && !m_apidl)
+ return E_OUTOFMEMORY;
+
+ return S_OK;
+}
+
+CCPLItemMenu::~CCPLItemMenu()
+{
+ _ILFreeaPidl(const_cast<PITEMID_CHILD *>(m_apidl), m_cidl);
+}
+
+HRESULT WINAPI CCPLItemMenu::QueryContextMenu(
HMENU hMenu,
UINT indexMenu,
UINT idCmdFirst,
@@ -818,43 +843,37 @@
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, Count);
}
+EXTERN_C
+void WINAPI Control_RunDLLA(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow);
+
/**************************************************************************
* ICPanel_IContextMenu_InvokeCommand()
*/
-HRESULT WINAPI CControlPanelFolder::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
+HRESULT WINAPI CCPLItemMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
{
WCHAR szPath[MAX_PATH];
char szTarget[MAX_PATH];
- STRRET strret;
WCHAR* pszPath;
INT Length, cLength;
CComPtr<IPersistFile> ppf;
CComPtr<IShellLinkA> isl;
HRESULT hResult;
- PIDLCPanelStruct *pcpanel = _ILGetCPanelPointer(apidl[0]);
+ PIDLCPanelStruct *pCPanel = _ILGetCPanelPointer(m_apidl[0]);
+ if(!pCPanel)
+ return E_FAIL;
TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n", this, lpcmi,
lpcmi->lpVerb, lpcmi->hwnd);
if (lpcmi->lpVerb == MAKEINTRESOURCEA(IDS_OPEN)) //FIXME
{
- LPITEMIDLIST lpIDList = ILCombine(pidlRoot, apidl[0]);
-
- if (!pcpanel)
- {
- /* UGLY HACK! */
- LPSHELLBROWSER lpSB = (LPSHELLBROWSER)SendMessageW(lpcmi->hwnd,
CWM_GETISHELLBROWSER, 0, 0);
- HRESULT hr;
-
- if (lpSB == NULL)
- return E_FAIL;
-
- hr = lpSB->BrowseObject(lpIDList, 0);
- return hr;
- }
-
- /* Note: we pass the applet name to Control_RunDLL to distinguish between
multiple applets in one .cpl file */
- ShellExecuteA(NULL, "cplopen", pcpanel->szName, pcpanel->szName +
pcpanel->offsDispName, NULL, 0);
+ CHAR szParams[MAX_PATH];
+
+ strcpy(szParams, pCPanel->szName);
+ strcat(szParams, ",");
+ strcat(szParams, pCPanel->szName + pCPanel->offsDispName);
+
+ Control_RunDLLA (NULL, NULL, szParams, SW_NORMAL);
}
else if (lpcmi->lpVerb == MAKEINTRESOURCEA(IDS_CREATELINK)) //FIXME
{
@@ -865,18 +884,17 @@
if (!pszPath)
return E_FAIL;
- if (GetDisplayNameOf(apidl[0], SHGDN_FORPARSING, &strret) != S_OK)
- return E_FAIL;
+ CHAR* pszDisplayName = pCPanel->szName + pCPanel->offsDispName;
Length = MAX_PATH - (pszPath - szPath);
- cLength = strlen(strret.cStr);
+ cLength = strlen(pszDisplayName);
if (Length < cLength + 5)
{
FIXME("\n");
return E_FAIL;
}
- if (MultiByteToWideChar(CP_ACP, 0, strret.cStr, cLength + 1, pszPath, Length))
+ if (MultiByteToWideChar(CP_ACP, 0, pszDisplayName, cLength + 1, pszPath,
Length))
{
pszPath += cLength;
Length -= cLength;
@@ -893,16 +911,8 @@
}
wcscpy(pszPath, L".lnk");
- pcpanel = _ILGetCPanelPointer(ILFindLastID(apidl[0]));
- if (pcpanel)
- {
- strncpy(szTarget, pcpanel->szName, MAX_PATH);
- }
- else
- {
- FIXME("Couldn't retrieve pointer to cpl structure\n");
- return E_FAIL;
- }
+ strncpy(szTarget, pCPanel->szName, MAX_PATH);
+
hResult = CShellLink::_CreatorClass::CreateInstance(NULL,
IID_PPV_ARG(IShellLinkA, &isl));
if (SUCCEEDED(hResult))
{
@@ -919,7 +929,7 @@
* ICPanel_IContextMenu_GetCommandString()
*
*/
-HRESULT WINAPI CControlPanelFolder::GetCommandString(
+HRESULT WINAPI CCPLItemMenu::GetCommandString(
UINT_PTR idCommand,
UINT uFlags,
UINT* lpReserved,
@@ -935,7 +945,7 @@
/**************************************************************************
* ICPanel_IContextMenu_HandleMenuMsg()
*/
-HRESULT WINAPI CControlPanelFolder::HandleMenuMsg(
+HRESULT WINAPI CCPLItemMenu::HandleMenuMsg(
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
Modified: trunk/reactos/dll/win32/shell32/folders/CControlPanelFolder.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CControlPanelFolder.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/folders/CControlPanelFolder.h [iso-8859-1] Fri Apr 3
11:40:00 2015
@@ -26,15 +26,12 @@
public CComCoClass<CControlPanelFolder, &CLSID_ControlPanel>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellFolder2,
- public IPersistFolder2,
- public IContextMenu2
+ public IPersistFolder2
{
private:
/* both paths are parsible from the desktop */
LPITEMIDLIST pidlRoot; /* absolute pidl */
int dwAttributes; /* attributes returned by GetAttributesOf FIXME: use it
*/
- LPCITEMIDLIST *apidl;
- UINT cidl;
HRESULT WINAPI ExecuteFromIdList(LPCITEMIDLIST pidl);
@@ -73,14 +70,6 @@
// IPersistFolder2
virtual HRESULT WINAPI GetCurFolder(LPITEMIDLIST * pidl);
- // IContextMenu
- virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT
idCmdFirst, UINT idCmdLast, UINT uFlags);
- virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi);
- virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT
*lpReserved, LPSTR lpszName, UINT uMaxNameLen);
-
- // IContextMenu2
- virtual HRESULT WINAPI HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam);
-
DECLARE_REGISTRY_RESOURCEID(IDR_CONTROLPANEL)
DECLARE_NOT_AGGREGATABLE(CControlPanelFolder)
@@ -92,9 +81,35 @@
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
- COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
- COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
END_COM_MAP()
};
+class CCPLItemMenu:
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IContextMenu2
+{
+private:
+ LPCITEMIDLIST *m_apidl;
+ UINT m_cidl;
+
+public:
+ CCPLItemMenu();
+ ~CCPLItemMenu();
+ HRESULT WINAPI Initialize(UINT cidl, PCUITEMID_CHILD_ARRAY apidl);
+ HRESULT WINAPI FinalConstruct();
+
+ // IContextMenu
+ virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst,
UINT idCmdLast, UINT uFlags);
+ virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi);
+ virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT
*lpReserved, LPSTR lpszName, UINT uMaxNameLen);
+
+ // IContextMenu2
+ virtual HRESULT WINAPI HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ BEGIN_COM_MAP(CCPLItemMenu)
+ COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
+ COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
+ END_COM_MAP()
+};
+
#endif /* _SHFLDR_CPANEL_H_ */