4 * Copyright 2003 Martin Fuchs
5 * Copyright 2009 Andrew Hill
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
26 /***********************************************************************
27 * control panel implementation in shell namespace
30 class CControlPanelEnum
:
31 public CEnumIDListBase
36 HRESULT WINAPI
Initialize(DWORD dwFlags
);
37 BOOL
RegisterCPanelApp(LPCWSTR path
);
38 int RegisterRegistryCPanelApps(HKEY hkey_root
, LPCWSTR szRepPath
);
39 int RegisterCPanelFolders(HKEY hkey_root
, LPCWSTR szRepPath
);
40 BOOL
CreateCPanelEnumList(DWORD dwFlags
);
42 BEGIN_COM_MAP(CControlPanelEnum
)
43 COM_INTERFACE_ENTRY_IID(IID_IEnumIDList
, IEnumIDList
)
47 /***********************************************************************
48 * IShellFolder [ControlPanel] implementation
51 static const shvheader ControlPanelSFHeader
[] = {
52 {IDS_SHV_COLUMN8
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 20},/*FIXME*/
53 {IDS_SHV_COLUMN9
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 80},/*FIXME*/
56 #define CONROLPANELSHELLVIEWCOLUMNS 2
58 CControlPanelEnum::CControlPanelEnum()
62 CControlPanelEnum::~CControlPanelEnum()
66 HRESULT WINAPI
CControlPanelEnum::Initialize(DWORD dwFlags
)
68 if (CreateCPanelEnumList(dwFlags
) == FALSE
)
73 static LPITEMIDLIST
_ILCreateCPanelApplet(LPCWSTR pszName
, LPCWSTR pszDisplayName
, LPCWSTR pszComment
, int iIconIdx
)
75 PIDLCPanelStruct
*pCP
;
78 int cchName
, cchDisplayName
, cchComment
, cbData
;
80 /* Calculate lengths of given strings */
81 cchName
= wcslen(pszName
);
82 cchDisplayName
= wcslen(pszDisplayName
);
83 cchComment
= wcslen(pszComment
);
86 cbData
= sizeof(pidl
->mkid
.cb
) + sizeof(pData
->type
) + sizeof(pData
->u
.cpanel
) - sizeof(pData
->u
.cpanel
.szName
)
87 + (cchName
+ cchDisplayName
+ cchComment
+ 3) * sizeof(WCHAR
);
88 pidl
= (LPITEMIDLIST
)SHAlloc(cbData
+ sizeof(WORD
));
92 /* Copy data to allocated memory */
93 pidl
->mkid
.cb
= cbData
;
94 pData
= (PIDLDATA
*)pidl
->mkid
.abID
;
95 pData
->type
= PT_CPLAPPLET
;
97 pCP
= &pData
->u
.cpanel
;
99 pCP
->iconIdx
= iIconIdx
;
100 wcscpy(pCP
->szName
, pszName
);
101 pCP
->offsDispName
= cchName
+ 1;
102 wcscpy(pCP
->szName
+ pCP
->offsDispName
, pszDisplayName
);
103 pCP
->offsComment
= pCP
->offsDispName
+ cchDisplayName
+ 1;
104 wcscpy(pCP
->szName
+ pCP
->offsComment
, pszComment
);
106 /* Add PIDL NULL terminator */
107 *(WORD
*)(pCP
->szName
+ pCP
->offsComment
+ cchComment
+ 1) = 0;
114 /**************************************************************************
115 * _ILGetCPanelPointer()
116 * gets a pointer to the control panel struct stored in the pidl
118 static PIDLCPanelStruct
*_ILGetCPanelPointer(LPCITEMIDLIST pidl
)
120 LPPIDLDATA pdata
= _ILGetDataPointer(pidl
);
122 if (pdata
&& pdata
->type
== PT_CPLAPPLET
)
123 return (PIDLCPanelStruct
*) & (pdata
->u
.cpanel
);
128 BOOL
CControlPanelEnum::RegisterCPanelApp(LPCWSTR wpath
)
130 CPlApplet
* applet
= Control_LoadApplet(0, wpath
, NULL
);
135 for (UINT i
= 0; i
< applet
->count
; ++i
)
137 if (applet
->info
[i
].idIcon
> 0)
138 iconIdx
= -applet
->info
[i
].idIcon
; /* negative icon index instead of icon number */
142 LPITEMIDLIST pidl
= _ILCreateCPanelApplet(wpath
,
143 applet
->info
[i
].name
,
144 applet
->info
[i
].info
,
150 Control_UnloadApplet(applet
);
155 int CControlPanelEnum::RegisterRegistryCPanelApps(HKEY hkey_root
, LPCWSTR szRepPath
)
157 WCHAR name
[MAX_PATH
];
158 WCHAR value
[MAX_PATH
];
163 if (RegOpenKeyW(hkey_root
, szRepPath
, &hkey
) == ERROR_SUCCESS
)
169 DWORD nameLen
= MAX_PATH
;
170 DWORD valueLen
= MAX_PATH
;
171 WCHAR buffer
[MAX_PATH
];
173 if (RegEnumValueW(hkey
, idx
, name
, &nameLen
, NULL
, NULL
, (LPBYTE
)&value
, &valueLen
) != ERROR_SUCCESS
)
176 if (ExpandEnvironmentStringsW(value
, buffer
, MAX_PATH
))
178 wcscpy(value
, buffer
);
181 if (RegisterCPanelApp(value
))
190 int CControlPanelEnum::RegisterCPanelFolders(HKEY hkey_root
, LPCWSTR szRepPath
)
192 WCHAR name
[MAX_PATH
];
197 if (RegOpenKeyW(hkey_root
, szRepPath
, &hkey
) == ERROR_SUCCESS
)
199 for (int idx
= 0; ; idx
++)
201 if (RegEnumKeyW(hkey
, idx
, name
, MAX_PATH
) != ERROR_SUCCESS
)
206 LPITEMIDLIST pidl
= _ILCreateGuidFromStrW(name
);
208 if (pidl
&& AddToEnumList(pidl
))
219 /**************************************************************************
220 * CControlPanelEnum::CreateCPanelEnumList()
222 BOOL
CControlPanelEnum::CreateCPanelEnumList(DWORD dwFlags
)
224 WCHAR szPath
[MAX_PATH
];
225 WIN32_FIND_DATAW wfd
;
228 TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags
);
230 /* enumerate control panel folders */
231 if (dwFlags
& SHCONTF_FOLDERS
)
232 RegisterCPanelFolders(HKEY_LOCAL_MACHINE
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace");
234 /* enumerate the control panel applets */
235 if (dwFlags
& SHCONTF_NONFOLDERS
)
239 GetSystemDirectoryW(szPath
, MAX_PATH
);
240 p
= PathAddBackslashW(szPath
);
243 hFile
= FindFirstFileW(szPath
, &wfd
);
245 if (hFile
!= INVALID_HANDLE_VALUE
)
249 if (!(dwFlags
& SHCONTF_INCLUDEHIDDEN
) && (wfd
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
))
252 if (!(wfd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)) {
253 wcscpy(p
, wfd
.cFileName
);
254 if (wcscmp(wfd
.cFileName
, L
"ncpa.cpl"))
255 RegisterCPanelApp(szPath
);
257 } while(FindNextFileW(hFile
, &wfd
));
261 RegisterRegistryCPanelApps(HKEY_LOCAL_MACHINE
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls");
262 RegisterRegistryCPanelApps(HKEY_CURRENT_USER
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls");
267 CControlPanelFolder::CControlPanelFolder()
269 pidlRoot
= NULL
; /* absolute pidl */
272 CControlPanelFolder::~CControlPanelFolder()
274 TRACE("-- destroying IShellFolder(%p)\n", this);
278 HRESULT WINAPI
CControlPanelFolder::FinalConstruct()
280 pidlRoot
= _ILCreateControlPanel(); /* my qualified pidl */
281 if (pidlRoot
== NULL
)
282 return E_OUTOFMEMORY
;
286 /**************************************************************************
287 * CControlPanelFolder::ParseDisplayName
289 HRESULT WINAPI
CControlPanelFolder::ParseDisplayName(
292 LPOLESTR lpszDisplayName
,
294 PIDLIST_RELATIVE
*ppidl
,
295 DWORD
*pdwAttributes
)
297 /* We only support parsing guid names */
298 return SH_ParseGuidDisplayName(this, hwndOwner
, pbc
, lpszDisplayName
, pchEaten
, ppidl
, pdwAttributes
);
301 /**************************************************************************
302 * CControlPanelFolder::EnumObjects
304 HRESULT WINAPI
CControlPanelFolder::EnumObjects(HWND hwndOwner
, DWORD dwFlags
, LPENUMIDLIST
*ppEnumIDList
)
306 return ShellObjectCreatorInit
<CControlPanelEnum
>(dwFlags
, IID_IEnumIDList
, ppEnumIDList
);
309 /**************************************************************************
310 * CControlPanelFolder::BindToObject
312 HRESULT WINAPI
CControlPanelFolder::BindToObject(
313 PCUIDLIST_RELATIVE pidl
,
318 return SHELL32_BindToGuidItem(pidlRoot
, pidl
, pbcReserved
, riid
, ppvOut
);
321 /**************************************************************************
322 * CControlPanelFolder::BindToStorage
324 HRESULT WINAPI
CControlPanelFolder::BindToStorage(
325 PCUIDLIST_RELATIVE pidl
,
330 FIXME("(%p)->(pidl=%p,%p,%s,%p) stub\n", this, pidl
, pbcReserved
, shdebugstr_guid(&riid
), ppvOut
);
336 /**************************************************************************
337 * CControlPanelFolder::CompareIDs
339 HRESULT WINAPI
CControlPanelFolder::CompareIDs(LPARAM lParam
, PCUIDLIST_RELATIVE pidl1
, PCUIDLIST_RELATIVE pidl2
)
341 /* Dont use SHELL32_CompareGuidItems because it would cause guid items to come first */
342 if (_ILIsSpecialFolder(pidl1
) || _ILIsSpecialFolder(pidl2
))
344 return SHELL32_CompareDetails(this, lParam
, pidl1
, pidl2
);
346 PIDLCPanelStruct
*pData1
= _ILGetCPanelPointer(pidl1
);
347 PIDLCPanelStruct
*pData2
= _ILGetCPanelPointer(pidl2
);
349 if (!pData1
|| !pData2
|| LOWORD(lParam
)>= CONROLPANELSHELLVIEWCOLUMNS
)
353 switch(LOWORD(lParam
))
356 result
= wcsicmp(pData1
->szName
+ pData1
->offsDispName
, pData2
->szName
+ pData2
->offsDispName
);
358 case 1: /* comment */
359 result
= wcsicmp(pData1
->szName
+ pData1
->offsComment
, pData2
->szName
+ pData2
->offsComment
);
362 ERR("Got wrong lParam!\n");
366 return MAKE_COMPARE_HRESULT(result
);
369 /**************************************************************************
370 * CControlPanelFolder::CreateViewObject
372 HRESULT WINAPI
CControlPanelFolder::CreateViewObject(HWND hwndOwner
, REFIID riid
, LPVOID
* ppvOut
)
374 CComPtr
<IShellView
> pShellView
;
375 HRESULT hr
= E_INVALIDARG
;
377 TRACE("(%p)->(hwnd=%p,%s,%p)\n", this, hwndOwner
, shdebugstr_guid(&riid
), ppvOut
);
382 if (IsEqualIID(riid
, IID_IDropTarget
)) {
383 WARN("IDropTarget not implemented\n");
385 } else if (IsEqualIID(riid
, IID_IContextMenu
)) {
386 WARN("IContextMenu not implemented\n");
388 } else if (IsEqualIID(riid
, IID_IShellView
)) {
389 hr
= CDefView_Constructor(this, riid
, ppvOut
);
392 TRACE("--(%p)->(interface=%p)\n", this, ppvOut
);
396 /**************************************************************************
397 * CControlPanelFolder::GetAttributesOf
399 HRESULT WINAPI
CControlPanelFolder::GetAttributesOf(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, DWORD
* rgfInOut
)
402 static const DWORD dwControlPanelAttributes
=
403 SFGAO_HASSUBFOLDER
| SFGAO_FOLDER
| SFGAO_CANLINK
;
405 TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
406 this, cidl
, apidl
, rgfInOut
, rgfInOut
? *rgfInOut
: 0);
418 *rgfInOut
&= dwControlPanelAttributes
;
422 while(cidl
> 0 && *apidl
)
425 if (_ILIsCPanelStruct(*apidl
))
426 *rgfInOut
&= SFGAO_CANLINK
;
427 else if (_ILIsSpecialFolder(*apidl
))
428 SHELL32_GetGuidItemAttributes(this, *apidl
, rgfInOut
);
430 ERR("Got an unkown pidl here!\n");
435 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
436 *rgfInOut
&= ~SFGAO_VALIDATE
;
438 TRACE("-- result=0x%08x\n", *rgfInOut
);
442 /**************************************************************************
443 * CControlPanelFolder::GetUIObjectOf
446 * HWND hwndOwner, //[in ] Parent window for any output
447 * UINT cidl, //[in ] array size
448 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
449 * REFIID riid, //[in ] Requested Interface
450 * UINT* prgfInOut, //[ ] reserved
451 * LPVOID* ppvObject) //[out] Resulting Interface
454 HRESULT WINAPI
CControlPanelFolder::GetUIObjectOf(HWND hwndOwner
,
455 UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, REFIID riid
, UINT
* prgfInOut
, LPVOID
* ppvOut
)
458 IUnknown
*pObj
= NULL
;
459 HRESULT hr
= E_INVALIDARG
;
461 TRACE("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
462 this, hwndOwner
, cidl
, apidl
, shdebugstr_guid(&riid
), prgfInOut
, ppvOut
);
467 if (IsEqualIID(riid
, IID_IContextMenu
) && (cidl
>= 1)) {
469 /* HACK: We should use callbacks from CDefaultContextMenu instead of creating one on our own */
470 BOOL bHasCpl
= FALSE
;
471 for (UINT i
= 0; i
< cidl
; i
++)
473 if(_ILIsCPanelStruct(apidl
[i
]))
480 hr
= ShellObjectCreatorInit
<CCPLItemMenu
>(cidl
, apidl
, riid
, &pObj
);
482 hr
= CDefFolderMenu_Create2(pidlRoot
, hwndOwner
, cidl
, apidl
, (IShellFolder
*)this, NULL
, 0, NULL
, (IContextMenu
**)&pObj
);
483 } else if (IsEqualIID(riid
, IID_IDataObject
) && (cidl
>= 1)) {
484 hr
= IDataObject_Constructor(hwndOwner
, pidlRoot
, apidl
, cidl
, (IDataObject
**)&pObj
);
485 } else if (IsEqualIID(riid
, IID_IExtractIconA
) && (cidl
== 1)) {
486 pidl
= ILCombine(pidlRoot
, apidl
[0]);
487 pObj
= IExtractIconA_Constructor(pidl
);
490 } else if (IsEqualIID(riid
, IID_IExtractIconW
) && (cidl
== 1)) {
491 pidl
= ILCombine(pidlRoot
, apidl
[0]);
492 pObj
= IExtractIconW_Constructor(pidl
);
495 } else if ((IsEqualIID(riid
, IID_IShellLinkW
) || IsEqualIID(riid
, IID_IShellLinkA
))
497 pidl
= ILCombine(pidlRoot
, apidl
[0]);
498 hr
= IShellLink_ConstructFromFile(NULL
, riid
, pidl
, (LPVOID
*)&pObj
);
504 if (SUCCEEDED(hr
) && !pObj
)
509 TRACE("(%p)->hr=0x%08x\n", this, hr
);
513 /**************************************************************************
514 * CControlPanelFolder::GetDisplayNameOf
516 HRESULT WINAPI
CControlPanelFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl
, DWORD dwFlags
, LPSTRRET strRet
)
521 PIDLCPanelStruct
*pCPanel
= _ILGetCPanelPointer(pidl
);
525 return SHSetStrRet(strRet
, pCPanel
->szName
+ pCPanel
->offsDispName
);
527 else if (_ILIsSpecialFolder(pidl
))
529 static const WCHAR
* pszCPanelPath
= L
"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}";
530 return SHELL32_GetDisplayNameOfGUIDItem(this, pszCPanelPath
, pidl
, dwFlags
, strRet
);
536 /**************************************************************************
537 * CControlPanelFolder::SetNameOf
538 * Changes the name of a file object or subfolder, possibly changing its item
539 * identifier in the process.
542 * HWND hwndOwner, //[in ] Owner window for output
543 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
544 * LPCOLESTR lpszName, //[in ] the items new display name
545 * DWORD dwFlags, //[in ] SHGNO formatting flags
546 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
548 HRESULT WINAPI
CControlPanelFolder::SetNameOf(HWND hwndOwner
, PCUITEMID_CHILD pidl
, /*simple pidl */
549 LPCOLESTR lpName
, DWORD dwFlags
, PITEMID_CHILD
*pPidlOut
)
551 FIXME("(%p)->(%p,pidl=%p,%s,%u,%p)\n", this, hwndOwner
, pidl
, debugstr_w(lpName
), dwFlags
, pPidlOut
);
555 HRESULT WINAPI
CControlPanelFolder::GetDefaultSearchGUID(GUID
*pguid
)
557 FIXME("(%p)\n", this);
561 HRESULT WINAPI
CControlPanelFolder::EnumSearches(IEnumExtraSearch
**ppenum
)
563 FIXME("(%p)\n", this);
567 HRESULT WINAPI
CControlPanelFolder::GetDefaultColumn(DWORD dwRes
, ULONG
*pSort
, ULONG
*pDisplay
)
569 TRACE("(%p)\n", this);
571 if (pSort
) *pSort
= 0;
572 if (pDisplay
) *pDisplay
= 0;
576 HRESULT WINAPI
CControlPanelFolder::GetDefaultColumnState(UINT iColumn
, DWORD
*pcsFlags
)
578 TRACE("(%p)\n", this);
580 if (!pcsFlags
|| iColumn
>= CONROLPANELSHELLVIEWCOLUMNS
) return E_INVALIDARG
;
581 *pcsFlags
= ControlPanelSFHeader
[iColumn
].pcsFlags
;
585 HRESULT WINAPI
CControlPanelFolder::GetDetailsEx(PCUITEMID_CHILD pidl
, const SHCOLUMNID
*pscid
, VARIANT
*pv
)
587 FIXME("(%p)\n", this);
591 HRESULT WINAPI
CControlPanelFolder::GetDetailsOf(PCUITEMID_CHILD pidl
, UINT iColumn
, SHELLDETAILS
*psd
)
593 if (!psd
|| iColumn
>= CONROLPANELSHELLVIEWCOLUMNS
)
598 psd
->fmt
= ControlPanelSFHeader
[iColumn
].fmt
;
599 psd
->cxChar
= ControlPanelSFHeader
[iColumn
].cxChar
;
600 return SHSetStrRet(&psd
->str
, shell32_hInstance
, ControlPanelSFHeader
[iColumn
].colnameid
);
602 else if (_ILIsSpecialFolder(pidl
))
604 return SHELL32_GetDetailsOfGuidItem(this, pidl
, iColumn
, psd
);
608 PIDLCPanelStruct
*pCPanel
= _ILGetCPanelPointer(pidl
);
616 return SHSetStrRet(&psd
->str
, pCPanel
->szName
+ pCPanel
->offsDispName
);
617 case 1: /* comment */
618 return SHSetStrRet(&psd
->str
, pCPanel
->szName
+ pCPanel
->offsComment
);
625 HRESULT WINAPI
CControlPanelFolder::MapColumnToSCID(UINT column
, SHCOLUMNID
*pscid
)
627 FIXME("(%p)\n", this);
631 /************************************************************************
632 * CControlPanelFolder::GetClassID
634 HRESULT WINAPI
CControlPanelFolder::GetClassID(CLSID
*lpClassId
)
636 TRACE("(%p)\n", this);
640 *lpClassId
= CLSID_ControlPanel
;
645 /************************************************************************
646 * CControlPanelFolder::Initialize
648 * NOTES: it makes no sense to change the pidl
650 HRESULT WINAPI
CControlPanelFolder::Initialize(LPCITEMIDLIST pidl
)
653 SHFree((LPVOID
)pidlRoot
);
655 pidlRoot
= ILClone(pidl
);
659 /**************************************************************************
660 * CControlPanelFolder::GetCurFolder
662 HRESULT WINAPI
CControlPanelFolder::GetCurFolder(LPITEMIDLIST
* pidl
)
664 TRACE("(%p)->(%p)\n", this, pidl
);
668 *pidl
= ILClone(pidlRoot
);
672 HRESULT
CPanel_GetIconLocationW(LPCITEMIDLIST pidl
, LPWSTR szIconFile
, UINT cchMax
, int* piIndex
)
674 PIDLCPanelStruct
* pcpanel
= _ILGetCPanelPointer(pidl
);
679 wcsncpy(szIconFile
, pcpanel
->szName
, cchMax
);
680 *piIndex
= (int)pcpanel
->iconIdx
!= -1 ? pcpanel
->iconIdx
: 0;
686 CCPLItemMenu::CCPLItemMenu()
692 HRESULT WINAPI
CCPLItemMenu::Initialize(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
)
695 m_apidl
= _ILCopyaPidl(apidl
, m_cidl
);
696 if (m_cidl
&& !m_apidl
)
697 return E_OUTOFMEMORY
;
702 CCPLItemMenu::~CCPLItemMenu()
704 _ILFreeaPidl(m_apidl
, m_cidl
);
707 HRESULT WINAPI
CCPLItemMenu::QueryContextMenu(
714 _InsertMenuItemW(hMenu
, indexMenu
++, TRUE
, IDS_OPEN
, MFT_STRING
, MAKEINTRESOURCEW(IDS_OPEN
), MFS_DEFAULT
);
715 _InsertMenuItemW(hMenu
, indexMenu
++, TRUE
, idCmdFirst
+ 1, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
716 _InsertMenuItemW(hMenu
, indexMenu
++, TRUE
, IDS_CREATELINK
, MFT_STRING
, MAKEINTRESOURCEW(IDS_CREATELINK
), MFS_ENABLED
);
718 return MAKE_HRESULT(SEVERITY_SUCCESS
, 0, 2);
722 void WINAPI
Control_RunDLLW(HWND hWnd
, HINSTANCE hInst
, LPCWSTR cmd
, DWORD nCmdShow
);
724 /**************************************************************************
725 * ICPanel_IContextMenu_InvokeCommand()
727 HRESULT WINAPI
CCPLItemMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi
)
731 PIDLCPanelStruct
*pCPanel
= _ILGetCPanelPointer(m_apidl
[0]);
735 TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n", this, lpcmi
, lpcmi
->lpVerb
, lpcmi
->hwnd
);
737 if (lpcmi
->lpVerb
== MAKEINTRESOURCEA(IDS_OPEN
)) //FIXME
739 /* Hardcode the command here; Executing a cpl file would be fine but we also need to run things like console.dll */
740 WCHAR wszParams
[MAX_PATH
];
741 PCWSTR wszFile
= L
"rundll32.exe";
742 PCWSTR wszFormat
= L
"shell32.dll,Control_RunDLL %s,%s";
744 wsprintfW(wszParams
, wszFormat
, pCPanel
->szName
, pCPanel
->szName
+ pCPanel
->offsDispName
);
746 /* Note: we pass the applet name to Control_RunDLL to distinguish between multiple applets in one .cpl file */
747 ShellExecuteW(NULL
, NULL
, wszFile
, wszParams
, NULL
, 0);
749 else if (lpcmi
->lpVerb
== MAKEINTRESOURCEA(IDS_CREATELINK
)) //FIXME
751 CComPtr
<IDataObject
> pDataObj
;
752 LPITEMIDLIST pidl
= _ILCreateControlPanel();
754 hResult
= SHCreateDataObject(pidl
, m_cidl
, m_apidl
, NULL
, IID_PPV_ARG(IDataObject
, &pDataObj
));
760 //FIXME: Use SHCreateLinks
761 CComPtr
<IShellFolder
> psf
;
762 CComPtr
<IDropTarget
> pDT
;
764 hResult
= SHGetDesktopFolder(&psf
);
768 hResult
= psf
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
, &pDT
));
772 SHSimulateDrop(pDT
, pDataObj
, MK_CONTROL
|MK_SHIFT
, NULL
, NULL
);
777 /**************************************************************************
778 * ICPanel_IContextMenu_GetCommandString()
781 HRESULT WINAPI
CCPLItemMenu::GetCommandString(
788 TRACE("(%p)->(idcom=%lx flags=%x %p name=%p len=%x)\n", this, idCommand
, uFlags
, lpReserved
, lpszName
, uMaxNameLen
);
790 FIXME("unknown command string\n");
794 /**************************************************************************
795 * ICPanel_IContextMenu_HandleMenuMsg()
797 HRESULT WINAPI
CCPLItemMenu::HandleMenuMsg(
802 TRACE("ICPanel_IContextMenu_HandleMenuMsg (%p)->(msg=%x wp=%lx lp=%lx)\n", this, uMsg
, wParam
, lParam
);