现在的位置: 首页 > 综合 > 正文

DeskBand实现之——注册与反注册

2018年09月03日 ⁄ 综合 ⁄ 共 3296字 ⁄ 字号 评论关闭

有了COM对象后,必须对浏览栏的CLSID进行注册。另外如果要与IE或资源管理器协调运行,还必须进行的恰当的组件种类(CATID_DeskBand)注册。这个工作由DllRegisterServer处理。实现代码如下:

注册表中的结构如下图:

1. 注册

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);
        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;
}

2. 反注册

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;
}


抱歉!评论已关闭.