⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atldispa.h

📁 remote debug and compile tools
💻 H
📖 第 1 页 / 共 2 页
字号:
#if !defined(AFX_ATLDISPA_H__20010608_7B20_BD08_5EED_0080AD509054__INCLUDED_)
#define AFX_ATLDISPA_H__20010608_7B20_BD08_5EED_0080AD509054__INCLUDED_

#pragma once

/////////////////////////////////////////////////////////////////////////////
// atldispa - Dynamic IDispatch handler
//
// Written by Bjarke Viksoe (bjarke@viksoe.dk)
// Copyright (c) 2001-2005 Bjarke Viksoe.
//
// This code may be used in compiled form in any way you desire. This
// source file may be redistributed by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name is included. 
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to you or your
// computer whatsoever. It's free, so don't hassle me about it.
//
// Beware of bugs.
//

#ifndef __cplusplus
  #error ATL requires C++ compilation (use a .cpp suffix)
#endif

#ifndef __ATLCOM_H__
  #error atldispa.h requires atlcom.h to be included first
#endif


/////////////////////////////////////////////////////////////////////////////
// Dynamic IDispatch macros

// Parameter types: by value VTs
#define VTS_EMPTY           L"\x00"
#define VTS_I2              L"\x02"      // a 'short'
#define VTS_I4              L"\x03"      // a 'long'
#define VTS_R4              L"\x04"      // a 'float'
#define VTS_R8              L"\x05"      // a 'double'
#define VTS_CY              L"\x06"      // a 'CY'
#define VTS_DATE            L"\x07"      // a 'DATE'
#define VTS_BSTR            L"\x08"      // a 'BSTR'
#define VTS_DISPATCH        L"\x09"      // an 'IDispatch*'
#define VTS_SCODE           L"\x0A"      // a 'SCODE'
#define VTS_BOOL            L"\x0B"      // a 'BOOL'
#define VTS_VARIANT         L"\x0C"      // a 'VARIANT'
#define VTS_UNKNOWN         L"\x0D"      // an 'IUnknown*'

// Parameter types: by reference VTs
#define VTS_REF_I2          L"\x4002"    // a 'short*'
#define VTS_REF_I4          L"\x4003"    // a 'long*'
#define VTS_REF_R4          L"\x4004"    // a 'float*'
#define VTS_REF_R8          L"\x4005"    // a 'double*'
#define VTS_REF_CY          L"\x4006"    // a 'CY*'
#define VTS_REF_DATE        L"\x4007"    // a 'DATE*'
#define VTS_REF_BSTR        L"\x4008"    // a 'BSTR*'
#define VTS_REF_DISPATCH    L"\x4009"    // an 'IDispatch**'
#define VTS_REF_SCODE       L"\x400A"    // a 'SCODE*'
#define VTS_REF_BOOL        L"\x400B"    // a 'VARIANT_BOOL*'
#define VTS_REF_VARIANT     L"\x400C"    // a 'VARIANT*'
#define VTS_REF_UNKNOWN     L"\x400D"    // an 'IUnknown**'


template< class T >
struct _ATL_DISPATCH_ENTRY
{
  OLECHAR *szName;
  DISPID dispid;
  UINT wFlags;
  VARTYPE vtReturn;
  UINT nArgs;
  LPCWSTR vtArgs;
  VARTYPE vtSingle;
  void (__stdcall T::*pfn)();
};

#define BEGIN_DISPATCH_MAP(theClass) \
   static const _ATL_DISPATCH_ENTRY<theClass>* _GetDispMap()\
   {\
      typedef theClass _atl_disp_classtype;\
      static const _ATL_DISPATCH_ENTRY<_atl_disp_classtype> _dispmap[] = {

#define DISP_METHOD_ID(func, dispid, vtRet, nCnt, vtArgs) \
   { OLESTR(#func), dispid, DISPATCH_METHOD, vtRet, nCnt, { vtArgs }, VT_EMPTY, (void (__stdcall _atl_disp_classtype::*)())func },

#define DISP_METHOD(func, vtRet, nCnt, vtArgs) \
   DISP_METHOD_ID(func, DISPID_UNKNOWN, vtRet, nCnt, vtArgs)

#define DISP_METHOD0_ID(func, dispid, vtRet) \
   { OLESTR(#func), dispid, DISPATCH_METHOD, vtRet, 0, { VTS_EMPTY }, VT_EMPTY, (void (__stdcall _atl_disp_classtype::*)())func },

#define DISP_METHOD0(func, vtRet) \
   DISP_METHOD0_ID(func, DISPID_UNKNOWN, vtRet)

#define DISP_METHOD1_ID(func, dispid, vtRet, vtArg) \
   { OLESTR(#func), dispid, DISPATCH_METHOD, vtRet, 1, NULL, vtArg, (void (__stdcall _atl_disp_classtype::*)())func },

#define DISP_METHOD1(func, vtRet, vtArg) \
   DISP_METHOD1_ID(func, DISPID_UNKNOWN, vtRet, vtArg)

#define DISP_PROP_ID(member, dispid, vt) \
   { OLESTR(#member), dispid, DISPATCH_PROPERTYGET, vt, 0, { VTS_EMPTY }, VT_EMPTY, (void (__stdcall _atl_disp_classtype::*)())get_##member }, \
   { OLESTR(#member), DISPID_PROPERTYPUT, DISPATCH_PROPERTYPUT, VT_EMPTY, 1, NULL, vt, (void (__stdcall _atl_disp_classtype::*)())put_##member },

#define DISP_PROP(member, vt) \
   DISP_PROP_ID(member, DISPID_UNKNOWN, vt)

#define DISP_PROPGET_ID(member, dispid, vt) \
   { OLESTR(#member), dispid, DISPATCH_PROPERTYGET, vt, 0, { VTS_EMPTY }, VT_EMPTY, (void (__stdcall _atl_disp_classtype::*)())get_##member },

#define DISP_PROPGET(member, vt) \
   DISP_PROPGET_ID(member, DISPID_UNKNOWN, vt)

#define DISP_PROPPUT_ID(member, dispid, vt) \
   { OLESTR(#member), dispid, DISPATCH_PROPERTYPUT, VT_EMPTY, 1, NULL, vt, (void (__stdcall _atl_disp_classtype::*)())put_##member },

#define DISP_PROPPUT(member, vt) \
   DISP_PROPPUT_ID(member, DISPID_UNKNOWN, vt)

#define END_DISPATCH_MAP() {0}}; return _dispmap;}


/////////////////////////////////////////////////////////////////////////////
// IDispDynImpl

template< class T, const IID* pdiid = &IID_NULL >
class ATL_NO_VTABLE IDispDynImpl : public IDispatch
{
public:
   IDispDynImpl()
   {
   }

   // These are here only to support use in non-COM objects   
   STDMETHOD(QueryInterface)(REFIID riid, LPVOID *ppvObject)
   {
      // NOTE: If compile errors occour at this location, 
      //       add/remove the "ATL::" namespace qualifiers in front 
      //       of the InlineIsEqualGUID() methods below.
      //       This is due to a problem in old MS Platform SDK releases.
      if( ATL::InlineIsEqualGUID(riid, *pdiid) || 
          InlineIsEqualUnknown(riid) ||
          ATL::InlineIsEqualGUID(riid, IID_IDispatch) )
      {
         if( ppvObject==NULL ) return E_POINTER;
         *ppvObject = this;
         AddRef();
#ifdef _ATL_DEBUG_INTERFACES
         _Module.AddThunk((IUnknown**)ppvObject, _T("IDispDynImpl"), riid);
#endif // _ATL_DEBUG_INTERFACES
         return S_OK;
      }
      else {
         return E_NOINTERFACE;
      }
   }
   virtual ULONG STDMETHODCALLTYPE AddRef()
   {
      return 1;
   }
   virtual ULONG STDMETHODCALLTYPE Release()
   {
      return 1;
   }

   STDMETHOD(GetTypeInfoCount)(UINT* pctinfo)
   {
      *pctinfo = 0; 
      return S_OK;
   }

   STDMETHOD(GetTypeInfo)(UINT /*itinfo*/, LCID /*lcid*/, ITypeInfo** /*pptinfo*/)
   {
      return E_NOTIMPL;
   }

   STDMETHOD(GetIDsOfNames)(REFIID /*riid*/, LPOLESTR* rgszNames, UINT cNames, LCID /*lcid*/, DISPID* rgdispid)
   {
      HRESULT Hr = S_OK;
      for( UINT i=0; i<cNames; i++ ) {
         const _ATL_DISPATCH_ENTRY<T>* pMap = T::_GetDispMap();
         DISPID dispid = 1;
         while( pMap->pfn!=NULL ) {
            if( ::lstrcmpiW(pMap->szName, rgszNames[i])==0 ) {
               rgdispid[i] = pMap->dispid==DISPID_UNKNOWN ? dispid : pMap->dispid;
               break;
            }
            dispid++;
            pMap++;
         }
         if( pMap->pfn==NULL ) {
            rgdispid[i] = DISPID_UNKNOWN;
            Hr = DISP_E_UNKNOWNNAME; 
         }
      }
      return Hr;
   }

   STDMETHOD(Invoke)(DISPID dispidMember, REFIID /*riid*/,
      LCID /*lcid*/, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
      EXCEPINFO* /*pexcepinfo*/, UINT* /*puArgErr*/)
   {
      if( (DISPATCH_PROPERTYPUT!=wFlags) && (pdispparams->cNamedArgs>0) ) return DISP_E_NONAMEDARGS;
      const _ATL_DISPATCH_ENTRY<T>* pMap = T::_GetDispMap();
      DISPID i = 1;
      while( pMap->pfn!=NULL ) {
         DISPID dispid = pMap->dispid==DISPID_UNKNOWN ? i : pMap->dispid;
         if( dispidMember==dispid ) {
            if( (DISPATCH_PROPERTYPUT==wFlags) && (DISPID_PROPERTYPUT==(pMap+1)->dispid) ) 
               pMap++;
            VARTYPE* pArgs = (VARTYPE*) pMap->vtArgs;
            if( pArgs == NULL ) pArgs = (VARTYPE*) &pMap->vtSingle;
            UINT nArgs = pMap->nArgs;
            if( pdispparams->cArgs != nArgs ) return DISP_E_BADPARAMCOUNT;
            VARIANTARG** ppVarArgs = nArgs ? (VARIANTARG**)_alloca(sizeof(VARIANTARG*)*nArgs) : NULL;
            VARIANTARG* pVarArgs = nArgs ? (VARIANTARG*)_alloca(sizeof(VARIANTARG)*nArgs) : NULL;
            UINT i;
            for( i=0; i<nArgs; i++ ) {
               ppVarArgs[i] = &pVarArgs[i];
               ::VariantInit(&pVarArgs[i]);
               if( FAILED(::VariantCopyInd(&pVarArgs[i], &pdispparams->rgvarg[nArgs-i-1])) ) return DISP_E_TYPEMISMATCH;
               if( FAILED(::VariantChangeType(&pVarArgs[i], &pVarArgs[i], 0, pArgs[i])) ) return DISP_E_TYPEMISMATCH;
            }
            T *pT = static_cast<T*>(this);
            CComStdCallThunk<T> thunk;
            thunk.Init(pMap->pfn, pT);
            CComVariant tmpResult;
            if( pvarResult==NULL ) pvarResult = &tmpResult;
            HRESULT Hr = ::DispCallFunc(
               &thunk,
               0,
               CC_STDCALL,
               pMap->vtReturn,
               nArgs,
               pArgs,
               nArgs ? ppVarArgs : NULL,
               pvarResult);
            for( i=0; i<nArgs; i++ ) ::VariantClear(&pVarArgs[i]);
            return Hr;
         }
         i++;
         pMap++;
      }
      return DISP_E_MEMBERNOTFOUND;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -