MFC----ATL IDispatch调度接口

概述

IDispatch接口:完成接口调度的接口,可以不使用头文件完成接口的函数调用

IDispatch 接口函数

  •      1> GetIDsOfNames-根据接口函数的名称获取接口函数的ID
  •      2> Invoke-根据接口函数ID,调用接口函数
  •      3>GetTypeInfo-获取指定的类型信息接口
  •      4>GetTypeInfoCount-获取指定类型信息接口的数量

IDispatch项目

   创建项目: 增加组件和接口时,要选择“dual”,增加IDispatch接口的支持

   项目变化

  •          文件的变化;接口的父接口,是IDispatch接口;当添加接口函数时,会自动添加接口函数的ID
  •          组件的实现类:父类增加了IDispathImpl
GetIDsOfNames函数

HRESULT GetIDsOfNames( 

REFIID riid, //保留值,IID_NULL

OLECHAR FAR *FAR *rgszNames,//接口函数名字符串数组 

unsigned int cNames, //数组长度

LCID lcid, //语言ID ,LOCALE_SYSTEM_DEFAULT

DISPID FAR *rgDispId //返回查询到的接口函数的ID号数组	     

);

Invoke函数

HRESULT Invoke( 

DISPID dispIdMember,//接口函数的ID 

REFIID riid, //保留参数,IID_NULL

LCID lcid, //语言ID

WORD wFlags, //接口函数的类型

DISPPARAMS FAR *pDispParams, //函数的参数

VARIANT FAR *pVarResult, //函数的返回值

EXCEPINFO FAR *pExcepInfo, //异常信息

unsigned int FAR *puArgErr//错误代码

);

 实例

一创建ATL项目ATLDIsp

1.新建ATL项目ATLDisp:下一步-->应用程序类型:动态链接库DLL;支持选项:支持COM+1.0,支持部件注册器-->完成。

2.添加MyMath类:右击--添加--类-->选择ATLCOM+1.0组件-->简称:MyMath;别的默认;COM  ProgID:ATLDisp-->下一步,完成。

3.添加接口方法Add()和ShowMsg():在类视图中,右击IMyMath接口,选择 添加---方法 -->方法名:Add,参数特性 [id(1)] HRESULT Add([in] int nAdd1, [in] int nAdd2, [out,retval] int* nResult); [id(2)] HRESULT ShowMsg(void);

4.添加Add()方法的实现:在MyMath.cpp中添加:

STDMETHODIMP CMyMath::Add(int nAdd1, int nAdd2, int* nResult)

{ 

	*nResult=nAdd1+nAdd2;

	return S_OK;

}

STDMETHODIMP CMyMath::ShowMsg(void)

{ 

	MessageBox(NULL,L"Hello Dispatch!!!",L"ATLDisp",MB_OK);

	return S_OK;

}

二创建MFCDialog的UseATLDisp项目

1.在用一个解决方案中创建MFC dialog UseATLDisp项目

2.在UseATLDisp.cpp中:

BOOL CUseATLDispApp::InitInstance()

{

	CoInitialize(0); // 现在初始化COM

    ...



	return FALSE;

}

int CUseATLDispApp::ExitInstance()

{

	CoUninitialize();// 卸载COM

	return CWinApp::ExitInstance();

}

3.按钮代码
3.按钮代码3.按钮代码

IDispatch* CUseATLDispDlg::GetDispatch()

{

	CLSID clsid={0};

	CLSIDFromProgID(L"ATLDisp",&clsid);//根据ProgID获取classID

	IDispatch* piDispatch=NULL;

	CoCreateInstance(clsid,NULL,CLSCTX_SERVER,IID_IDispatch,(LPVOID*)&piDispatch);//创建组件并返回IDispatch接口

	if (piDispatch==NULL)

	{

		AfxMessageBox(L"创建IDispatch接口失败");

	}

	return piDispatch;

}

//根据接口函数的名称获取接口函数的ID

void CUseATLDispDlg::OnBnClickedButtonGetidsofnames()

{ 

	IDispatch* piDispatch=GetDispatch();

	WCHAR* pszName=L"ShowMsg";//Add

	DISPID nID={0};

	piDispatch->GetIDsOfNames(IID_NULL,&pszName,1,LOCALE_SYSTEM_DEFAULT,&nID);

	CString strID;

	strID.Format(L"nID=%d",nID);

	MessageBox(strID);//Add 1; ShowMsg 2

}

//不带参数

void CUseATLDispDlg::OnBnClickedButtonNoparam()

{ 

	IDispatch* piDispatch=GetDispatch();

	WCHAR* pszName=L"ShowMsg";

	DISPID nID={0};

	piDispatch->GetIDsOfNames(IID_NULL,&pszName,1,LOCALE_SYSTEM_DEFAULT,&nID);

	

	//使用Invoke调用函数,参数和返回值

	DISPPARAMS params={0};

	VARIANT varResult={0};

	piDispatch->Invoke(nID,IID_NULL,LOCALE_SYSTEM_DEFAULT,DISPATCH_METHOD,¶ms,&varResult,NULL,NULL);

}

//带参数

void CUseATLDispDlg::OnBnClickedButtonparams()

{ 

	IDispatch* piDispatch=GetDispatch();

	WCHAR* pszName=L"Add";

	DISPID nID={0};

	piDispatch->GetIDsOfNames(IID_NULL,&pszName,1,LOCALE_SYSTEM_DEFAULT,&nID);

	//使用Invoke调用函数,构造参数和返回值

	VARIANT varResult={0};

	DISPPARAMS params={0};

	VARIANT varParam[3]={0};

	params.cArgs=3;

	params.rgvarg=varParam;

	//参数的顺序从右向左

	//第一个参数

	long nValue=0;

	varParam[0].vt=VT_I4|VT_BYREF;

	varParam[0].plVal=&nValue;

	//第二个参数

	varParam[1].vt=VT_I4;

	varParam[1].lVal=100;

	//第三个参数

	varParam[2].vt=VT_I4;

	varParam[2].lVal=100;

	//调用函数

	piDispatch->Invoke(nID,IID_NULL,LOCALE_SYSTEM_DEFAULT,DISPATCH_METHOD,¶ms,&varResult,NULL,NULL);

	CString strValue;

	strValue.Format(L"nResult:%d",nValue);

	MessageBox(strValue);//输出结果

}

4.界面MFC----ATL IDispatch调度接口

你可能感兴趣的:(Dispatch)