久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

用MFC進(jìn)行COM編程

 uqt123 2012-10-04

用MFC進(jìn)行COM編程- -

                                      

[轉(zhuǎn)載]VC++6.0中用MFC進(jìn)行COM編程


說(shuō)明 很有用的帖子 盡管有點(diǎn)老

首先應(yīng)當(dāng)明確,MFC中是通過(guò)嵌套類而不是多重繼承來(lái)實(shí)現(xiàn)COM接口的,,通過(guò)接口映射機(jī)制將接口和實(shí)現(xiàn)該接口的嵌套類關(guān)聯(lián)起來(lái),;MFC中提供一套簡(jiǎn)明的宏來(lái)實(shí)現(xiàn)嵌套類的定義.其次,MFC通過(guò)CCmdTarget類實(shí)現(xiàn)了IUnknown接口,。
  本文首先描述創(chuàng)建一個(gè)COM服務(wù)器的步驟和核心代碼.然后說(shuō)明客戶程序關(guān)鍵代碼。

  此COM服務(wù)器實(shí)現(xiàn)一個(gè)TimeLogServer組件,,為簡(jiǎn)明起見(jiàn),,此組件只有一個(gè)接口ITimeLog,通過(guò)ITimeLog的方法OutputLog可以將日志文本輸出至日志文件,。

  創(chuàng)建一個(gè)MFC DLL工程,,選擇支持Automation(當(dāng)然本程序不一定是自動(dòng)化服務(wù)器,在這里這樣做好處在于自動(dòng)實(shí)現(xiàn)了幾個(gè)必要的輸出函數(shù)如DllGetClassObject,,DllRegisterServer等,,否則要自己寫(xiě))

  第一節(jié) COM服務(wù)器

  一. 聲明組件和接口

  1.寫(xiě)一個(gè)GUIDs.h,在GUIDs.h中聲明組件和接口的GUID

//聲明組件GUID {A433E701-E45E-11d3-97B5-52544CBA7F28}
//DEFINE_GUID(CLSID_TimeLogServer,,
//0xa433e701,, 0xe45e, 0x11d3,, 0x97,, 0xb5, 0x52,, 0x54,, 0x4c, 0xba,, 0x7f,, 0x28);
static const IID CLSID_TimeLogServer =
{0xa433e701,, 0xe45e,, 0x11d3, {0x97,, 0xb5,, 0x52, 0x54,, 0x4c,, 0xba, 0x7f,, 0x28}},;
// 聲明接口GUID{A433E702-E45E-11d3-97B5-52544CBA7F28}
//DEFINE_GUID(IID_ITimeLog,
//0xa433e702, 0xe45e,, 0x11d3,, 0x97, 0xb5,, 0x52,, 0x54, 0x4c,, 0xba,, 0x7f, 0x28),;
static const IID IID_ITimeLog =
{0xa433e702,, 0xe45e, 0x11d3,, {0x97,, 0xb5, 0x52,, 0x54,, 0x4c, 0xba,, 0x7f,, 0x28}};

  2.寫(xiě)一個(gè)ITimeLogServer.h,,在ITimeLogServer.h文件中聲明組件和接口

//ITimeLogServer.h
#include ";GUIDs.h",;
//接口ITimeLog的聲明
DECLARE_INTERFACE_(ITimeLog,,IUnknown)
{
    STDMETHOD(OutputLog)(BSTR* varLogText)PURE;
},;

  說(shuō)明:

  1.宏DEFINE_GUID將組件和接口的progid與GUID相關(guān)聯(lián).可以用guidgen.exe工具產(chǎn)生,。

  2.宏DECLARE_INTERFACE_聲明接口;該宏第一個(gè)參數(shù)為接口名,,第二個(gè)參數(shù)為該接口的基類.聲明沒(méi)有基類的接口用DECLARE_INTERFACE宏,。

  3.宏STDMETHOD聲明接口中的方法.此方法的返回值為HRESULT.PURE被解釋為";=0",;,,即此方法為純虛函數(shù).當(dāng)方法的返回值不是HRESULT時(shí),用宏STDMETHOD_(返回類型,,函數(shù)名)(參數(shù))PURE,;

二.聲明組件類CTimeLogServer和實(shí)現(xiàn)接口的嵌套類

  在ClassWizard中添加新類CTimeLogServer,其基類選擇為CCmdTarget.修改其頭文件TimeLogServer1.h,加上#include ",;ITimeLogServer.h",;;同時(shí)在類聲明體中加上

//聲明實(shí)現(xiàn)ITimelog接口的嵌套類
    BEGIN_INTERFACE_PART(TimeLog,,ITimeLog)//自動(dòng)聲明IUnknown接口的三個(gè)方法
    STDMETHOD(OutputLog)(BSTR* varLogText),;
    END_INTERFACE_PART(TimeLog)
    //聲明接口映射
    DECLARE_INTERFACE_MAP()
    //聲明類廠
    DECLARE_OLECREATE(CTimeLogServer)

  三.實(shí)現(xiàn)類廠和接口映射

  在CTimeLogServer的實(shí)現(xiàn)文件中寫(xiě)入:

//實(shí)現(xiàn)類廠
IMPLEMENT_OLECREATE(CTimeLogServer,",;TimeLogServer",;,
0xa433e701,, 0xe45e,, 0x11d3, 0x97,, 0xb5,, 0x52, 0x54,, 0x4c,, 0xba, 0x7f,, 0x28),;
//映射接口到相應(yīng)的嵌套類
BEGIN_INTERFACE_MAP(CTimeLogServer,CCmdTarget)
INTERFACE_PART(CTimeLogServer,,IID_ITimeLog,,TimeLog)
END_INTERFACE_MAP()

  四.在組件的構(gòu)造和析構(gòu)函數(shù)中對(duì)全局對(duì)象計(jì)數(shù)

CTimeLogServer::CTimeLogServer()
{
    ::AfxOleLockApp();
}

CTimeLogServer::~CTimeLogServer()
{
    ::AfxOleUnlockApp(),;
}


  五.為嵌套類實(shí)現(xiàn)IUnknown接口

//為嵌套類而實(shí)現(xiàn)IUnknown接口
STDMETHODIMP_(ULONG)
CTimeLogServer::XTimeLog::AddRef()
{
    METHOD_PROLOGUE(CTimeLogServer,,TimeLog)
    return pThis->;ExternalAddRef(),;
}

STDMETHODIMP_(ULONG)
CTimeLogServer::XTimeLog::Release()
{
    METHOD_PROLOGUE(CTimeLogServer,,TimeLog)
    return pThis->;ExternalRelease(),;
}

STDMETHODIMP
CTimeLogServer::XTimeLog::QueryInterface(REFIID riid,,void**ppvObj)
{
    METHOD_PROLOGUE(CTimeLogServer,TimeLog)
    return pThis->,;ExternalQueryInterface(&,;riid,ppvObj),;
}


  說(shuō)明:雖然CCmdTarget類已經(jīng)實(shí)現(xiàn)了IUnknown接口,,但是還必須通過(guò)上述代碼來(lái)將嵌套類的IUnknown映射到CCmdTarget支持的IUnknown接口.METHOD_PROLOGUEH宏的兩個(gè)參數(shù)分別是實(shí)現(xiàn)組件對(duì)象的類和實(shí)現(xiàn)接口的嵌套類,。

六.實(shí)現(xiàn)ItimeLog接口的方法OutputLog

  注意本組件的功能是往日志文件中輸入日志.

  1. 在組件類中添加一個(gè)文件指針:

 // Attributes
 public:
 protected:
      FILE* m_logfile;

  2. 初始化和退出

  首先在CTimeLogServer的構(gòu)造函數(shù)中進(jìn)行一些初始化:

CTimeLogServer::CTimeLogServer()
{
    ::AfxOleLockApp(),;
    CTime TimeStamp = CTime::GetCurrentTime(),;
    CString FileName;
    FileName.Format(_T(",;%s.log",;),TimeStamp.Format(",;%Y%m%d",;));
    m_logfile = fopen(FileName,,_T(",;a";)),;
    if(m_logfile)
    {
        fprintf(m_logfile,,_T(";# # # # # # # # # # # # # # # # # n",;)),;
        fprintf(m_logfile,_T(",;開(kāi)始于:%s",;),(LPCTSTR)TimeStamp.Format(",;%Y年%m月%d日%H:%M %S",;));
        fprintf(m_logfile,,_T(",;n";)),;
    }
}
//然后在析構(gòu)函數(shù)中關(guān)閉文件
CTimeLogServer::~CTimeLogServer()
{
    ::AfxOleUnlockApp();
    if(m_logfile)
    {
        CTime TimeStamp = CTime::GetCurrentTime(),;
        fprintf(m_logfile,,_T(";n",;)),;
        fprintf(m_logfile,_T(",;結(jié)束于:%s",;),(LPCTSTR)TimeStamp.Format(";%Y年%m月%d日%H:%M %S",;)),;
    fprintf(m_logfile,_T(",;n",;));
        fprintf(m_logfile,,_T(",;# # # # # # # # # # # # # # # # #n";)),;
        fclose(m_logfile),;
    }
}

  3. 實(shí)現(xiàn)接口ITimeLog方法

//實(shí)現(xiàn)接口ITimeLog方法
STDMETHODIMP
CTimeLogServer::XTimeLog::OutputLog(BSTR* varLogText)
{
    METHOD_PROLOGUE(CTimeLogServer,TimeLog)
    if(pThis->,;m_logfile)
    {
        CTime TimeStamp = CTime::GetCurrentTime(),;
        CString NowTime = TimeStamp.Format(";%Y年%m月%d日%H:%M:%S",;),;
        CString LogText((LPCWSTR)*varLogText);
fprintf(pThis->,;m_logfile,,";n%sn%sn%",;,,NowTime,LogText),;
        return NOERROR,;
    }
    else
    {
AfxMessageBox(";沒(méi)有日志文件!",;),;
        return S_FALSE;
    }
}

  七.完善組件服務(wù)器

  在應(yīng)用對(duì)象CTimeLogServerApp的 實(shí)現(xiàn)文件中,,處理Instance()和ExitInstance()

BOOL CTimeLogServerApp::InitInstance()
{
    ::AfxOleLockApp(),;
    // Register all OLE server (factories) as running. This enables the
    // OLE libraries to create objects from other applications.
    COleObjectFactory::RegisterAll();

    return TRUE,;
}
int CTimeLogServerApp::ExitInstance()
{
    // TODO: Add your specialized code here and/or call the base class
  ::AfxOleUnlockApp(),;
    return CWinApp::ExitInstance();
}


  第二節(jié) 客戶程序

  使用COM組件服務(wù)器的客戶程序關(guān)鍵步驟是:初始化COM庫(kù),,創(chuàng)建組件對(duì)象并獲取IUnknown接口指針,,查詢接口并使用,,釋放組件。

  #include ",;ITimeLogServer.h",;
  //初始化COM庫(kù),對(duì)組件實(shí)例化
    HRESULT hResult,;
  IUnknown* pIUnknown,;
    hResult = ::CoInitialize(NULL);
    if(FAILED(hResult))
    {
        ::AfxMessageBox(",;不能初始化COM庫(kù)!",;);
        return FALSE,;
    }

  //創(chuàng)建組件實(shí)例
  pIUnknown = NULL,;
    hResult = ::CoCreateInstance(CLSID_TimeLogServer,NULL,,
        CLSCTX_INPROC_SERVER,,IID_IUnknown,(void**)&,;pIUnknown),;
    if(FAILED(hResult))
    {
        pIUnknown = NULL;
        ::AfxMessageBox(",;不能創(chuàng)建TimeLog對(duì)象!",;);
        return FALSE,;
    }
  //查詢接口并使用
  if(pIUnknown!=NULL)
        {
            ITimeLog* pITimeLog,;
HResult=pIUnknown->;QueryInterface(IID_ITimeLog,,(void**)&,;pITimeLog);
            if(FAILED(hResult))
            {
            ::AfxMessageBox(",;不能獲取接口ITimeLog!",;);
                pIUnknown->,;Release(),;
                return;
            }
            BSTR bstrLogText,;
            bstrLogText = m_logtext.AllocSysString(),;
            CString text((LPCWSTR)bstrLogText),;
            ::AfxMessageBox(text),;

            if(FAILED(pITimeLog->,;OutputLog(&;bstrLogText)))
            {
                ::AfxMessageBox(",;日志輸出出錯(cuò)!",;);
                pITimeLog->,;Release(),;
                return;
            }
            pITimeLog->,;Release(),;
            ::AfxMessageBox(";日志已經(jīng)寫(xiě)入!",;),;
        }
    //釋放組件
    pIUnknown->;Release(),;
    pIUnknown = NULL,;
      ::CoUninitialize();

- 作者: 天涯-明月 2005年04月1日, 星期五 22:47 加入博采

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多