C/C++ codeBOOL CMyFolder::RegisterNamespaceExtension(REFCLSID refClsid, LPCTSTR lpszName, BOOL bCurUser)
{
// 转换CLSID为字符串
LPOLESTR pwszClsid = NULL;
StringFromCLSID(clsid, &pwszClsid);
TCHAR szClsid[MAX_PATH];
#ifdef _UNICODE
StrCpy(szClsid, pwszClsid);
#else
USES_CONVERSION;
StrCpy(szClsid, W2CT(pwszClsid));
#endif
CoTaskMemFree(pwszClsid);
// NameSpace CLSID
HKEY hKeyRoot = HKEY_LOCAL_MACHINE;
if (bCurUser)
hKeyRoot = HKEY_CURRENT_USER;
TCHAR szNameSpace[MAX_PATH] = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\NameSpace\\");
StrCat(szNameSpace, szClsid);
HKEY hKeyNamespace;
DWORD dwDisposition = 0;
if (ERROR_SUCCESS != RegCreateKeyEx(hKeyRoot, szNameSpace, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyNamespace, &dwDisposition))
{
return FALSE;
}
DWORD dwType = REG_SZ;
DWORD dwSize = (DWORD)(_tcslen(lpszName) + sizeof(TCHAR));
RegSetValueEx(hKeyNamespace, NULL, 0, dwType, (BYTE*)lpszName, dwSize);
RegCloseKey(hKeyNamespace);
// Shell
TCHAR szModuleName[MAX_PATH];
TCHAR szModulePath[MAX_PATH];
GetModuleFileName(AfxGetInstanceHandle(), szModuleName, MAX_PATH);
StrCpy(szModulePath, szModuleName);
PathRemoveFileSpec(szModulePath);
// HKEY_CLASSES_ROOT\CLSID
TCHAR szMyClsid[MAX_PATH];
StrCpy(szMyClsid, _T("CLSID\\"));
StrCat(szMyClsid, szClsid);
HKEY hKeyClsid;
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, szMyClsid, 0, KEY_ALL_ACCESS, &hKeyClsid))
{
return FALSE;
}
// Name
RegSetValueEx(hKeyClsid, NULL, 0, dwType, (BYTE*)lpszName, dwSize);
// Infotip
TCHAR szInfotip[] = _T("Myfolder shell namespace extension.");
dwSize = (DWORD)(_tcslen(szInfotip) + sizeof(TCHAR));
RegSetValueEx(hKeyClsid, _T("InfoTip"), 0, dwType, (BYTE*)szInfotip, dwSize);
// DefaultIcon
TCHAR szDefaultIcon[MAX_PATH];
StrCpy(szDefaultIcon, szModuleName);
StrCat(szDefaultIcon, _T(",0"));
dwSize = (DWORD)(_tcslen(szDefaultIcon) + sizeof(TCHAR));
HKEY hKeyIcon;
RegCreateKeyEx(hKeyClsid, _T("DefaultIcon"), 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyIcon, &dwDisposition);
RegSetValueEx(hKeyIcon, NULL, 0, dwType, (BYTE*)szDefaultIcon, dwSize);
RegCloseKey(hKeyIcon);
...
RegCloseKey(hKeyClsid);
return TRUE;
}
当然,这只是添加了一个图标。要实现相应的功能,需要自己创建并注册一个进程内COM组件,这个COM的CLSID就是上面这个函数第一个参数。这个COM组件至少需要导出并实现以下接口:
IShellExtInit
IPersistFolder
IEnumIDList
IShellView
IShellFolder
还可以选择性实现并导出以下接口:
IExtractIcon
IContextMenu3
IQueryInfo
等
具体在SDK中有个例子SampView可以参考。
{
// 转换CLSID为字符串
LPOLESTR pwszClsid = NULL;
StringFromCLSID(clsid, &pwszClsid);
TCHAR szClsid[MAX_PATH];
#ifdef _UNICODE
StrCpy(szClsid, pwszClsid);
#else
USES_CONVERSION;
StrCpy(szClsid, W2CT(pwszClsid));
#endif
CoTaskMemFree(pwszClsid);
// NameSpace CLSID
HKEY hKeyRoot = HKEY_LOCAL_MACHINE;
if (bCurUser)
hKeyRoot = HKEY_CURRENT_USER;
TCHAR szNameSpace[MAX_PATH] = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\NameSpace\\");
StrCat(szNameSpace, szClsid);
HKEY hKeyNamespace;
DWORD dwDisposition = 0;
if (ERROR_SUCCESS != RegCreateKeyEx(hKeyRoot, szNameSpace, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyNamespace, &dwDisposition))
{
return FALSE;
}
DWORD dwType = REG_SZ;
DWORD dwSize = (DWORD)(_tcslen(lpszName) + sizeof(TCHAR));
RegSetValueEx(hKeyNamespace, NULL, 0, dwType, (BYTE*)lpszName, dwSize);
RegCloseKey(hKeyNamespace);
// Shell
TCHAR szModuleName[MAX_PATH];
TCHAR szModulePath[MAX_PATH];
GetModuleFileName(AfxGetInstanceHandle(), szModuleName, MAX_PATH);
StrCpy(szModulePath, szModuleName);
PathRemoveFileSpec(szModulePath);
// HKEY_CLASSES_ROOT\CLSID
TCHAR szMyClsid[MAX_PATH];
StrCpy(szMyClsid, _T("CLSID\\"));
StrCat(szMyClsid, szClsid);
HKEY hKeyClsid;
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, szMyClsid, 0, KEY_ALL_ACCESS, &hKeyClsid))
{
return FALSE;
}
// Name
RegSetValueEx(hKeyClsid, NULL, 0, dwType, (BYTE*)lpszName, dwSize);
// Infotip
TCHAR szInfotip[] = _T("Myfolder shell namespace extension.");
dwSize = (DWORD)(_tcslen(szInfotip) + sizeof(TCHAR));
RegSetValueEx(hKeyClsid, _T("InfoTip"), 0, dwType, (BYTE*)szInfotip, dwSize);
// DefaultIcon
TCHAR szDefaultIcon[MAX_PATH];
StrCpy(szDefaultIcon, szModuleName);
StrCat(szDefaultIcon, _T(",0"));
dwSize = (DWORD)(_tcslen(szDefaultIcon) + sizeof(TCHAR));
HKEY hKeyIcon;
RegCreateKeyEx(hKeyClsid, _T("DefaultIcon"), 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyIcon, &dwDisposition);
RegSetValueEx(hKeyIcon, NULL, 0, dwType, (BYTE*)szDefaultIcon, dwSize);
RegCloseKey(hKeyIcon);
...
RegCloseKey(hKeyClsid);
return TRUE;
}
当然,这只是添加了一个图标。要实现相应的功能,需要自己创建并注册一个进程内COM组件,这个COM的CLSID就是上面这个函数第一个参数。这个COM组件至少需要导出并实现以下接口:
IShellExtInit
IPersistFolder
IEnumIDList
IShellView
IShellFolder
还可以选择性实现并导出以下接口:
IExtractIcon
IContextMenu3
IQueryInfo
等
具体在SDK中有个例子SampView可以参考。