在上一篇Blog 中谈到在WTL中添加IDL用于通过向导实现IDispatch,是要付出代价的,而且代价还不小,所以最后我还是用了最简单有效的方法。
这里就把这样一个例子代码帖子下面:
下面是我的IDispatch的实现,其中的MainDlg就是WTL向导生成的非模态对话框,可以根据自己的需求去掉。
<textarea cols="50" rows="15" name="code" class="cpp">/* ------------------------------------------------------------------------- // FileName : BrowserExternal.h // Creator : linyehui // Date : 2009/12/17 21:36:36 // Brief : // // $Id: $ // -----------------------------------------------------------------------*/ #ifndef __BROWSEREXTERNAL_H__ #define __BROWSEREXTERNAL_H__ // ------------------------------------------------------------------------- class CMainDlg; class CBrowserExternal : public IDispatch { protected: ULONG m_cRef; public: CBrowserExternal(void); ~CBrowserExternal(void); STDMETHODIMP QueryInterface(REFIID, void **); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); //IDispatch STDMETHODIMP GetTypeInfoCount(UINT* pctinfo); STDMETHODIMP GetTypeInfo(/* [in] */ UINT iTInfo, /* [in] */ LCID lcid, /* [out] */ ITypeInfo** ppTInfo); STDMETHODIMP GetIDsOfNames( /* [in] */ REFIID riid, /* [size_is][in] */ LPOLESTR *rgszNames, /* [in] */ UINT cNames, /* [in] */ LCID lcid, /* [size_is][out] */ DISPID *rgDispId); STDMETHODIMP Invoke( /* [in] */ DISPID dispIdMember, /* [in] */ REFIID riid, /* [in] */ LCID lcid, /* [in] */ WORD wFlags, /* [out][in] */ DISPPARAMS *pDispParams, /* [out] */ VARIANT *pVarResult, /* [out] */ EXCEPINFO *pExcepInfo, /* [out] */ UINT *puArgErr); public: BOOL Init(CMainDlg* pMainDlg); private: CMainDlg* m_pMainDlg; }; // ------------------------------------------------------------------------- // $Log: $ #endif /* __BROWSEREXTERNAL_H__ */ </textarea>
<textarea cols="50" rows="15" name="code" class="cpp">/* ------------------------------------------------------------------------- // FileName : BrowserExternal.cpp // Creator : linyehui // Date : 2009/12/17 21:38:07 // Brief : // // $Id: $ // -----------------------------------------------------------------------*/ #include "stdafx.h" #include "BrowserExternal.h" #include "MainDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // ------------------------------------------------------------------------- // 每添加一个函数都要在这里添加,并在GetIDsOfName和Invoke中相应添加代码 const CString KKMethod_IsOurCustomBrowser = "KK_IsOurCustomBrowser"; const CString KKMethod_Close = "KK_Close"; const CString KKMethod_FullScreen = "KK_FullScreen"; const CString KKMethod_SetWindowSize = "KK_SetWindowSize"; #define DISPID_KK_IsOurCustomBrowser 1 #define DISPID_KK_Close 2 #define DISPID_KK_FullScreen 3 #define DISPID_KK_SetWindowSize 4 // ------------------------------------------------------------------------- /* * CBrowserExternal::CBrowserExternal * CBrowserExternal::~CBrowserExternal * * Parameters (Constructor): * pSite PCSite of the site we're in. * pUnkOuter LPUNKNOWN to which we delegate. */ CBrowserExternal::CBrowserExternal( void ) { m_cRef = 0; } CBrowserExternal::~CBrowserExternal( void ) { ASSERT( m_cRef == 0 ); } /* * CBrowserExternal::QueryInterface * CBrowserExternal::AddRef * CBrowserExternal::Release * * Purpose: * IUnknown members for CBrowserExternal object. */ STDMETHODIMP CBrowserExternal::QueryInterface( REFIID riid, void **ppv ) { *ppv = NULL; if ( IID_IDispatch == riid ) { *ppv = this; } if ( NULL != *ppv ) { ((LPUNKNOWN)*ppv)->AddRef(); return NOERROR; } return E_NOINTERFACE; } STDMETHODIMP_(ULONG) CBrowserExternal::AddRef(void) { return ++m_cRef; } STDMETHODIMP_(ULONG) CBrowserExternal::Release(void) { return --m_cRef; } //IDispatch STDMETHODIMP CBrowserExternal::GetTypeInfoCount(UINT* /*pctinfo*/) { return E_NOTIMPL; } STDMETHODIMP CBrowserExternal::GetTypeInfo( /* [in] */ UINT /*iTInfo*/, /* [in] */ LCID /*lcid*/, /* [out] */ ITypeInfo** /*ppTInfo*/) { return E_NOTIMPL; } STDMETHODIMP CBrowserExternal::GetIDsOfNames( /* [in] */ REFIID riid, /* [size_is][in] */ OLECHAR** rgszNames, /* [in] */ UINT cNames, /* [in] */ LCID lcid, /* [size_is][out] */ DISPID* rgDispId) { HRESULT hr; UINT i; // Assume some degree of success hr = NOERROR; for ( i=0; i < cNames; i++) { CString cszName = rgszNames[i]; if(cszName == KKMethod_IsOurCustomBrowser) { rgDispId[i] = DISPID_KK_IsOurCustomBrowser; } else if(cszName == KKMethod_Close) { rgDispId[i] = DISPID_KK_Close; } else if(cszName == KKMethod_FullScreen) { rgDispId[i] = DISPID_KK_FullScreen; } else if(cszName == KKMethod_SetWindowSize) { rgDispId[i] = DISPID_KK_SetWindowSize; } else { // One or more are unknown so set the return code accordingly hr = ResultFromScode(DISP_E_UNKNOWNNAME); rgDispId[i] = DISPID_UNKNOWN; } } return hr; } STDMETHODIMP CBrowserExternal::Invoke( /* [in] */ DISPID dispIdMember, /* [in] */ REFIID /*riid*/, /* [in] */ LCID /*lcid*/, /* [in] */ WORD wFlags, /* [out][in] */ DISPPARAMS* pDispParams, /* [out] */ VARIANT* pVarResult, /* [out] */ EXCEPINFO* /*pExcepInfo*/, /* [out] */ UINT* puArgErr) { if(dispIdMember == DISPID_KK_IsOurCustomBrowser) { if(wFlags & DISPATCH_PROPERTYGET) { if(pVarResult != NULL) { VariantInit(pVarResult); V_VT(pVarResult)=VT_BOOL; V_BOOL(pVarResult) = true; } } if ( wFlags & DISPATCH_METHOD ) { BOOL bResult = m_pMainDlg->KK_IsOurCustomBrowser(); VariantInit(pVarResult); V_VT(pVarResult)=VT_BOOL; V_BOOL(pVarResult) = bResult; } } if(dispIdMember == DISPID_KK_Close) { if(wFlags & DISPATCH_PROPERTYGET) { if(pVarResult != NULL) { VariantInit(pVarResult); V_VT(pVarResult)=VT_BOOL; V_BOOL(pVarResult) = true; } } if ( wFlags & DISPATCH_METHOD ) { m_pMainDlg->KK_Close(); } } if(dispIdMember == DISPID_KK_FullScreen) { if(wFlags & DISPATCH_PROPERTYGET) { if(pVarResult != NULL) { VariantInit(pVarResult); V_VT(pVarResult)=VT_BOOL; V_BOOL(pVarResult) = true; } } if ( wFlags & DISPATCH_METHOD ) { m_pMainDlg->KK_FullScreen(); } } if(dispIdMember == DISPID_KK_SetWindowSize) { if(wFlags & DISPATCH_PROPERTYGET) { if(pVarResult != NULL) { VariantInit(pVarResult); V_VT(pVarResult)=VT_BOOL; V_BOOL(pVarResult) = true; } } if ( wFlags & DISPATCH_METHOD ) { //arguments come in reverse order // Invoke中的参数顺序是逆序的 int nArg1 = pDispParams->rgvarg[1].intVal; int nArg2 = pDispParams->rgvarg[0].intVal; m_pMainDlg->KK_SetWindowSize(nArg1, nArg2); } } return S_OK; } ////////////////////////////////////////////////////////////////////////// // public method BOOL CBrowserExternal::Init(CMainDlg* pMainDlg) { if (NULL == pMainDlg) return FALSE; m_pMainDlg = pMainDlg; return TRUE; } // ------------------------------------------------------------------------- // $Log: $ </textarea>
完整的代码例子在下面的图片里,右键“图片另存为”后修改文件后缀名为.rar,就可以解压出代码:
--The End--