TN065: Dual-Interface ʹѺʹعÊÓËÃѺà«ÔÃì¿àÇÍÃì OLE Automation

ËÁÒÂà˵عÕé͸ԺÒ¶֧ÇÔ¸Õ¡ÒÃà¾ÔèÁ¡ÒÃʹѺʹعÍÔ¹à·ÍÃì࿫Ẻ´ÙÍÑÅŧáÍ»¾ÅÔपѹà«ÔÃì¿àÇÍÃìãªé MFC OLE Automation ACDUALÍÂèÒ§áÊ´§ãËéàËç¹¶Ö§¡ÒÃʹѺʹعÍÔ¹à·ÍÃì࿫Ẻ´ÙÍÑÅ áÅÐâ¤é´µÑÇÍÂèÒ§ã¹ËÁÒÂà˵عÕé¹ÓÁÒ¨Ò¡ ACDUAL áÁâ¤Ã·Õè͸ԺÒÂäÇéã¹ËÁÒÂà˵عÕé àªè¹ DECLARE_DUAL_ERRORINFO , DUAL_ERRORINFO_PART áÅÐ IMPLEMENT_DUAL_ERRORINFO à»ç¹Êèǹ˹Ö觢ͧµÑÇÍÂèÒ§ ACDUAL áÅÐÊÒÁÒö¾ºä´éã¹ MFCDUALH?

ÍÔ¹à·ÍÃì࿫Ẻ¤Ùè

áÁéÇèÒ OLE Automation ªèÇÂãË館³ÊÒÁÒöãªéÍÔ¹à·ÍÃìà¿«IDispatchÊèǹµÔ´µèÍẺ VTBL ËÃ×ÍÍÔ¹à·ÍÃì࿫Ẻ¤Ùè («Ö觤Ãͺ¤ÅØÁ·Ñé§ÊͧÍÂèÒ§), Microsoft ¢Íá¹Ð¹ÓãËé ¤Ø³ãªéÍÔ¹à·ÍÃì࿫Ẻ¤ÙèÊÓËÃѺÇѵ¶Ø OLE Automation exposed ·Ñé§ËÁ´ ÍÔ¹à·ÍÃì࿫Ẻ¤ÙèÁÕ¢éÍä´éà»ÃÕº·ÕèÊӤѭ¼èÒ¹IDispatch-ÍÔ¹à·ÍÃìà¿«·Õè੾ÒÐ ËÃ×Í VTBL à·èÒ¹Ñé¹:

¡ÒÃà¾ÔèÁ¡ÒÃʹѺʹعÍÔ¹à·ÍÃì࿫Ẻ´ÙÍÑŤÅÒÊ·Õèãªé CCmdTarget

ÍÔ¹à·ÍÃìà¿«Êͧà»ç¹à¾Õ§¡ÒõԴµèÍẺ¡Ó˹´àͧ·Õèä´éÁÒ¨Ò¡IDispatch ÇÔ¸Õãªé¡ÒÃʹѺʹعÍÔ¹à·ÍÃì࿫Ẻ´ÙÍÑÅã¹CCmdTargetµÃ§ä»µÃ§ÁÒÁÒ¡·ÕèÊØ´-¤ÅÒʵÒÁ¤×Í¡ÒÃáá·Ó¡ÒÃÊÃØ»¢éÍÁÙÅ»¡µÔÍÔ¹à·ÍÃìà¿«º¹ªÑ鹢ͧ¤Ø³â´Âãªé MFC áÅÐ ClassWizard áÅéÇà¾ÔèÁÊèǹµÔ´µèÍẺ¡Ó˹´àͧã¹ÀÒÂËÅѧ ÊèǹãË­è ¡ÒÃãªé§Ò¹ÍÔ¹à·ÍÃì࿫Ẻ¡Ó˹´àͧ¢Í§¤Ø³¨Ðà¾Õ§ÁͺËÁÒ¡ÅѺä»ãªé§Ò¹ MFC IDispatch?

¤ÃÑé§áá »ÃѺà»ÅÕè¹á¿éÁ ODL ÊÓËÃѺà«ÔÃì¿àÇÍÃì¢Í§¤Ø³à¾×èÍ¡Ó˹´ÍÔ¹à·ÍÃì࿫Ẻ¤ÙèÊÓËÃѺÇѵ¶Ø¢Í§¤Ø³ ¡ÒáÓ˹´ÍÔ¹à·ÍÃìà¿«Êͧ ¤Ø³µéͧãªé¤ÓÊÑè§ÍÔ¹à·ÍÃìà¿« á·¹ DISPINTERFACE ¤ÓÊÑè§·ÕèÊÃéÒ§¢Öé¹ã¹µÑǪèÇÂÊÃéÒ§¢Í§ Visual c ++ á·¹·ÕèàÍÒ·ÕèÁÕÍÂÙè DISPINTERFACE §º à¾ÔèÁ¤ÓÊÑè§ÍÔ¹à·ÍÃìà¿«ãËÁè â´Â¡ÒÃÃÑ¡ÉÒ¡Òà DISPINTERFACE Ẻ¿ÍÃìÁ¤Ø³ÊÒÁÒöãªé ClassWizard à¾×èÍà¾ÔèÁ¤Ø³ÊÁºÑµÔáÅÐàÁ¸Í´¢Í§Çѵ¶Ø áµè¤Ø³µéͧà¾ÔèÁ¤Ø³ÊÁºÑµÔà·Õºà·èÒáÅÐÇÔ¸Õ¡ÒäӪÕéᨧ¢Í§ÍÔ¹à·ÍÃìà¿«?

¤ÓÊÑè§ÍÔ¹à·ÍÃìà¿«ÊÓËÃѺÍÔ¹à·ÍÃì࿫Ẻ¤ÙèµéͧÁÕOLEAUTOMATIONáÅÐá͵·ÃÔºÔǵìDUALáÅÐÍÔ¹à·ÍÃìà¿«µéͧä´éÁÒ¨Ò¡IDispatch ¤Ø³ÊÒÁÒöãªé¡Òà GUIDGENµÑÇÍÂèÒ§¡ÒÃÊÃéÒ§IIDÊÓËÃѺÍÔ¹à·ÍÃì࿫Ẻ dual

[uuid(0BDD0E81-0DD7-11cf-BBA8-444553540000), / / IID_IDualAClick
 nbsp oleautomation
   ÍÑÅ
]
ÍÔ¹à·ÍÃìà¿« IDualAClick: IDispatch
  {
  }(&N)

àÁ×èͤسÁÕ¤ÓÊÑè§ÍÔ¹à·ÍÃìà¿«ã¹Ê¶Ò¹·Õè àÃÔèÁà¾ÔèÁÃÒ¡ÒÃÊÓËÃѺàÁ¸Í´áÅФسÊÁºÑµÔ ÊÓËÃѺÍÔ¹à·ÍÃìà¿«·ÕèÊͧ ¤Ø³¨Óà»ç¹µéͧ¨Ñ´àÃÕ§ÃÒ¡ÒþÒÃÒÁÔàµÍÃìà¾×èÍãËéàÁ¸Í´áÅФسÊÁºÑµÔà¢éÒ¶Ö§¿Ñ§¡ìªÑ¹ã¹ÍÔ¹à·ÍÃì࿫Ẻ¤Ùè¢Í§¤Ø³¡ÅѺhresult 㹡Òà áÅСÒÃÊè§¼èÒ¹¤èÒÊ觤׹à»ç¹¾ÒÃÒÁÔàµÍÃì´éÇÂá͵·ÃÔºÔǵì [retval,out] â»Ã´¨ÓäÇéÇèÒ ÊÓËÃѺ¤Ø³ÊÁºÑµÔ ¤Ø³¨Ðµéͧà¾ÔèÁ¡ÒÃÍèÒ¹·Ñé§Êͧ ( propget ) áÅÐà¢Õ¹ ( propput ) ¡ÒÃà¢éÒ¶Ö§¿Ñ§¡ìªÑ¹ ´éÇ id à´ÕÂǡѹ µÑÇÍÂèÒ§àªè¹:

[propput, id(1)] Hresult ã¹¢éÍ ([ã¹] BSTR newText);
[propget, id(1)] Hresult ã¹¢éͤÇÒÁ ([ÍÍ¡ retval] BSTR * retval)

ËÅѧ¨Ò¡·ÕèàÁ¸Í´áÅФسÊÁºÑµÔ¢Í§¤Ø³¶Ù¡¡Ó˹´ ¤Ø³µéͧ¡ÒÃà¾ÔèÁ¡ÒÃÍéÒ§ÍÔ§¶Ö§¤ÓÊÑè§ÍÔ¹à·ÍÃì࿫㹤ӪÕéᨧ¢Í§¤Ø³ coclass µÑÇÍÂèÒ§àªè¹:

[uuid(4B115281-32F0-11cf-AC85-444553540000)]
coclass àÍ¡ÊÒÃ
{
 nbsp dispinterface IAClick
   ÍÔ¹à·ÍÃìà¿« [àÃÔèÁµé¹] IDualAClick
}(&N)

àÁ×èÍÁÕ¡ÒûÃѺ»Ãاá¿éÁ¢Í§¤Ø³ ODL ãªé¡Åä¡¡ÒÃá¼¹·Õè MFC ¢Í§ÍÔ¹à·ÍÃìà¿«¡ÒáÓ˹´¤ÅÒ¡ÒÃãªé§Ò¹ÊÓËÃѺÍÔ¹à·ÍÃì࿫Ẻ¤Ùè㹪Ñ鹢ͧÇѵ¶Ø áÅзÓÃÒ¡Ò÷Õèà¡ÕèÂÇ¢éͧ㹡Åä¡QueryInterface¢Í§ MFC ¤Ø³µéͧ¡ÒÃãËéÃÒ¡ÒÃ˹Öè§ã¹¡Òà INTERFACE_PART ºÅçÍ¡ÊÓËÃѺáµèÅÐÃÒ¡ÒÃã¹§º¡ÒÃÍÔ¹àµÍÃìà¿«¢Í§µÑÇ ODL ºÇ¡ÃÒ¡ÒÃÊÓËÃѺÍÔ¹à·ÍÃìà¿«¡ÒÃÊÃØ»¢éÍÁÙÅ áµèÅÐÃÒ¡Òà ODL ¡Ñºá͵·ÃÔºÔǵìpropputµéͧ¡Òÿѧ¡ìªÑ¹ª×èÍÇèÒ put_propertyname áµèÅÐÃÒ¡Ò÷Õè ÁÕá͵·ÃÔºÔǵìpropgetµéͧ¡Òÿѧ¡ìªÑ¹·Õèª×èÍget_propertyname?

àÁ×è͵éͧ¡ÒáÓ˹´¤ÅÒ¡ÒÃãªé§Ò¹ÊÓËÃѺÍÔ¹à·ÍÃìà¿«¢Í§ÍÑÅ à¾ÔèÁ¡Òà DUAL_INTERFACE_PART ºÅçÍ¡¢Í§¤Ø³¢éÍ¡Ó˹´ªÑ鹢ͧÇѵ¶Ø µÑÇÍÂèÒ§àªè¹:

BEGIN_DUAL_INTERFACE_PART (DualAClick, IDualAClick)
  STDMETHOD(put_text) (THIS_ BSTR newText);
  STDMETHOD(get_text) (THIS_ BSTR ä¡Å * retval);
  STDMETHOD(put_x) (THIS_ ÊÑé¹ newX);
  STDMETHOD(get_x) (THIS_ ÊÑé¹ä¡Å * retval);
  STDMETHOD(put_y) (THIS_ ÊÑé¹ newY);
  STDMETHOD(get_y) (THIS_ ÊÑé¹ä¡Å * retval);
  STDMETHOD(put_Position) (THIS_ IDualAutoClickPoint ä¡Å * newPosition);
  STDMETHOD(get_Position) (THIS_ IDualAutoClickPoint ä¡Å * ä¡Å * retval);
  STDMETHOD(RefreshWindow)(THIS)
  STDMETHOD(SetAllProps) (THIS_ ÊÑé¹ x, y ÊÑé¹ ¢éͤÇÒÁ BSTR);
  STDMETHOD(ShowWindow)(THIS)
END_DUAL_INTERFACE_PART(DualAClick)

¡ÒÃàª×èÍÁµèÍÍÔ¹à·ÍÃìà¿Ê·ÕèÊͧ¢Í§ MFC QueryInterface¡Åä¡ à¾ÔèÁ¡Òà INTERFACE_PART ¡ÒÃáÁ»ÍÔ¹à·ÍÃìà¿«ÃÒ¡ÒÃ

BEGIN_INTERFACE_MAP (CAutoClickDoc, CDocument)
  INTERFACE_PART (CAutoClickDoc, DIID_IAClick ¨Ñ´Êè§)
  INTERFACE_PART (CAutoClickDoc, IID_IDualAClick, DualAClick)
END_INTERFACE_MAP()

¶Ñ´ä» ¤Ø³¨Óà»ç¹µéͧ¡ÃÍ¡¢éÍÁÙÅ㹡ÒÃãªé§Ò¹ÍÔ¹à·ÍÃìà¿« ÊèǹãË­è ¤Ø³¨ÐÊÒÁÒöÁͺËÁÒÂ㹡ÒÃãªé§Ò¹ MFC IDispatch·ÕèÁÕÍÂÙè µÑÇÍÂèÒ§àªè¹:

STDMETHODIMP_(ULONG) CAutoClickDoc::XDualAClick::AddRef()
{
   METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
   return pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) CAutoClickDoc::XDualAClick::Release()
{
   METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
   return pThis->ExternalRelease();
}
STDMETHODIMP CAutoClickDoc::XDualAClick::QueryInterface(
             REFIID iid, LPVOID* ppvObj)
{
   METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
   return pThis->ExternalQueryInterface(&iid, ppvObj);
}
STDMETHODIMP CAutoClickDoc::XDualAClick::GetTypeInfoCount(
            UINT FAR* pctinfo)
{
   METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
   LPDISPATCH lpDispatch = pThis->GetIDispatch(FALSE);
   ASSERT(lpDispatch != NULL);
   return lpDispatch->GetTypeInfoCount(pctinfo);
}
STDMETHODIMP CAutoClickDoc::XDualAClick::GetTypeInfo(
          UINT itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
{
   METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
   LPDISPATCH lpDispatch = pThis->GetIDispatch(FALSE);
   ASSERT(lpDispatch != NULL);
   return lpDispatch->GetTypeInfo(itinfo, lcid, pptinfo);
}
STDMETHODIMP CAutoClickDoc::XDualAClick::GetIDsOfNames(
       REFIID riid, OLECHAR FAR* FAR* rgszNames, UINT cNames,
       LCID lcid, DISPID FAR* rgdispid) 
{
   METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
   LPDISPATCH lpDispatch = pThis->GetIDispatch(FALSE);
   ASSERT(lpDispatch != NULL);
   return lpDispatch->GetIDsOfNames(riid, rgszNames, cNames, 
                                    lcid, rgdispid);
}
STDMETHODIMP CAutoClickDoc::XDualAClick::Invoke(
    DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
    DISPPARAMS FAR* pdispparams, VARIANT FAR* pvarResult,
    EXCEPINFO FAR* pexcepinfo, UINT FAR* puArgErr)
{
   METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
   LPDISPATCH lpDispatch = pThis->GetIDispatch(FALSE);
   ASSERT(lpDispatch != NULL);
   return lpDispatch->Invoke(dispidMember, riid, lcid,
                             wFlags, pdispparams, pvarResult,
                             pexcepinfo, puArgErr);
}

ÊÓËÃѺ¢Í§Çѵ¶Ø¢Í§ÇÔ¸Õ¡ÒÃáÅФسÊÁºÑµÔà¢éÒ¶Ö§¿Ñ§¡ìªÑ¹ ¤Ø³¨Óà»ç¹µéͧ¡ÒáÃÍ¡¢éÍÁÙÅ㹡ÒÃãªé§Ò¹ ¿Ñ§¡ìªÑ¹¢Í§àÁ¸Í´áÅФسÊÁºÑµÔâ´Â·ÑèÇ仨Ðä´éÊÒÁÒöÁͺËÁÒ¡ÅѺä»ãªéÇÔ¸Õ¡Ò÷ÕèÊÃéÒ§â´Âãªé ClassWizard ÍÂèÒ§äáçµÒÁ ¶éҤسµÑ駤سÊÁºÑµÔ㹡ÒÃà¢éÒ¶Ö§µÑÇá»Ãâ´ÂµÃ§ ¤Ø³¨Óà»ç¹µéͧà¢Õ¹â¤é´à¾×èÍÃѺ/ÂéÒ¤èÒà»ç¹µÑÇá»Ã µÑÇÍÂèÒ§àªè¹:

STDMETHODIMP CAutoClickDoc::XDualAClick::put_text(BSTR newText)
{
 nbsp METHOD_PROLOGUE (CAutoClickDoc, DualAClick)
   / / MFC á»Å§â´ÂÍѵâ¹ÁѵԨҡ Unicode BSTR ¡Òà / / Ansi CString ¶éÒ¨Óà»ç¹...
   pThis - > m_str = newText
   ¡ÅѺ NOERROR
}
STDMETHODIMP CAutoClickDoc::XDualAClick::get_text(BSTR* retval)
{
   METHOD_PROLOGUE (CAutoClickDoc, DualAClick)
   / / MFC á»Å§¨Ò¡ Ansi CString ¡Òà / / Unicode BSTR ¶éÒ¨Óà»ç¹...
   pThis - > m_strSetSysString(retval)
   ¡ÅѺ NOERROR
}

µÑǪÕéẺ´ÙÍÑÅÍÔ¹à·ÍÃìà¿«¼èÒ¹

¼èÒ¹µÑǪÕé¢Í§¤Ø³´ÙÍÑÅÍÔ¹à·ÍÃìà¿«äÁèµÃ§ä»µÃ§ÁÒ â´Â੾ÒÐÍÂèÒ§ÂÔè§¶éҤس¨Óà»ç¹µéͧâ·ÃCCmdTarget::FromIDispatch FromIDispatch·Ó§Ò¹à©¾Òк¹µÑǪÕéIDispatch¢Í§ MFC ÇÔ¸Õ˹Öè§ã¹¡Ò÷ӧҹÃͺ¹Õé¤×Í¡ÒÃÊͺ¶ÒÁÊÓËÃѺªØ´µÑǪÕéIDispatchµé¹©ºÑº¢Öé¹ â´Â MFC áÅмèÒ¹·ÕèªÕéä»Âѧ¿Ñ§¡ìªÑ¹·Õè¨Óà»ç¹ µÑÇÍÂèÒ§àªè¹

 STDMETHODIMP CAutoClickDoc::XDualAClick::put_Position (
 nbsp    IDualAutoClickPoint ä¡Å * newPosition)
{
   METHOD_PROLOGUE (CAutoClickDoc, DualAClick)
   LPDISPATCH lpDisp = NULL
   newPosition - > QueryInterface (IID_IDispatch, (LPVOID *) & lpDisp);
   pThis - > SetPosition(lpDisp)
   lpDisp - > Release()
   ¡ÅѺ NOERROR
}

¡è͹¡ÅѺ¼èÒ¹ÇÔ¸Õ¡ÒÃÍÔ¹à·ÍÃì࿫Ẻ´ÙÍÑÅ ÁÒªÕé·Õè¤Ø³ÍÒ¨µéͧ¡ÒÃá»Å§¨Ò¡µÑǪÕé MFC IDispatchãËéÇÒ§µÑǪÕé¢Í§¤Ø³´ÙÍÑÅÍÔ¹à·ÍÃìà¿« µÑÇÍÂèÒ§àªè¹:

STDMETHODIMP CAutoClickDoc::XDualAClick::get_Position (
 nbsp    IDualAutoClickPoint * ä¡Åä¡Å * retval)
{
   METHOD_PROLOGUE (CAutoClickDoc, DualAClick)
   LPDISPATCH lpDisp
   lpDisp = pThis - > GetPosition()
   lpDisp - > QueryInterface (IID_IDualAutoClickPoint, (LPVOID *) retval);
   ¡ÅѺ NOERROR
}

¡ÓÅѧŧ·ÐàºÕ¹äźÃÒÃÕª¹Ô´¢Í§â»Ãá¡ÃÁ»ÃÐÂØ¡µì

AppWizard ÊÃéÒ§ÃËÑÊŧ·ÐàºÕ¹äźÃÒÃÕª¹Ô´ OLE Automation à«ÔÃì¿àÇÍÃì¢Í§â»Ãá¡ÃÁ»ÃÐÂØ¡µì¡ÑºÃкº ã¹¢³Ð·ÕèÁÕÇÔ¸Õ¡ÒÃŧ·ÐàºÕ¹äźÃÒÃÕª¹Ô´Í×è¹ æ ÁѹÊдǡʺÒÂà¾×èÍãËéâ»Ãá¡ÃÁ»ÃÐÂØ¡µì·Õèŧ·ÐàºÕ¹äźÃÒÃÕª¹Ô´àÁ×èÍÁѹ¡ÓÅѧ»ÃѺ»Ãا¢éÍÁÙŪ¹Ô´¢Í§ OLE ¡ÅèÒǤ×Í àÁ×èÍã´¡ç µÒÁ·Õèâ»Ãá¡ÃÁ»ÃÐÂØ¡µì·ÕèÁÕ¡ÒÃàÃÕ¡ãªéẺÊáµ¹´ìÍâŹ?

¡ÒÃŧ·ÐàºÕ¹äźÃÒÃÕª¹Ô´¢Í§â»Ãá¡ÃÁ»ÃÐÂØ¡µìàÁ×èÍâ»Ãá¡ÃÁ»ÃÐÂØ¡µì·ÕèÁÕ¡ÒÃàÃÕ¡ãªéẺÊáµ¹´ìÍâŹ:

»ÃѺà»ÅÕ蹡ÒõÑ駤èÒâ¤Ã§ÊÃéÒ§à¾×èÍÃͧÃѺ¡ÒÃà»ÅÕè¹á»Å§ª¹Ô´äźÃÒÃÕ

¡ÒûÃѺà»ÅÕè¹ ¢Í§â¤Ã§¡ÒÃÊÃéÒ§¡ÒõÑ駤èÒà¾×èÍãËéá¿éÁËÑÇ¢éÍ·Õè»ÃСͺ´éǤӹÔÂÒÁUUID¶Ù¡ÊÃéÒ§¢Öé¹â´Â MkTypLib·Ø¡¤ÃÑé§·ÕèÁÕÊÃéÒ§äźÃÒÃÕª¹Ô´

  1. ¨Ò¡àÁ¹Ù Build ¤ÅÔ¡µÑ駤èÒ áÅéÇàÅ×Í¡á¿éÁ ODL ¨Ò¡ÃÒ¡ÒÃá¿éÁÊÓËÃѺáµèÅСÒõÑ駤èҤ͹¿Ô¡?

  2. ¤ÅÔ¡á·çºª¹Ô´ OLE áÅÐÃкت×èÍá¿éÁ㹿ÔÅ´ìª×èÍá¿éÁËÑÇÍÍ¡ ãªéª×èÍá¿éÁ·ÕèäÁèä´éãªé â´Ââ¤Ã§¡Òà à¹×èͧ¨Ò¡ MkTypLib ¨Ðà¢Õ¹·Ñºá¿éÁã´ æ ·ÕèÁÕÍÂÙè ¤ÅÔ¡µ¡Å§à¾×èͻԴ¡ÅèͧâµéµÍºÊÃéÒ§¡ÒõÑ駤èÒ?

àÁ×è͵éͧ¡ÒÃà¾ÔèÁ¢éÍ¡Ó˹´UUID¨Ò¡ËÑÇ¢éÍ¡ÒÃÊÃéÒ§â´Â MkTypLib á¿éÁâ¤Ã§¡Òâͧ¤Ø³:

  1. ÃÇÁ MkTypLib ÊÃéÒ§ÊèǹËÑǢͧá¿éÁÁҵðҹ¢Í§¤Ø³»ÃСͺ´éÇÂÊèǹËÑǢͧá¿éÁ STDAFXH?

  2. ÊÃéÒ§á¿éÁãËÁè INITIIDSCPP áÅÐà¾ÔèÁŧã¹â¤Ã§¡Òâͧ¤Ø³ ã¹á¿éÁ¹Õé ÃÇÁá¿éÁ MkTypLib ÊÃéÒ§ÊèǹËÑǢͧ¤Ø³ËÅѧ¨Ò¡ÃÇÁ¶Ö§ OLE2H áÅÐ INITGUIDH:
    / / initIIDs.c: ¡Ó˹´ iid ¢Í§ÊÓËÃѺÍÔ¹à·ÍÃì࿫Ẻ¤Ùè
    / / ¹ÕéµéͧäÁèÊÒÁÒöÊÃéÒ§ ´éÇÂËÑÇ¢éÍ¡è͹¤ÍÁä¾Åì
      #ÃÇÁ lt;ole2.h >
      #ÃÇÁ <initguid.h>
      #ÃÇÁ "acdual.h"
    
  3. ¨Ò¡àÁ¹Ù Build ¤ÅÔ¡µÑ駤èÒ áÅéÇàÅ×Í¡ INITIIDSCPP ¨Ò¡ÃÒ¡ÒÃá¿éÁÊÓËÃѺáµèÅСÒõÑ駤èҤ͹¿Ô¡?

  4. ¤ÅÔ¡á·çº c ++ »ÃÐàÀ· "ËÑÇ¡è͹¤ÍÁä¾Åì" áÅÐàÅ×Í¡·Õè "äÁèãªé precompiled ËÑÇ" àôÔâÍ ¤ÅÔ¡µ¡Å§à¾×èͻԴ¡ÅèͧâµéµÍºÊÃéÒ§¡ÒõÑ駤èÒ?

Ãкت×èͤÅÒÊÇѵ¶Ø·Õè¶Ù¡µéͧã¹äźÃÒÃÕª¹Ô´

µÑǪèÇÂÊÃéÒ§¡ÒèѴÊè§ â´Âãªé Visual c ++äÁè¶Ù¡µéͧãªéª×èͤÅÒʹÓä»ãªéà¾×èÍÃкطÕè coclass ã¹á¿éÁ ODL ¢Í§à«ÔÃì¿àÇÍÃì OLE createable àÃÕ¹ ã¹¢³Ð¹Õé¨Ð·Ó§Ò¹ ãªé§Ò¹¤ÅÒʪ×èͤ§äÁèä´éª×èͤÅÒʤسµéͧ¡ÒÃãËé¼Ùéãªé¢Í§Çѵ¶Ø¢Í§¤Ø³ãªé§Ò¹ àÁ×è͵éͧ¡ÒÃÃкت×èͶ١µéͧ à»Ô´á¿éÁ ODL ¤é¹ËÒáµèÅЧº coclass áÅÐá·¹ª×èͤÅÒÊãªé§Ò¹ ´éǪ×èÍÀÒ¹͡·Õè¶Ù¡µéͧ?

ËÁÒÂà˵ØÇèÒ àÁ×èÍÁÕà»ÅÕ蹤ÓÊÑè§ coclass, s CLSIDã¹á¿éÁÊÃéÒ§â´Â MkTypLib ËÑÇ¢éͪ×è͵ÑÇá»Ã¨Ðà»ÅÕè¹µÒÁ ¤Ø³¨Ðµéͧ»ÃѺ»Ãاâ¤é´¢Í§¤Ø³ãªéª×è͵ÑÇá»ÃãËÁè?

¡ÒèѴ¡ÒâéÍ¡àÇé¹áÅÐÍÔ¹à·ÍÃìà¿«¢éͼԴ¾ÅÒ´Íѵâ¹ÁѵÔ

ÇÔ¸Õ¡ÒÃáÅпѧ¡ìªÑ¹µÑÇà¢éÒ¶Ö§¤Ø³ÊÁºÑµÔ¢Í§Çѵ¶ØÍѵâ¹ÁѵÔÍҨ⹢éÍ¡àÇé¹ ¶éÒà»ç¹àªè¹¹Ñé¹ ¤Ø³¤ÇèѴ¡ÒáѺàËÅèÒ¹Ñé¹ã¹¡ÒÃãªé§Ò¹¢Í§¤Ø³´ÙÍÑÅÍÔ¹à·ÍÃìà¿« áÅÐÊè§¢éÍÁÙÅà¡ÕèÂǡѺ¢éÍ¡àÇé¹·Õè¡ÅѺä»ÂѧµÑǤǺ¤ØÁ¼èÒ¹ÍÔ¹à·ÍÃìà¿«¡ÒèѴ¡ÒâéͼԴ¾ÅÒ´ OLE Automation, IErrorInfo ÍÔ¹à·ÍÃìà¿«¹ÕéáÊ´§¢éͼԴ¾ÅÒ´ã¹ÃÒÂÅÐàÍÕ´ ºÃÔº·¢éÍÁÙżèÒ¹ÍÔ¹à·ÍÃìà¿«·Ñé§IDispatcháÅÐ VTBL àÁ×è͵éͧÃкØÇèÒ ÁÕ¡ÒèѴ¡ÒâéͼԴ¾ÅÒ´ ¤Ø³¤ÇÃãªéÍÔ¹à·ÍÃìà¿«ÊÓËÃѺISupportErrorInfo?

áÊ´§¡Åä¡ã¹¡ÒèѴ¡ÒâéͼԴ¾ÅÒ´ Êѹ¹ÔɰҹÇèÒ ÊÃéÒ§ ClassWizard ¿Ñ§¡ìªÑ¹·Õèãªé㹡ÒùÓÁÒãªéʹѺʹع¡ÒèѴÊè§Áҵðҹâ¹¢éÍ¡àÇé¹ ¡ÒÃãªé§Ò¹¢Í§ MFC IDispatch::Invoke catches ¢éÍ¡àÇé¹àËÅèÒ¹Õéâ´Â·ÑèÇä» áÅéÇá»Å§à»ç¹ EXCEPTINFO ÁÕâ¤Ã§ÊÃéÒ§·Õè¶Ù¡Êè§¡ÅѺ¼èÒ¹ÊÒÂInvoke ÍÂèÒ§äáçµÒÁ àÁ×èÍÁÕãªéÍÔ¹à·ÍÃìà¿«ÊÓËÃѺ VTBL ¤Ø³¨ÐªÍº¨Ñºã¨¢éÍ¡àÇé¹µÑÇàͧ µÑÇÍÂèÒ§¢Í§¡Òûéͧ¡Ñ¹ÇÔ¸Õ´ÙÍÑÅÍÔ¹à·ÍÃìà¿«¢Í§¤Ø³

STDMETHODIMP CAutoClickDoc::XDualAClick::put_text(BSTR newText)
{
 nbsp METHOD_PROLOGUE (CAutoClickDoc, DualAClick)
   TRY_DUAL(IID_IDualAClick)
   {
      / / MFC á»Å§â´ÂÍѵâ¹ÁѵԨҡ Unicode BSTR ¡Òà / / Ansi CString ¶éÒ¨Óà»ç¹...
      pThis - > m_str = newText
      ¡ÅѺ NOERROR
   }
   CATCH_ALL_DUAL
}

CATCH_ALL_DUAL¨Ð´ÙáÅÊè§¡ÅѺÃËÑÊ¢éͼԴ¾ÅÒ´·Õè¶Ù¡µéͧàÁ×èÍà¡Ô´¢éÍ¡àÇé¹ CATCH_ALL_DUALá»Å§¢éÍ¡àÇé¹ MFC OLE Automation ¨Ñ´¡ÒâéͼԴ¾ÅÒ´¢Í§¢éÍÁÙÅâ´ÂãªéÍÔ¹à·ÍÃìà¿«ÊÓËÃѺICreateErrorInfo (µÑÇÍÂèÒ§ CATCH_ALL_DUAL áÁâ¤Ã·ÕèÍÂÙèã¹á¿éÁ MFCDUALH 㹡Òà ACDUALÍÂèÒ§ ¿Ñ§¡ìªÑ¹¡ÒÃàÃÕ¡à¾×èͨѴ¡ÒâéÍ¡àÇé¹ DualHandleException ã¹á¿éÁ MFCDUALCPP) CATCH_ALL_DUAL¡Ó˹´ÃËÑÊ¢éͼԴ¾ÅÒ´Êè§¡ÅѺµÒÁª¹Ô´¢Í§¢éÍ¡àÇé¹·Õèà¡Ô´¢Öé¹

àÁ×è͵éͧÃкØÇèÒ ÁÕãªéµÑǨѴ¡ÒâéͼԴ¾ÅÒ´ OLE Automation ¤Ø³¤ÇèÐãªéÍÔ¹à·ÍÃìà¿«ÊÓËÃѺISupportErrorInfo?

à¾ÔèÁÃËÑÊáá ãËé¤Ó¨Ó¡Ñ´¤ÇÒÁ¤ÅÒÍѵâ¹ÁѵÔà¾×èÍáÊ´§Ê¹ÑºÊ¹Ø¹ISupportErrorInfo?

à¾ÔèÁÃËÑÊ¡ÒÃáÁ»ÍÔ¹à·ÍÃìà¿«¢Í§¤ÅÒÊÍѵâ¹ÁѵԢͧ¤Ø³¡ÅÑéÇISupportErrorInfoãªé§Ò¹ªÑ鹢ͧ MFC QueryInterface¡Åä¡·ÕèÊͧ ¡Òà INTERFACE_PART ¤ÓÊÑ觵ç¡ÑºÃдѺªÑ鹡Ó˹´äÇéÊÓËÃѺISupportErrorInfo?

·éÒ·ÕèÊØ´ ãªé¤ÅÒÊ·Õè¡Ó˹´à¾×èÍʹѺʹعISupportErrorInfo?

(The ACDUALÍÂèÒ§»ÃСͺ´éÇ 3 áÁâ¤Ãà¾×èͪèÇÂãËé·ÓµÒÁ¢Ñ鹵͹àËÅèÒ¹ÕéÊÒÁ DECLARE_DUAL_ERRORINFO , DUAL_ERRORINFO_PART áÅÐ IMPLEMENT_DUAL_ERRORINFO ·Ñé§ËÁ´·ÕèÁÕÍÂÙèã¹ MFCDUALH.)

µÑÇÍÂèÒ§µèÍ仹Õéãªé¤ÅÒÊ·Õè¡Ó˹´à¾×èÍʹѺʹعISupportErrorInfo CAutoClickDoc¤×ͪ×èͧ͢¤ÅÒÍѵâ¹ÁѵԢͧ¤Ø³ áÅÐ IID_IDualAClick IIDÊÓËÃѺÍÔ¹à·ÍÃìà¿«·Õèà»ç¹áËÅè§ÁҢͧ¢éͼԴ¾ÅÒ´ÃÒ§ҹ¼èÒ¹Çѵ¶Ø OLE Automation ¢éͼԴ¾ÅÒ´:

STDMETHODIMP_(ULONG) CAutoClickDoc::XSupportErrorInfo::AddRef() {
 nbsp METHOD_PROLOGUE (CAutoClickDoc, SupportErrorInfo) ¡ÅѺ pThis - > ExternalAddRef() 
} STDMETHODIMP_(ULONG) CAutoClickDoc::XSupportErrorInfo::Release() { METHOD_PROLOGUE (CAutoClickDoc, SupportErrorInfo) ¡ÅѺ pThis - > ExternalRelease() 
} STDMETHODIMP CAutoClickDoc::XSupportErrorInfo::QueryInterface (REFIID iid, LPVOID * ppvObj) { METHOD_PROLOGUE (CAutoClickDoc, SupportErrorInfo) ¡ÅѺ pThis - > ExternalQueryInterface (& iid, ppvObj); 
} STDMETHODIMP CAutoClickDoc::XSupportErrorInfo::InterfaceSupportsErrorInfo (REFIID iid) { METHOD_PROLOGUE (CAutoClickDoc, SupportErrorInfo) Ê觤׹ (iid == IID_IDualAClick) S_OK: S_FALSE 
}

ËÁÒÂà˵شéҹ෤¹Ô¤µÒÁËÁÒÂàÅ¢|nbsp ËÁÒÂà˵شéҹ෤¹Ô¤µÒÁ»ÃÐàÀ·(&N)

Index