Commit dd46d6df authored by Martin Fuchs's avatar Martin Fuchs Committed by Alexandre Julliard

Implementation of the control panel folder in shell namespace.

parent ce32fc56
...@@ -18,6 +18,7 @@ C_SRCS = \ ...@@ -18,6 +18,7 @@ C_SRCS = \
classes.c \ classes.c \
clipboard.c \ clipboard.c \
control.c \ control.c \
cpanelfolder.c \
dataobject.c \ dataobject.c \
debughlp.c \ debughlp.c \
dialogs.c \ dialogs.c \
......
...@@ -36,27 +36,11 @@ ...@@ -36,27 +36,11 @@
#define NO_SHLWAPI_REG #define NO_SHLWAPI_REG
#include "shlwapi.h" #include "shlwapi.h"
#include "cpanel.h"
WINE_DEFAULT_DEBUG_CHANNEL(shlctrl); WINE_DEFAULT_DEBUG_CHANNEL(shlctrl);
typedef struct CPlApplet { CPlApplet* Control_UnloadApplet(CPlApplet* applet)
struct CPlApplet* next; /* linked list */
HWND hWnd;
unsigned count; /* number of subprograms */
HMODULE hModule; /* module of loaded applet */
APPLET_PROC proc; /* entry point address */
NEWCPLINFOW info[1]; /* array of count information.
* dwSize field is 0 if entry is invalid */
} CPlApplet;
typedef struct CPanel {
CPlApplet* first; /* linked list */
HWND hWnd;
unsigned status;
CPlApplet* clkApplet;
unsigned clkSP;
} CPanel;
static CPlApplet* Control_UnloadApplet(CPlApplet* applet)
{ {
unsigned i; unsigned i;
CPlApplet* next; CPlApplet* next;
...@@ -72,7 +56,7 @@ static CPlApplet* Control_UnloadApplet(CPlApplet* applet) ...@@ -72,7 +56,7 @@ static CPlApplet* Control_UnloadApplet(CPlApplet* applet)
return next; return next;
} }
static CPlApplet* Control_LoadApplet(HWND hWnd, LPCWSTR cmd, CPanel* panel) CPlApplet* Control_LoadApplet(HWND hWnd, LPCWSTR cmd, CPanel* panel)
{ {
CPlApplet* applet; CPlApplet* applet;
unsigned i; unsigned i;
......
/* Control Panel management
*
* Copyright 2001 Eric Pouech
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __WINE_SHELL_CPANEL_H
#define __WINE_SHELL_CPANEL_H
typedef struct CPlApplet {
struct CPlApplet* next; /* linked list */
HWND hWnd;
unsigned count; /* number of subprograms */
HMODULE hModule; /* module of loaded applet */
APPLET_PROC proc; /* entry point address */
NEWCPLINFOW info[1]; /* array of count information.
* dwSize field is 0 if entry is invalid */
} CPlApplet;
typedef struct CPanel {
CPlApplet* first; /* linked list */
HWND hWnd;
unsigned status;
CPlApplet* clkApplet;
unsigned clkSP;
} CPanel;
CPlApplet* Control_LoadApplet(HWND hWnd, LPCWSTR cmd, CPanel* panel);
CPlApplet* Control_UnloadApplet(CPlApplet* applet);
#endif /* __WINE_SHELL_CPANEL_H */
...@@ -29,10 +29,12 @@ ...@@ -29,10 +29,12 @@
#include "shlwapi.h" #include "shlwapi.h"
#include "winerror.h" #include "winerror.h"
#include "objbase.h" #include "objbase.h"
#include <cpl.h>
#include "pidl.h" #include "pidl.h"
#include "shlguid.h" #include "shlguid.h"
#include "shell32_main.h" #include "shell32_main.h"
#include "cpanel.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell); WINE_DEFAULT_DEBUG_CHANNEL(shell);
...@@ -168,6 +170,161 @@ static BOOL CreateFolderEnumList( ...@@ -168,6 +170,161 @@ static BOOL CreateFolderEnumList(
return TRUE; return TRUE;
} }
BOOL SHELL_RegisterCPanelApp(IEnumIDList* list, LPCSTR path)
{
LPITEMIDLIST pidl;
CPlApplet* applet;
CPanel panel;
CPLINFO info;
unsigned i;
int iconIdx;
char displayName[MAX_PATH];
char comment[MAX_PATH];
WCHAR wpath[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, MAX_PATH);
panel.first = NULL;
applet = Control_LoadApplet(0, wpath, &panel);
if (applet) {
for(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 */
else
iconIdx = 0;
pidl = _ILCreateCPanel(path, displayName, comment, iconIdx);
if (pidl)
AddToEnumList(list, pidl);
}
Control_UnloadApplet(applet);
}
return TRUE;
}
int SHELL_RegisterRegistryCPanelApps(IEnumIDList* list, HKEY hkey_root, LPCSTR szRepPath)
{
char name[MAX_PATH];
char value[MAX_PATH];
HKEY hkey;
int cnt = 0;
if (RegOpenKeyA(hkey_root, szRepPath, &hkey) == ERROR_SUCCESS)
{
int idx = 0;
for(;; ++idx)
{
DWORD nameLen = MAX_PATH;
DWORD valueLen = MAX_PATH;
if (RegEnumValueA(hkey, idx, name, &nameLen, NULL, NULL, (LPBYTE)&value, &valueLen) != ERROR_SUCCESS)
break;
if (SHELL_RegisterCPanelApp(list, value))
++cnt;
}
RegCloseKey(hkey);
}
return cnt;
}
int SHELL_RegisterCPanelFolders(IEnumIDList* list, 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 == '{') {
LPITEMIDLIST pidl = _ILCreateSpecial(name);
if (pidl && AddToEnumList(list, pidl))
++cnt;
}
}
RegCloseKey(hkey);
}
return cnt;
}
/**************************************************************************
* CreateCPanelEnumList()
*/
static BOOL CreateCPanelEnumList(
IEnumIDList * iface,
DWORD dwFlags)
{
ICOM_THIS(IEnumIDListImpl,iface);
CHAR szPath[MAX_PATH];
WIN32_FIND_DATAA wfd;
HANDLE hFile;
TRACE("(%p)->(flags=0x%08lx) \n",This,dwFlags);
/* enumerate control panel folders folders */
if (dwFlags & SHCONTF_FOLDERS)
SHELL_RegisterCPanelFolders((IEnumIDList*)This, HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace");
/* enumerate the control panel applets */
if (dwFlags & SHCONTF_NONFOLDERS)
{
LPSTR p;
GetSystemDirectoryA(szPath, MAX_PATH);
p = PathAddBackslashA(szPath);
strcpy(p, "*.cpl");
TRACE("-- (%p)-> enumerate SHCONTF_NONFOLDERS of %s\n",This,debugstr_a(szPath));
hFile = FindFirstFileA(szPath, &wfd);
if (hFile != INVALID_HANDLE_VALUE)
{
do
{
if (!(dwFlags & SHCONTF_INCLUDEHIDDEN) && (wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
continue;
if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
strcpy(p, wfd.cFileName);
SHELL_RegisterCPanelApp((IEnumIDList*)This, szPath);
}
} while(FindNextFileA(hFile, &wfd));
FindClose(hFile);
}
SHELL_RegisterRegistryCPanelApps((IEnumIDList*)This, HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls");
SHELL_RegisterRegistryCPanelApps((IEnumIDList*)This, HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls");
}
return TRUE;
}
/************************************************************************** /**************************************************************************
* CreateDesktopEnumList() * CreateDesktopEnumList()
*/ */
...@@ -343,6 +500,10 @@ IEnumIDList * IEnumIDList_Constructor( ...@@ -343,6 +500,10 @@ IEnumIDList * IEnumIDList_Constructor(
case EIDL_FILE: case EIDL_FILE:
ret = CreateFolderEnumList((IEnumIDList*)lpeidl, lpszPath, dwFlags); ret = CreateFolderEnumList((IEnumIDList*)lpeidl, lpszPath, dwFlags);
break; break;
case EIDL_CPANEL:
ret = CreateCPanelEnumList((IEnumIDList*)lpeidl, dwFlags);
break;
} }
if(!ret) { if(!ret) {
......
...@@ -231,33 +231,47 @@ static HRESULT WINAPI IExtractIconW_fnGetIconLocation( ...@@ -231,33 +231,47 @@ static HRESULT WINAPI IExtractIconW_fnGetIconLocation(
} }
*piIndex = (uFlags & GIL_OPENICON) ? dwNr + 1 : dwNr; *piIndex = (uFlags & GIL_OPENICON) ? dwNr + 1 : dwNr;
} }
else /* object is file */
else
{ {
if (_ILGetExtension(pSimplePidl, sTemp, MAX_PATH) BOOL found = FALSE;
&& HCR_MapTypeToValueA(sTemp, sTemp, MAX_PATH, TRUE)
&& HCR_GetDefaultIconA(sTemp, sTemp, MAX_PATH, &dwNr)) if (_ILIsCPanelStruct(pSimplePidl))
{
if (SUCCEEDED(CPanel_GetIconLocationW(pSimplePidl, szIconFile, cchMax, piIndex)))
found = TRUE;
}
else if (_ILGetExtension(pSimplePidl, sTemp, MAX_PATH))
{ {
if (!lstrcmpA("%1", sTemp)) /* icon is in the file */ if (HCR_MapTypeToValueA(sTemp, sTemp, MAX_PATH, TRUE)
&& HCR_GetDefaultIconA(sTemp, sTemp, MAX_PATH, &dwNr))
{ {
SHGetPathFromIDListW(This->pidl, szIconFile); if (!lstrcmpA("%1", sTemp)) /* icon is in the file */
*piIndex = 0; {
SHGetPathFromIDListW(This->pidl, szIconFile);
*piIndex = 0;
}
else
{
MultiByteToWideChar(CP_ACP, 0, sTemp, -1, szIconFile, cchMax);
*piIndex = dwNr;
}
found = TRUE;
} }
else
if (!found) /* default icon */
{ {
MultiByteToWideChar(CP_ACP, 0, sTemp, -1, szIconFile, cchMax); lstrcpynW(szIconFile, swShell32Name, cchMax);
*piIndex = dwNr; *piIndex = 0;
} }
} }
else /* default icon */
{
lstrcpynW(szIconFile, swShell32Name, cchMax);
*piIndex = 0;
}
} }
TRACE("-- %s %x\n", debugstr_w(szIconFile), *piIndex); TRACE("-- %s %x\n", debugstr_w(szIconFile), *piIndex);
return NOERROR; return NOERROR;
} }
/************************************************************************** /**************************************************************************
* IExtractIconW_Extract * IExtractIconW_Extract
*/ */
......
...@@ -1662,6 +1662,49 @@ LPITEMIDLIST _ILCreateSpecial(LPCSTR szGUID) ...@@ -1662,6 +1662,49 @@ LPITEMIDLIST _ILCreateSpecial(LPCSTR szGUID)
return _ILCreate(PT_MYCOMP, &iid, sizeof(IID)); return _ILCreate(PT_MYCOMP, &iid, sizeof(IID));
} }
LPITEMIDLIST _ILCreateCPanel(LPCSTR name, LPCSTR displayName, LPCSTR comment, int iconIdx)
{
PIDLCPanelStruct *p;
LPITEMIDLIST pidl;
PIDLDATA tmp;
int size0 = (char*)&tmp.u.cpanel.szName-(char*)&tmp.u.cpanel;
int size = size0;
int l;
tmp.type = 0;
tmp.u.cpanel.dummy = 0;
tmp.u.cpanel.iconIdx = iconIdx;
l = strlen(name);
size += l+1;
tmp.u.cpanel.offsDispName = l+1;
l = strlen(displayName);
size += l+1;
tmp.u.cpanel.offsComment = tmp.u.cpanel.offsDispName+1+l;
l = strlen(comment);
size += l+1;
pidl = SHAlloc(size+4);
if (!pidl)
return NULL;
pidl->mkid.cb = size+2;
memcpy(pidl->mkid.abID, &tmp, 2+size0);
p = &((PIDLDATA*)pidl->mkid.abID)->u.cpanel;
strcpy(p->szName, name);
strcpy(p->szName+tmp.u.cpanel.offsDispName, displayName);
strcpy(p->szName+tmp.u.cpanel.offsComment, comment);
*(WORD*)((char*)pidl+(size+2)) = 0;
pcheck(pidl);
return pidl;
}
/************************************************************************** /**************************************************************************
* _ILCreate() * _ILCreate()
* Creates a new PIDL * Creates a new PIDL
...@@ -1823,6 +1866,12 @@ BOOL _ILIsValue(LPCITEMIDLIST pidl) ...@@ -1823,6 +1866,12 @@ BOOL _ILIsValue(LPCITEMIDLIST pidl)
return (pidl && lpPData && PT_VALUE == lpPData->type); return (pidl && lpPData && PT_VALUE == lpPData->type);
} }
BOOL _ILIsCPanelStruct(LPCITEMIDLIST pidl)
{ LPPIDLDATA lpPData = _ILGetDataPointer(pidl);
TRACE("(%p)\n",pidl);
return (pidl && lpPData && (lpPData->type == 0));
}
/************************************************************************** /**************************************************************************
* _ILIsPidlSimple * _ILIsPidlSimple
*/ */
...@@ -2041,6 +2090,20 @@ REFIID _ILGetGUIDPointer(LPCITEMIDLIST pidl) ...@@ -2041,6 +2090,20 @@ REFIID _ILGetGUIDPointer(LPCITEMIDLIST pidl)
return NULL; return NULL;
} }
/**************************************************************************
* _ILGetCPanelPointer()
* gets a pointer to the control panel struct stored in the pidl
*/
PIDLCPanelStruct* _ILGetCPanelPointer(LPCITEMIDLIST pidl)
{
LPPIDLDATA pdata = _ILGetDataPointer(pidl);
if (pdata && pdata->type==0)
return (PIDLCPanelStruct*)&(pdata->u.cpanel);
return NULL;
}
/************************************************************************* /*************************************************************************
* _ILGetFileDateTime * _ILGetFileDateTime
* *
......
...@@ -107,6 +107,15 @@ ...@@ -107,6 +107,15 @@
#include "pshpack1.h" #include "pshpack1.h"
typedef BYTE PIDLTYPE; typedef BYTE PIDLTYPE;
typedef struct tagPIDLCPanelStruct
{
BYTE dummy; /*01 is 0x00 */
DWORD iconIdx; /*02 negative icon ID */
WORD offsDispName; /*06*/
WORD offsComment; /*08*/
CHAR szName[1]; /*10*/ /* terminated by 0x00, followed by display name and comment string */
} PIDLCPanelStruct;
typedef struct tagPIDLDATA typedef struct tagPIDLDATA
{ PIDLTYPE type; /*00*/ { PIDLTYPE type; /*00*/
union union
...@@ -137,8 +146,9 @@ typedef struct tagPIDLDATA ...@@ -137,8 +146,9 @@ typedef struct tagPIDLDATA
struct struct
{ WORD dummy; /*01*/ { WORD dummy; /*01*/
DWORD dummy1; /*02*/ DWORD dummy1; /*02*/
CHAR szName[1]; /*06*/ /* teminated by 0x00 0x00 */ CHAR szName[1]; /*06*/ /* terminated by 0x00 0x00 */
} htmlhelp; } htmlhelp;
struct tagPIDLCPanelStruct cpanel;
}u; }u;
} PIDLDATA, *LPPIDLDATA; } PIDLDATA, *LPPIDLDATA;
#include "poppack.h" #include "poppack.h"
...@@ -167,6 +177,7 @@ BOOL _ILIsFolder (LPCITEMIDLIST pidl); ...@@ -167,6 +177,7 @@ BOOL _ILIsFolder (LPCITEMIDLIST pidl);
BOOL _ILIsValue (LPCITEMIDLIST pidl); BOOL _ILIsValue (LPCITEMIDLIST pidl);
BOOL _ILIsSpecialFolder (LPCITEMIDLIST pidl); BOOL _ILIsSpecialFolder (LPCITEMIDLIST pidl);
BOOL _ILIsPidlSimple (LPCITEMIDLIST pidl); BOOL _ILIsPidlSimple (LPCITEMIDLIST pidl);
BOOL _ILIsCPanelStruct (LPCITEMIDLIST pidl);
/* /*
* simple pidls from strings * simple pidls from strings
...@@ -185,6 +196,7 @@ LPITEMIDLIST _ILCreateFolder (WIN32_FIND_DATAA * stffile); ...@@ -185,6 +196,7 @@ LPITEMIDLIST _ILCreateFolder (WIN32_FIND_DATAA * stffile);
LPITEMIDLIST _ILCreateValue (WIN32_FIND_DATAA * stffile); LPITEMIDLIST _ILCreateValue (WIN32_FIND_DATAA * stffile);
LPITEMIDLIST _ILCreateSpecial (LPCSTR szGUID); LPITEMIDLIST _ILCreateSpecial (LPCSTR szGUID);
LPITEMIDLIST _ILCreateFromPathA (LPCSTR szPath); LPITEMIDLIST _ILCreateFromPathA (LPCSTR szPath);
LPITEMIDLIST _ILCreateCPanel (LPCSTR name, LPCSTR displayName, LPCSTR comment, int iconIdx);
/* /*
* helper functions (getting struct-pointer) * helper functions (getting struct-pointer)
...@@ -193,6 +205,7 @@ LPPIDLDATA _ILGetDataPointer (LPCITEMIDLIST); ...@@ -193,6 +205,7 @@ LPPIDLDATA _ILGetDataPointer (LPCITEMIDLIST);
LPSTR _ILGetTextPointer (LPCITEMIDLIST); LPSTR _ILGetTextPointer (LPCITEMIDLIST);
LPSTR _ILGetSTextPointer (LPCITEMIDLIST); LPSTR _ILGetSTextPointer (LPCITEMIDLIST);
REFIID _ILGetGUIDPointer (LPCITEMIDLIST pidl); REFIID _ILGetGUIDPointer (LPCITEMIDLIST pidl);
PIDLCPanelStruct* _ILGetCPanelPointer (LPCITEMIDLIST pidl);
/* /*
* debug helper * debug helper
......
...@@ -91,11 +91,17 @@ HRESULT WINAPI ISF_Desktop_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID ...@@ -91,11 +91,17 @@ HRESULT WINAPI ISF_Desktop_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID
HRESULT WINAPI ISF_MyComputer_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv); HRESULT WINAPI ISF_MyComputer_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
HRESULT WINAPI IDropTargetHelper_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv); HRESULT WINAPI IDropTargetHelper_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
HRESULT WINAPI IFileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC *ppV); HRESULT WINAPI IFileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC *ppV);
HRESULT WINAPI IControlPanel_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
HRESULT WINAPI CPanel_GetIconLocationA(LPITEMIDLIST pidl, LPSTR szIconFile, UINT cchMax, int* piIndex);
HRESULT WINAPI CPanel_GetIconLocationW(LPITEMIDLIST pidl, LPWSTR szIconFile, UINT cchMax, int* piIndex);
HRESULT WINAPI CPanel_ExtractIconA(LPITEMIDLIST pidl, LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
HRESULT WINAPI CPanel_ExtractIconW(LPITEMIDLIST pidl, LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
/* kind of enumidlist */ /* kind of enumidlist */
#define EIDL_DESK 0 #define EIDL_DESK 0
#define EIDL_MYCOMP 1 #define EIDL_MYCOMP 1
#define EIDL_FILE 2 #define EIDL_FILE 2
#define EIDL_CPANEL 3
LPENUMIDLIST IEnumIDList_Constructor(LPCSTR,DWORD,DWORD); LPENUMIDLIST IEnumIDList_Constructor(LPCSTR,DWORD,DWORD);
......
...@@ -61,12 +61,13 @@ IClassFactory * IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, ...@@ -61,12 +61,13 @@ IClassFactory * IDefClF_fnConstructor(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll,
struct { struct {
REFIID riid; REFIID riid;
LPFNCREATEINSTANCE lpfnCI; LPFNCREATEINSTANCE lpfnCI;
} InterfaceTable[6] = { } InterfaceTable[] = {
{&CLSID_ShellFSFolder, &IFSFolder_Constructor}, {&CLSID_ShellFSFolder, &IFSFolder_Constructor},
{&CLSID_MyComputer, &ISF_MyComputer_Constructor}, {&CLSID_MyComputer, &ISF_MyComputer_Constructor},
{&CLSID_ShellDesktop, &ISF_Desktop_Constructor}, {&CLSID_ShellDesktop, &ISF_Desktop_Constructor},
{&CLSID_ShellLink, &IShellLink_Constructor}, {&CLSID_ShellLink, &IShellLink_Constructor},
{&CLSID_DragDropHelper, &IDropTargetHelper_Constructor}, {&CLSID_DragDropHelper, &IDropTargetHelper_Constructor},
{&CLSID_ControlPanel, &IControlPanel_Constructor},
{NULL,NULL} {NULL,NULL}
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment