有了COM对象后,必须对浏览栏的CLSID进行注册。另外如果要与IE或资源管理器协调运行,还必须进行的恰当的组件种类(CATID_DeskBand)注册。这个工作由DllRegisterServer处理。实现代码如下:
注册表中的结构如下图:
一、注册
STDAPI DllRegisterServer()
{
BOOL isSuccess = SdkDeskBandHelper::RegisterServer(g_hDllInst, CLSID_SdkDeskBand, L"Sampele Band");
if ( TRUE == isSuccess )
{
// 注册类型
isSuccess = SdkDeskBandHelper::RegisterComCategory(CLSID_LyraDeskBand);
}
// 以下代码就是让Toolbars子菜单项中立即出现我们注册的Band对象菜单项
if ( TRUE == isSuccess )
{
ITrayDeskBand *pTrayDeskBand = NULL;
HRESULT hr = CoCreateInstance(CLSID_TrayDeskBand, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pTrayDeskBand));
if ( SUCCEEDED(hr) )
{
pTrayDeskBand->DeskBandRegistrationChanged();
}
SAFE_RELEASE(pTrayDeskBand);
}
return (TRUE == isSuccess) ? S_OK : E_FAIL;
}
这个函数内部由两SdkDeskBandHelper::RegisterServer和SdkDeskBandHelper::RegisterComCategory两个方法实现。
BOOL SdkDeskBandHelper::RegisterServer(HINSTANCE hDlInstance, CLSID clsidCom, IN const WCHAR* pszDefValueText)
{
WCHAR *pszTempDefValueText = (NULL == pszDefValueText) ? L"" : pszDefValueText;
WCHAR szClsid[MAX_PATH] = { 0 };
StringFromGUID2(clsidCom, szClsid, MAX_PATH);
WCHAR szSubKey[MAX_PATH] = { 0 };
HRESULT hr = StringCchPrintf(szSubKey, MAX_PATH, L"CLSID//%s", szClsid);
HKEY hKey = NULL;
LONG lResult = (SUCCEEDED(hr)) ? ERROR_SUCCESS : ERROR_INVALID_FUNCTION;
if ( ERROR_SUCCESS == lResult )
{
lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT,
szSubKey, 0,
NULL, REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL,
&hKey, NULL);
if ( ERROR_SUCCESS == lResult )
{
// Set default value.
lResult = RegSetValueEx(hKey, NULL, 0, REG_SZ, (LPBYTE)pszDefValueText, (DWORD)wcslen(pszTempDefValueText) * sizeof(WCHAR));
hr = (ERROR_SUCCESS == lResult) ? S_OK : E_FAIL;
}
RegCloseKey(hKey);
}
if ( ERROR_SUCCESS == lResult )
{
StringCchPrintf(szSubKey, MAX_PATH, L"CLSID//%s//InprocServer32", szClsid);
lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT,
szSubKey, 0,
NULL, REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL,
&hKey, NULL);
来源:(http://blog.sina.com.cn/s/blog_5f8817250100hry2.html) - DeskBand 实现5(注册)_LeeHong_新浪博客
if ( ERROR_SUCCESS == lResult )
{
WCHAR szModuleFile[MAX_PATH] = { 0 };
GetModuleFileName(hDlInstance, szModuleFile, MAX_PATH);
lResult = RegSetValueEx(hKey, NULL, 0, REG_SZ, (LPBYTE)szModuleFile, (DWORD)wcslen(szModuleFile) * sizeof(WCHAR));
WCHAR const szModel[] = L"Apartment";
lResult = RegSetValueEx(hKey, L"ThreadingModel", 0, REG_SZ, (LPBYTE)szModel, sizeof(szModel));
}
}
return (ERROR_SUCCESS == lResult) ? TRUE : FALSE;
}
//
BOOL SdkDeskBandHelper::RegisterComCategory(CLSID clsidCom)
{
ICatRegister *pCatReg = NULL;
HRESULT hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pCatReg));
if ( SUCCEEDED(hr) )
{
// 注册Band对象的类型
CATID catid[] = { CATID_DeskBand };
hr = pCatReg->RegisterClassImplCategories(clsidCom, 1, catid);
}
SAFE_RELEASE(pCatReg);
return (SUCCEEDED(hr)) ? TRUE : FALSE;
}
二、反注册
STDAPI DllUnregisterServer()
{
// Hide the desk band window.
CommonHelper::ShowDeskBand(FALSE);
// Find handle to the task bar.
HWND hTaskbarWnd = FindWindow(L"Shell_TrayWnd", NULL);
// If task bar receives this message, it will call CoFreeUnusedLibraries function
// immediately to free unused libraries.
PostMessage(hTaskbarWnd, WM_TIMER, 24, 0);
return (TRUE == SdkDeskBandHelper::UnregisterServer(CLSID_SdkDeskBand)) ? S_OK : SELFREG_E_CLASS;
}
其中SdkDeskBandHelper::UnregisterServer的实现如下:
BOOL SdkDeskBandHelper::UnregisterServer(CLSID clsidCom)
{
WCHAR szClsid[MAX_PATH] = { 0 };
StringFromGUID2(clsidCom, szClsid, MAX_PATH);
WCHAR szSubKey[MAX_PATH] = { 0 };
StringCchPrintf(szSubKey, MAX_PATH, L"CLSID//%s", szClsid);
LONG lResult = RegDeleteTree(HKEY_CLASSES_ROOT, szSubKey);
return (ERROR_SUCCESS == lResult) ? TRUE : FALSE;
}