• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 在基于MFC的組件程序中加入自卸載功能

    發表于:2007-07-14來源:作者:點擊數: 標簽:
    作者:Alexei Evdokimov譯自:CodeGuru 使用MFC實現COM組件時,經常節省許多 開發 時間。例如,使用AppWizard生成的基于MFC的COM dll工程,已經自動的提供了DllRegisterServer功能的實現。然而,卻沒有自動生成DllUnregisterServer功能。一般情況下,DllUnre
    作者:Alexei Evdokimov  譯自:CodeGuru

    使用MFC實現COM組件時,經常節省許多開發時間。例如,使用AppWizard生成的基于MFC的COM dll工程,已經自動的提供了DllRegisterServer功能的實現。然而,卻沒有自動生成DllUnregisterServer功能。一般情況下,DllUnregisterServer對于程序是不可缺少的,因為一個完整的程序,不僅需要自注冊功能,同時也需要自卸載功能。

    基于MFC實現DllRegisterServer()的方法是調用COleObjectFactory::UpdateRegistryAll()。這個方法有一個未公開的參數-(BOOL bRegister = TRUE) - 因此,我們猜測通過調用COleObjectFactory::UpdateRegistry(FALSE)將能夠實卸載COM dll的功能。但是,事實并非如此。通過分析源代碼,我們能夠知道COleObjectFactory::UpdateRegistryAll(BOOL bRegister)通過同樣的BOOL值調用COleObjectFactory::UpdateRegistry(BOOL bRegister),但是COleObjectFactory::UpdateRegistry(BOOL bRegister)的實現調用UpdateRegistry(LPCTSTR lpszProgID)函數,這個調用僅當bRegister為TRUE時注冊組件,否則什么都不做!

    所以,有必要寫我們自己的DllUnregisterServer()。下面的代碼能夠實現基于MFC的DllUnregisterServer(),并且使用非常的簡單。使用方法:

    - 創建文件DllUnregisterServer_MFC_Impl.inl

    - 把下面的代碼拷貝/粘貼到新建的文件中

    - 在dll的主文件.cpp中(dll_name.cpp)加入:


    #include "DllUnregisterServer_MFC_Impl.inl"

    - 在dll_name.def文件的EXPORTS片斷中加入:


    DllUnregisterServer PRIVATE

    完成!現在你可以使用"regsvr32 /u dll_name.dll"完成組件的卸載了。

    以下代碼測試環境為VC++ 5.0, VC++ 5.0 SP3, VC++ 6.0,ANSI環境。也可用于UNICODE環境。


    //**************************************************************************
    // Date : 11.15.98
    // Header : DllUnregisterServer_MFC_Impl.inl
    //
    // Desc.:   DllUnregisterServer() helper for the inproc servers that were
    //      registered via MFC’s COleObjectFactory::UpdateRegistryAll()
    //
    // Usage:
    //         Add ’#include "DllUnregisterServer_MFC_Impl.inl"’ to the end of
    //      the main dll file (i.e. dll_name.cpp).
    //
    //         Add ’DllUnregisterServer   PRIVATE’ to EXPORTS section of the
    //      dll_name.def.
    //
    // Caution:
    //         Code below uses undocumented, internal MFC data structures
    //      and functions. Therefore, probably, it will be necessary to modify
    //      it, aclearcase/" target="_blank" >ccording to the changes in the future versions of MFC.
    //         Code below is based on the COleObjectFactory::UpdateRegistryAll(),
    //      in srcolefact.cpp. (srcolereg.cpp - is actual implementation of
    //      all registry work).
    //**************************************************************************
    #include "stdafx.h"

    // workaround MFC bug - no #ifndef/#endif for afximpl.h header
    #if !defined(CRIT_OBJECTFACTORYLIST)
    #include <..srcafximpl.h>
    #endif      //!CRIT_OBJECTFACTORYLIST
    //**************************************************************************
    static HRESULT UnregisterCOMObject(REFCLSID p_clsid)
    {
       LPOLESTR t_wzProgID(NULL);

       // get ProgID from CLSID and unregister...
       HRESULT t_hr = ::ProgIDFromCLSID(p_clsid, &t_wzProgID);
       if(FAILED(t_hr))
          return t_hr;

       // convert OLESTR to LPTSTR
       CString t_strProgID(t_wzProgID);
       LPCTSTR t_szProgID = t_strProgID.operator LPCTSTR();

       // free memory
       ::CoTaskMemFree(t_wzProgID);

       // unregister...
       if(AfxOleUnregisterServerClass(p_clsid,
                       t_szProgID,
                       t_szProgID,
                       t_szProgID,
                       OAT_DISPATCH_OBJECT))
          return S_OK;
       else
          return E_FAIL;
    }
    //**************************************************************************
    // by exporting DllUnregisterServer, you can use regsvr.exe
    STDAPI DllUnregisterServer(void)
    {
       AFX_MANAGE_STATE(AfxGetStaticModuleState());


       AFX_MODULE_STATE* pModuleState = AfxGetModuleState();

       AfxLockGlobals(CRIT_OBJECTFACTORYLIST);
       for(COleObjectFactory* pFactory = pModuleState->m_factoryList;
          pFactory != NULL;
          pFactory = pFactory->m_pNextFactory)
       {
          HRESULT t_hr = UnregisterCOMObject(pFactory->GetClassID());
          if(FAILED(t_hr))
          {
             AfxUnlockGlobals(CRIT_OBJECTFACTORYLIST);
             return t_hr;
          }
       }
       AfxUnlockGlobals(CRIT_OBJECTFACTORYLIST);

    #ifdef _AFXDLL
       AfxLockGlobals(CRIT_DYNLINKLIST);
       // register extension DLL factories
       for(CDynLinkLibrary* pDLL = pModuleState->m_libraryList;
          pDLL != NULL;
          pDLL = pDLL->m_pNextDLL)
       {
          for(pFactory = pDLL->m_factoryList;
             pFactory != NULL;
             pFactory = pFactory->m_pNextFactory)
          {
             HRESULT t_hr = UnregisterCOMObject(pFactory->GetClassID());
             if(FAILED(t_hr))
             {
                AfxUnlockGlobals(CRIT_DYNLINKLIST);
                return t_hr;
             }
          }
       }
       AfxUnlockGlobals(CRIT_DYNLINKLIST);
    #endif

       return S_OK;
    }
    //**************************************************************************
    // end of DllUnregisterServer_MFC_Impl.inl 

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>