* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-/*
-TODO:
-1. The selected items list should not be stored in CControlPanelFolder, it should
- be a result returned by an internal method.
-*/
-
#include <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
public:
CControlPanelEnum();
~CControlPanelEnum();
- HRESULT WINAPI Initialize(DWORD dwFlags);
- BOOL RegisterCPanelApp(LPCSTR path);
- int RegisterRegistryCPanelApps(HKEY hkey_root, LPCSTR szRepPath);
- int RegisterCPanelFolders(HKEY hkey_root, LPCSTR szRepPath);
+ HRESULT WINAPI Initialize(DWORD dwFlags, IEnumIDList* pRegEnumerator);
+ BOOL RegisterCPanelApp(LPCWSTR path);
+ int RegisterRegistryCPanelApps(HKEY hkey_root, LPCWSTR szRepPath);
BOOL CreateCPanelEnumList(DWORD dwFlags);
BEGIN_COM_MAP(CControlPanelEnum)
*/
static const shvheader ControlPanelSFHeader[] = {
- {IDS_SHV_COLUMN8, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},/*FIXME*/
- {IDS_SHV_COLUMN9, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 200},/*FIXME*/
+ {IDS_SHV_COLUMN_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 20},/*FIXME*/
+ {IDS_SHV_COLUMN_COMMENTS, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 80},/*FIXME*/
};
#define CONROLPANELSHELLVIEWCOLUMNS 2
{
}
-HRESULT WINAPI CControlPanelEnum::Initialize(DWORD dwFlags)
+HRESULT WINAPI CControlPanelEnum::Initialize(DWORD dwFlags, IEnumIDList* pRegEnumerator)
{
if (CreateCPanelEnumList(dwFlags) == FALSE)
return E_FAIL;
+ AppendItemsFromEnumerator(pRegEnumerator);
return S_OK;
}
-static LPITEMIDLIST _ILCreateCPanelApplet(LPCSTR pszName, LPCSTR pszDisplayName, LPCSTR pszComment, int iIconIdx)
+static LPITEMIDLIST _ILCreateCPanelApplet(LPCWSTR pszName, LPCWSTR pszDisplayName, LPCWSTR pszComment, int iIconIdx)
{
PIDLCPanelStruct *pCP;
LPITEMIDLIST pidl;
int cchName, cchDisplayName, cchComment, cbData;
/* Calculate lengths of given strings */
- cchName = strlen(pszName);
- cchDisplayName = strlen(pszDisplayName);
- cchComment = strlen(pszComment);
+ cchName = wcslen(pszName);
+ cchDisplayName = wcslen(pszDisplayName);
+ cchComment = wcslen(pszComment);
/* Allocate PIDL */
cbData = sizeof(pidl->mkid.cb) + sizeof(pData->type) + sizeof(pData->u.cpanel) - sizeof(pData->u.cpanel.szName)
- + cchName + cchDisplayName + cchComment + 3;
+ + (cchName + cchDisplayName + cchComment + 3) * sizeof(WCHAR);
pidl = (LPITEMIDLIST)SHAlloc(cbData + sizeof(WORD));
if (!pidl)
return NULL;
pCP = &pData->u.cpanel;
pCP->dummy = 0;
pCP->iconIdx = iIconIdx;
- strcpy(pCP->szName, pszName);
+ wcscpy(pCP->szName, pszName);
pCP->offsDispName = cchName + 1;
- strcpy(pCP->szName + pCP->offsDispName, pszDisplayName);
+ wcscpy(pCP->szName + pCP->offsDispName, pszDisplayName);
pCP->offsComment = pCP->offsDispName + cchDisplayName + 1;
- strcpy(pCP->szName + pCP->offsComment, pszComment);
+ wcscpy(pCP->szName + pCP->offsComment, pszComment);
/* Add PIDL NULL terminator */
*(WORD*)(pCP->szName + pCP->offsComment + cchComment + 1) = 0;
return NULL;
}
-BOOL CControlPanelEnum::RegisterCPanelApp(LPCSTR path)
+HRESULT CCPLExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID * ppvOut)
{
- LPITEMIDLIST pidl;
- CPlApplet* applet;
- CPanel panel;
- CPLINFO info;
- unsigned i;
- int iconIdx;
+ PIDLCPanelStruct *pData = _ILGetCPanelPointer(pidl);
+ if (!pData)
+ return E_FAIL;
- char displayName[MAX_PATH];
- char comment[MAX_PATH];
+ CComPtr<IDefaultExtractIconInit> initIcon;
+ HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
- WCHAR wpath[MAX_PATH];
+ initIcon->SetNormalIcon(pData->szName, (int)pData->iconIdx != -1 ? pData->iconIdx : 0);
- MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH);
+ return initIcon->QueryInterface(riid, ppvOut);
+}
- panel.first = NULL;
- applet = Control_LoadApplet(0, wpath, &panel);
+BOOL CControlPanelEnum::RegisterCPanelApp(LPCWSTR wpath)
+{
+ CPlApplet* applet = Control_LoadApplet(0, wpath, NULL);
+ int iconIdx;
if (applet)
{
- for (i = 0; i < applet->count; ++i)
+ for (UINT i = 0; i < applet->count; ++i)
{
- WideCharToMultiByte(CP_ACP, 0, applet->info[i].szName, -1, displayName, MAX_PATH, 0, 0);
- WideCharToMultiByte(CP_ACP, 0, applet->info[i].szInfo, -1, comment, MAX_PATH, 0, 0);
-
- applet->proc(0, CPL_INQUIRE, i, (LPARAM)&info);
-
- if (info.idIcon > 0)
- iconIdx = -info.idIcon; /* negative icon index instead of icon number */
+ if (applet->info[i].idIcon > 0)
+ iconIdx = -applet->info[i].idIcon; /* negative icon index instead of icon number */
else
iconIdx = 0;
- pidl = _ILCreateCPanelApplet(path, displayName, comment, iconIdx);
+ LPITEMIDLIST pidl = _ILCreateCPanelApplet(wpath,
+ applet->info[i].name,
+ applet->info[i].info,
+ iconIdx);
if (pidl)
AddToEnumList(pidl);
return TRUE;
}
-int CControlPanelEnum::RegisterRegistryCPanelApps(HKEY hkey_root, LPCSTR szRepPath)
+int CControlPanelEnum::RegisterRegistryCPanelApps(HKEY hkey_root, LPCWSTR szRepPath)
{
- char name[MAX_PATH];
- char value[MAX_PATH];
+ WCHAR name[MAX_PATH];
+ WCHAR value[MAX_PATH];
HKEY hkey;
int cnt = 0;
- if (RegOpenKeyA(hkey_root, szRepPath, &hkey) == ERROR_SUCCESS)
+ if (RegOpenKeyW(hkey_root, szRepPath, &hkey) == ERROR_SUCCESS)
{
int idx = 0;
{
DWORD nameLen = MAX_PATH;
DWORD valueLen = MAX_PATH;
+ WCHAR buffer[MAX_PATH];
- if (RegEnumValueA(hkey, idx, name, &nameLen, NULL, NULL, (LPBYTE)&value, &valueLen) != ERROR_SUCCESS)
+ if (RegEnumValueW(hkey, idx, name, &nameLen, NULL, NULL, (LPBYTE)&value, &valueLen) != ERROR_SUCCESS)
break;
- if (RegisterCPanelApp(value))
- ++cnt;
- }
- RegCloseKey(hkey);
- }
-
- return cnt;
-}
-
-int CControlPanelEnum::RegisterCPanelFolders(HKEY hkey_root, LPCSTR szRepPath)
-{
- char name[MAX_PATH];
- HKEY hkey;
-
- int cnt = 0;
-
- if (RegOpenKeyA(hkey_root, szRepPath, &hkey) == ERROR_SUCCESS)
- {
- int idx = 0;
- for (; ; idx++)
- {
- if (RegEnumKeyA(hkey, idx, name, MAX_PATH) != ERROR_SUCCESS)
- break;
-
- if (*name == '{')
+ if (ExpandEnvironmentStringsW(value, buffer, MAX_PATH))
{
- LPITEMIDLIST pidl = _ILCreateGuidFromStrA(name);
-
- if (pidl && AddToEnumList(pidl))
- ++cnt;
+ wcscpy(value, buffer);
}
- }
+ if (RegisterCPanelApp(value))
+ ++cnt;
+ }
RegCloseKey(hkey);
}
*/
BOOL CControlPanelEnum::CreateCPanelEnumList(DWORD dwFlags)
{
- CHAR szPath[MAX_PATH];
- WIN32_FIND_DATAA wfd;
+ WCHAR szPath[MAX_PATH];
+ WIN32_FIND_DATAW wfd;
HANDLE hFile;
TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags);
- /* enumerate control panel folders */
- if (dwFlags & SHCONTF_FOLDERS)
- RegisterCPanelFolders(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace");
-
/* enumerate the control panel applets */
if (dwFlags & SHCONTF_NONFOLDERS)
{
- LPSTR p;
+ LPWSTR p;
- GetSystemDirectoryA(szPath, MAX_PATH);
- p = PathAddBackslashA(szPath);
- strcpy(p, "*.cpl");
+ GetSystemDirectoryW(szPath, MAX_PATH);
+ p = PathAddBackslashW(szPath);
+ wcscpy(p, L"*.cpl");
- TRACE("-- (%p)-> enumerate SHCONTF_NONFOLDERS of %s\n", this, debugstr_a(szPath));
- hFile = FindFirstFileA(szPath, &wfd);
+ hFile = FindFirstFileW(szPath, &wfd);
if (hFile != INVALID_HANDLE_VALUE)
{
continue;
if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
- strcpy(p, wfd.cFileName);
- if (strcmp(wfd.cFileName, "ncpa.cpl"))
+ wcscpy(p, wfd.cFileName);
+ if (wcscmp(wfd.cFileName, L"ncpa.cpl"))
RegisterCPanelApp(szPath);
}
- } while(FindNextFileA(hFile, &wfd));
+ } while(FindNextFileW(hFile, &wfd));
FindClose(hFile);
}
- RegisterRegistryCPanelApps(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls");
- RegisterRegistryCPanelApps(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls");
+ RegisterRegistryCPanelApps(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls");
+ RegisterRegistryCPanelApps(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls");
}
return TRUE;
}
CControlPanelFolder::CControlPanelFolder()
{
pidlRoot = NULL; /* absolute pidl */
- dwAttributes = 0; /* attributes returned by GetAttributesOf FIXME: use it */
- apidl = NULL;
- cidl = 0;
}
CControlPanelFolder::~CControlPanelFolder()
SHFree(pidlRoot);
}
-HRESULT WINAPI CControlPanelFolder::FinalConstruct()
-{
- pidlRoot = _ILCreateControlPanel(); /* my qualified pidl */
- if (pidlRoot == NULL)
- return E_OUTOFMEMORY;
- return S_OK;
-}
-
/**************************************************************************
* CControlPanelFolder::ParseDisplayName
*/
PIDLIST_RELATIVE *ppidl,
DWORD *pdwAttributes)
{
- WCHAR szElement[MAX_PATH];
- LPCWSTR szNext = NULL;
- LPITEMIDLIST pidlTemp = NULL;
- HRESULT hr = S_OK;
- CLSID clsid;
-
- TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
- this, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName),
- pchEaten, ppidl, pdwAttributes);
-
- if (!lpszDisplayName || !ppidl)
- return E_INVALIDARG;
-
- *ppidl = 0;
-
- if (pchEaten)
- *pchEaten = 0; /* strange but like the original */
-
- if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
- {
- szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
- TRACE ("-- element: %s\n", debugstr_w (szElement));
- CLSIDFromString (szElement + 2, &clsid);
- pidlTemp = _ILCreateGuid (PT_GUID, clsid);
- }
- else if( (pidlTemp = SHELL32_CreatePidlFromBindCtx(pbc, lpszDisplayName)) )
- {
- *ppidl = pidlTemp;
- return S_OK;
- }
-
- if (SUCCEEDED(hr) && pidlTemp)
- {
- if (szNext && *szNext)
- {
- hr = SHELL32_ParseNextElement(this, hwndOwner, pbc,
- &pidlTemp, (LPOLESTR) szNext, pchEaten, pdwAttributes);
- }
- else
- {
- if (pdwAttributes && *pdwAttributes)
- hr = SHELL32_GetItemAttributes(this,
- pidlTemp, pdwAttributes);
- }
- }
-
- *ppidl = pidlTemp;
-
- TRACE ("(%p)->(-- ret=0x%08x)\n", this, hr);
-
- return hr;
+ /* We only support parsing guid names */
+ return m_regFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
}
/**************************************************************************
*/
HRESULT WINAPI CControlPanelFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
{
- return ShellObjectCreatorInit<CControlPanelEnum>(dwFlags, IID_IEnumIDList, ppEnumIDList);
+ CComPtr<IEnumIDList> pRegEnumerator;
+ m_regFolder->EnumObjects(hwndOwner, dwFlags, &pRegEnumerator);
+
+ return ShellObjectCreatorInit<CControlPanelEnum>(dwFlags, pRegEnumerator, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
}
/**************************************************************************
REFIID riid,
LPVOID *ppvOut)
{
- TRACE("(%p)->(pidl=%p,%p,%s,%p)\n", this, pidl, pbcReserved, shdebugstr_guid(&riid), ppvOut);
-
- return SHELL32_BindToChild(pidlRoot, NULL, pidl, riid, ppvOut);
+ return m_regFolder->BindToObject(pidl, pbcReserved, riid, ppvOut);
}
/**************************************************************************
/**************************************************************************
* CControlPanelFolder::CompareIDs
*/
-
HRESULT WINAPI CControlPanelFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
{
- int nReturn;
+ /* Dont use SHELL32_CompareGuidItems because it would cause guid items to come first */
+ if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2))
+ {
+ return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
+ }
+ PIDLCPanelStruct *pData1 = _ILGetCPanelPointer(pidl1);
+ PIDLCPanelStruct *pData2 = _ILGetCPanelPointer(pidl2);
- TRACE("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", this, lParam, pidl1, pidl2);
- nReturn = SHELL32_CompareIDs(this, lParam, pidl1, pidl2);
- TRACE("-- %i\n", nReturn);
- return nReturn;
+ if (!pData1 || !pData2 || LOWORD(lParam)>= CONROLPANELSHELLVIEWCOLUMNS)
+ return E_INVALIDARG;
+
+ int result;
+ switch(LOWORD(lParam))
+ {
+ case 0: /* name */
+ result = wcsicmp(pData1->szName + pData1->offsDispName, pData2->szName + pData2->offsDispName);
+ break;
+ case 1: /* comment */
+ result = wcsicmp(pData1->szName + pData1->offsComment, pData2->szName + pData2->offsComment);
+ break;
+ default:
+ ERR("Got wrong lParam!\n");
+ return E_INVALIDARG;
+ }
+
+ return MAKE_COMPARE_HRESULT(result);
}
/**************************************************************************
WARN("IContextMenu not implemented\n");
hr = E_NOTIMPL;
} else if (IsEqualIID(riid, IID_IShellView)) {
- hr = IShellView_Constructor((IShellFolder *)this, &pShellView);
- if (pShellView) {
- hr = pShellView->QueryInterface(riid, ppvOut);
- }
+ SFV_CREATE sfvparams = {sizeof(SFV_CREATE), this};
+ hr = SHCreateShellFolderView(&sfvparams, (IShellView**)ppvOut);
}
}
TRACE("--(%p)->(interface=%p)\n", this, ppvOut);
HRESULT WINAPI CControlPanelFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD * rgfInOut)
{
HRESULT hr = S_OK;
+ static const DWORD dwControlPanelAttributes =
+ SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_CANLINK;
TRACE("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n",
this, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
if (*rgfInOut == 0)
*rgfInOut = ~0;
- while(cidl > 0 && *apidl)
+ if (!cidl)
{
- pdump(*apidl);
- SHELL32_GetItemAttributes(this, *apidl, rgfInOut);
- apidl++;
- cidl--;
+ *rgfInOut &= dwControlPanelAttributes;
+ }
+ else
+ {
+ while(cidl > 0 && *apidl)
+ {
+ pdump(*apidl);
+ if (_ILIsCPanelStruct(*apidl))
+ *rgfInOut &= SFGAO_CANLINK;
+ else if (_ILIsSpecialFolder(*apidl))
+ m_regFolder->GetAttributesOf(1, apidl, rgfInOut);
+ else
+ ERR("Got an unkown pidl here!\n");
+ apidl++;
+ cidl--;
+ }
}
/* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
*rgfInOut &= ~SFGAO_VALIDATE;
HRESULT WINAPI CControlPanelFolder::GetUIObjectOf(HWND hwndOwner,
UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
{
- LPITEMIDLIST pidl;
- IUnknown *pObj = NULL;
+ LPVOID pObj = NULL;
HRESULT hr = E_INVALIDARG;
TRACE("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
*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 = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &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)) {
- pidl = ILCombine(pidlRoot, apidl[0]);
- pObj = IExtractIconA_Constructor(pidl);
- SHFree(pidl);
- hr = S_OK;
- } else if (IsEqualIID(riid, IID_IExtractIconW) && (cidl == 1)) {
- pidl = ILCombine(pidlRoot, apidl[0]);
- pObj = IExtractIconW_Constructor(pidl);
- SHFree(pidl);
- hr = S_OK;
- } else if ((IsEqualIID(riid, IID_IShellLinkW) || IsEqualIID(riid, IID_IShellLinkA))
- && (cidl == 1)) {
- pidl = ILCombine(pidlRoot, apidl[0]);
- hr = IShellLink_ConstructFromFile(NULL, riid, pidl, (LPVOID*)&pObj);
- SHFree(pidl);
+ } else if ((IsEqualIID(riid, IID_IExtractIconA) || IsEqualIID(riid, IID_IExtractIconW)) && (cidl == 1)) {
+ if (_ILGetCPanelPointer(apidl[0]))
+ hr = CCPLExtractIcon_CreateInstance(this, apidl[0], riid, &pObj);
+ else
+ hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
} else {
hr = E_NOINTERFACE;
}
*/
HRESULT WINAPI CControlPanelFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
{
- CHAR szName[MAX_PATH];
- WCHAR wszName[MAX_PATH+1]; /* +1 for potential backslash */
- PIDLCPanelStruct *pCPanel;
- HRESULT hr;
-
- *szName = '\0';
-
- TRACE("(%p)->(pidl=%p,0x%08x,%p)\n", this, pidl, dwFlags, strRet);
- pdump(pidl);
-
if (!pidl)
return S_FALSE;
- pCPanel = _ILGetCPanelPointer(pidl);
+ PIDLCPanelStruct *pCPanel = _ILGetCPanelPointer(pidl);
if (pCPanel)
{
- /* copy display name from pidl - it was retrived from applet before;
- SHGDN_FORPARSING does not need special handling */
- lstrcpyA(szName, pCPanel->szName + pCPanel->offsDispName);
+ return SHSetStrRet(strRet, pCPanel->szName + pCPanel->offsDispName);
}
- /* take names of special folders only if it's only this folder */
else if (_ILIsSpecialFolder(pidl))
{
- BOOL bSimplePidl = _ILIsPidlSimple(pidl);
- SFGAOF Attr = SFGAO_FILESYSTEM;
-
- SHELL32_GetItemAttributes(this, pidl, &Attr);
- if (Attr & SFGAO_FILESYSTEM)
- {
- hr = SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, wszName, sizeof(wszName));
- if (FAILED(hr))
- return hr;
- }
- else if (bSimplePidl)
- {
- _ILSimpleGetTextW(pidl, wszName, MAX_PATH); /* append my own path */
- }
- else
- {
- FIXME("special pidl\n");
- if (dwFlags & SHGDN_FORPARSING)
- {
- /* go deeper if needed */
- int cchName;
-
- PathAddBackslashW(wszName);
- cchName = wcslen(wszName);
-
- hr = SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, wszName + cchName, MAX_PATH + 1 - cchName);
- if (FAILED(hr))
- return hr;
- }
- }
-
- if (!WideCharToMultiByte(CP_ACP, 0, wszName, -1, szName, MAX_PATH, NULL, NULL))
- szName[0] = '\0';
+ return m_regFolder->GetDisplayNameOf(pidl, dwFlags, strRet);
}
- strRet->uType = STRRET_CSTR;
- lstrcpynA(strRet->cStr, szName, MAX_PATH);
-
- TRACE("--(%p)->(%s)\n", this, szName);
- return S_OK;
+ return E_FAIL;
}
/**************************************************************************
HRESULT WINAPI CControlPanelFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd)
{
- HRESULT hr;
-
- TRACE("(%p)->(%p %i %p)\n", this, pidl, iColumn, psd);
-
if (!psd || iColumn >= CONROLPANELSHELLVIEWCOLUMNS)
return E_INVALIDARG;
- if (!pidl) {
+ if (!pidl)
+ {
psd->fmt = ControlPanelSFHeader[iColumn].fmt;
psd->cxChar = ControlPanelSFHeader[iColumn].cxChar;
- psd->str.uType = STRRET_CSTR;
- LoadStringA(shell32_hInstance, ControlPanelSFHeader[iColumn].colnameid, psd->str.cStr, MAX_PATH);
- return S_OK;
- } else {
- psd->str.cStr[0] = 0x00;
- psd->str.uType = STRRET_CSTR;
- switch(iColumn) {
+ return SHSetStrRet(&psd->str, shell32_hInstance, ControlPanelSFHeader[iColumn].colnameid);
+ }
+ else if (_ILIsSpecialFolder(pidl))
+ {
+ return m_regFolder->GetDetailsOf(pidl, iColumn, psd);
+ }
+ else
+ {
+ PIDLCPanelStruct *pCPanel = _ILGetCPanelPointer(pidl);
+
+ if (!pCPanel)
+ return E_FAIL;
+
+ switch(iColumn)
+ {
case 0: /* name */
- hr = GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_INFOLDER, &psd->str);
- break;
+ return SHSetStrRet(&psd->str, pCPanel->szName + pCPanel->offsDispName);
case 1: /* comment */
- _ILGetFileType(pidl, psd->str.cStr, MAX_PATH);
- break;
+ return SHSetStrRet(&psd->str, pCPanel->szName + pCPanel->offsComment);
}
- hr = S_OK;
}
- return hr;
+ return S_OK;
}
HRESULT WINAPI CControlPanelFolder::MapColumnToSCID(UINT column, SHCOLUMNID *pscid)
*
* NOTES: it makes no sense to change the pidl
*/
-HRESULT WINAPI CControlPanelFolder::Initialize(LPCITEMIDLIST pidl)
+HRESULT WINAPI CControlPanelFolder::Initialize(PCIDLIST_ABSOLUTE pidl)
{
if (pidlRoot)
SHFree((LPVOID)pidlRoot);
pidlRoot = ILClone(pidl);
+
+ /* Create the inner reg folder */
+ HRESULT hr;
+ static const WCHAR* pszCPanelPath = L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}";
+ hr = CRegFolder_CreateInstance(&CLSID_ControlPanel,
+ pidlRoot,
+ pszCPanelPath,
+ L"ControlPanel",
+ IID_PPV_ARG(IShellFolder2, &m_regFolder));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
return S_OK;
}
/**************************************************************************
* CControlPanelFolder::GetCurFolder
*/
-HRESULT WINAPI CControlPanelFolder::GetCurFolder(LPITEMIDLIST * pidl)
+HRESULT WINAPI CControlPanelFolder::GetCurFolder(PIDLIST_ABSOLUTE * pidl)
{
TRACE("(%p)->(%p)\n", this, pidl);
return S_OK;
}
-HRESULT CPanel_GetIconLocationW(LPCITEMIDLIST pidl, LPWSTR szIconFile, UINT cchMax, int* piIndex)
+CCPLItemMenu::CCPLItemMenu()
{
- PIDLCPanelStruct* pcpanel = _ILGetCPanelPointer(pidl);
-
- if (!pcpanel)
- return E_INVALIDARG;
+ m_apidl = NULL;
+ m_cidl = 0;
+}
- MultiByteToWideChar(CP_ACP, 0, pcpanel->szName, -1, szIconFile, cchMax);
- *piIndex = (int)pcpanel->iconIdx != -1 ? pcpanel->iconIdx : 0;
+HRESULT WINAPI CCPLItemMenu::Initialize(UINT cidl, PCUITEMID_CHILD_ARRAY apidl)
+{
+ m_cidl = cidl;
+ m_apidl = _ILCopyaPidl(apidl, m_cidl);
+ if (m_cidl && !m_apidl)
+ return E_OUTOFMEMORY;
return S_OK;
}
-/**************************************************************************
-* IContextMenu2 Implementation
-*/
+CCPLItemMenu::~CCPLItemMenu()
+{
+ _ILFreeaPidl(m_apidl, m_cidl);
+}
-/**************************************************************************
-* ICPanel_IContextMenu_QueryContextMenu()
-*/
-HRESULT WINAPI CControlPanelFolder::QueryContextMenu(
+HRESULT WINAPI CCPLItemMenu::QueryContextMenu(
HMENU hMenu,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags)
{
- WCHAR szBuffer[30] = {0};
- ULONG Count = 1;
+ _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_OPEN, MFT_STRING, MAKEINTRESOURCEW(IDS_OPEN), MFS_DEFAULT);
+ _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 1, MFT_SEPARATOR, NULL, MFS_ENABLED);
+ _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_CREATELINK, MFT_STRING, MAKEINTRESOURCEW(IDS_CREATELINK), MFS_ENABLED);
- TRACE("(%p)->(hmenu=%p indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",
- this, hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
-
- if (LoadStringW(shell32_hInstance, IDS_OPEN, szBuffer, sizeof(szBuffer) / sizeof(WCHAR)))
- {
- szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
- _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_OPEN, MFT_STRING, szBuffer, MFS_DEFAULT); //FIXME identifier
- Count++;
- }
-
- if (LoadStringW(shell32_hInstance, IDS_CREATELINK, szBuffer, sizeof(szBuffer) / sizeof(WCHAR)))
- {
- if (Count)
- {
- _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + Count, MFT_SEPARATOR, NULL, MFS_ENABLED);
- }
- szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
-
- _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_CREATELINK, MFT_STRING, szBuffer, MFS_ENABLED); //FIXME identifier
- Count++;
- }
- return MAKE_HRESULT(SEVERITY_SUCCESS, 0, Count);
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 2);
}
+EXTERN_C
+void WINAPI Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR 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]);
+ /* Hardcode the command here; Executing a cpl file would be fine but we also need to run things like console.dll */
+ WCHAR wszParams[MAX_PATH];
+ PCWSTR wszFile = L"rundll32.exe";
+ PCWSTR wszFormat = L"shell32.dll,Control_RunDLL %s,%s";
- 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;
- }
+ wsprintfW(wszParams, wszFormat, pCPanel->szName, pCPanel->szName + pCPanel->offsDispName);
/* 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);
+ ShellExecuteW(NULL, NULL, wszFile, wszParams, NULL, 0);
}
else if (lpcmi->lpVerb == MAKEINTRESOURCEA(IDS_CREATELINK)) //FIXME
{
- if (!SHGetSpecialFolderPathW(NULL, szPath, CSIDL_DESKTOPDIRECTORY, FALSE))
- return E_FAIL;
+ CComPtr<IDataObject> pDataObj;
+ LPITEMIDLIST pidl = _ILCreateControlPanel();
- pszPath = PathAddBackslashW(szPath);
- if (!pszPath)
- return E_FAIL;
+ hResult = SHCreateDataObject(pidl, m_cidl, m_apidl, NULL, IID_PPV_ARG(IDataObject, &pDataObj));
+ if (FAILED(hResult))
+ return hResult;
- if (GetDisplayNameOf(apidl[0], SHGDN_FORPARSING, &strret) != S_OK)
- return E_FAIL;
+ SHFree(pidl);
- Length = MAX_PATH - (pszPath - szPath);
- cLength = strlen(strret.cStr);
- if (Length < cLength + 5)
- {
- FIXME("\n");
- return E_FAIL;
- }
+ //FIXME: Use SHCreateLinks
+ CComPtr<IShellFolder> psf;
+ CComPtr<IDropTarget> pDT;
- if (MultiByteToWideChar(CP_ACP, 0, strret.cStr, cLength + 1, pszPath, Length))
- {
- pszPath += cLength;
- Length -= cLength;
- }
+ hResult = SHGetDesktopFolder(&psf);
+ if (FAILED(hResult))
+ return hResult;
- if (Length > 10)
- {
- wcscpy(pszPath, L" - ");
- cLength = LoadStringW(shell32_hInstance, IDS_LNK_FILE, &pszPath[3], Length - 4) + 3;
- if (cLength + 5 > Length)
- cLength = Length - 5;
- Length -= cLength;
- pszPath += cLength;
- }
- wcscpy(pszPath, L".lnk");
+ hResult = psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pDT));
+ if (FAILED(hResult))
+ return hResult;
- 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;
- }
- hResult = CShellLink::_CreatorClass::CreateInstance(NULL, IID_PPV_ARG(IShellLinkA, &isl));
- if (SUCCEEDED(hResult))
- {
- isl->SetPath(szTarget);
- if (SUCCEEDED(isl->QueryInterface(IID_PPV_ARG(IPersistFile,&ppf))))
- ppf->Save(szPath, TRUE);
- }
- return NOERROR;
+ SHSimulateDrop(pDT, pDataObj, MK_CONTROL|MK_SHIFT, NULL, NULL);
}
return S_OK;
}
* ICPanel_IContextMenu_GetCommandString()
*
*/
-HRESULT WINAPI CControlPanelFolder::GetCommandString(
+HRESULT WINAPI CCPLItemMenu::GetCommandString(
UINT_PTR idCommand,
UINT uFlags,
UINT* lpReserved,
/**************************************************************************
* ICPanel_IContextMenu_HandleMenuMsg()
*/
-HRESULT WINAPI CControlPanelFolder::HandleMenuMsg(
+HRESULT WINAPI CCPLItemMenu::HandleMenuMsg(
UINT uMsg,
WPARAM wParam,
LPARAM lParam)