VS2010 简单ATL COM开发

一、打开VS2010,新建ATL COM 项目,步骤:“文件” --》“新建” --》“项目”,选择“Visual C++” --》“ATL 项目” ,填写“名称” FirstCOM --》“肯定”。 函数

二、ATL 项目向导,勾选 【支持COM+ 1.0】和【支持部件注册器】,其余默认,点击完成。 测试

三、切换到类视图,右键单击项目“FirstCOM”--》“添加”  --》“类”。 spa


四、选“ATL”  --》“ATL 简单对象” --》“添加”。 .net

五、ATL  简单对象向导,“简称”中输入类名称FirstClass,其余输入框会自动填写,最下面的“ProgID”没有自动填写,最好本身写上一个,如FirstCOM.math,不然后面没法正确调用组件,点击“完成”。若是出现提示【是否覆盖现有文件】,点击【是】便可。 指针

六、切换到类视图,选中刚才添加的接口IFirstClass,以下,而后右键单击【添加】添加方法。 code


七、添加方法向导,在"方法名"  下输入Add。增长两个输入参数:勾选【in】,选择参数类型LONG,输入参数名para1,点击“添加”。一样操做增长参数para2。而后增长一个返回参数:先选择参数类型LONG*,再勾选【retval】,输入参数名result,点击添加。点击“完成”便可,若是点击下一步,不须要填写信息,点击“完成”便可。 orm

八、切换到解决方案资源管理器,展开项目“源文件”, 双击 FirstCom.idl 打开IDL定义文件,看到以下代码,就是定义的COM方法了。 htm


九、双击打开FirstClass.cpp  编辑代码:*result = para1 + para2; 对象

  1. #include "stdafx.h"  
  2. #include "FirstClass.h"  
  3. // CFirstClass  
  4. STDMETHODIMP CFirstClass::Add(LONG para1, LONG para2, LONG* result)  
  5. {  
  6.     // TODO: 在此添加实现代码  
  7.      *result = para1 + para2;  
  8.     return S_OK;  
  9. }  

#include "stdafx.h"
#include "FirstClass.h"
// CFirstClass
STDMETHODIMP CFirstClass::Add(LONG para1, LONG para2, LONG* result)
{
	// TODO: 在此添加实现代码
	 *result = para1 + para2;
	return S_OK;
}

十、编译运行,会生成dll文件,并自动注册到系统中。

问题及解决方法 blog

问题1:我在Win64位系统中编译的,出现错误:没法打开预编译头文件:“Debug\FirstCOM.pch”:No such file or directory。

解决:右键点击你建立的项目,选择“属性”,弹出“FirstCOM 属性页”,在左侧展开"配置属性"--》展开“C/C++”--》选中“预编译头”,在右边的“预编译头”下拉菜单中选择“不使用预编译头文件”,点击“肯定”按钮退出。

缘由分析:编译器通常都是以文件为单位进行编译,若是修改了工程中的一个文件,那么将致使全部文件都要从新编译,这样的编译将耗费很长时间。为了提升编译速度,将那些不常被修改,比较稳定,文件单独包含到一个指定的头文件中, 而后生成一个预编译头文件 *.pch 。 VC++中默认的头文件为 stdAfx.h, 但光有头文件没法编译,因此还要用到StdAfx.cppStdAfx.cpp里只包含一句有效代码,这样编译时,经过编译  stdAfx.cpp就把大部分系统头文件编译进来, Debug目录下便会产生一个 存储了预编译信息的 *.pch 文件。若是 *.pch文件损坏或者不存在,就会出现“问题1”所示的没法打开预编译头文件的错。

如需深究,可参考博客:没法打开包括文件:“Stdfx.h”

问题2:解决了问题1以后,又出现:error MSB8011: 未能注册输出。请尝试启用“逐用户重定向”,或者使用提高的权限从命令提示符处注册该组件。

解决: 项目-》属性-》连接器-》逐用户重定向--》设置为 true  (该方案网上常见,但仍“未能”根本解决问题)
分析: 因为win7权限问题,因此出现问题3,须要经过使用命令提示符来帮助注册该组件。

问题3:没法启动程序:“I:\VS Project\FirstCOM\Debug\FirstCOM.dll”。

解决:程序 --》 附件 --》 命令提示符,在”命令提示符“上点击鼠标右键,选择”以管理员身份运行“命令,这个时候将打开Dos命令窗口。

接下来输入regsvr32   “I:\VS Project\FirstCOM\Debug\FirstCOM.dll”  (就是 regsvr32+.dll文件所在的彻底路径了,全路径最好用引号括起来)

按 Enter 键,就可以注册成功了。


ATL COM 组件准备好了,下面咱们来调用刚才的COM。

前面一章介绍了怎么建立ATL COM组件及注册,下面简单介绍如何调用COM组件。

一、在MFC中调用有一种很方便的方法,就是经过ClassWizard利用类型库生成包装类,不过有个前提就是com组件的接口必须是派生自IDispatch。
具体方法:
(1)VS2010新建一个MFC基于对话框程序,调出类向导,点击“添加类”下拉菜单,选择“类型库中的MFC类”(From a type libarary)。

(2)选“注册表”,而后在“可用类型库”中定位到FirstCOMLib<1.0>,接下来会出来该库中的全部接口,选择你想生成的接口包装类IFirstClass后点击“完成”,向导会自动生成相应的.h文件,这样你就能够在你的MFC工程中像使用普通类那样使用COM组件了.
(3)代码编写:

首先引入头文件   #include "CFirstClass.h"

为对话框程序添加一个“测试”按钮,添加按钮单击响应函数

  1.   

 

  1. void CFirstCOMTestDlg::OnBnClickedButton1()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.     CoInitialize(NULL);  
  5.     CFirstClass m_mymath;  
  6.     if (!m_mymath.CreateDispatch(_T("FirstCOM.math.1")))//建立COM对象:这里的字符串必定要和注册表中的ProgID一致!!!   
  7.     {  
  8.         MessageBox(_T("建立COM组件失败:请检查ProgID是否正确,组件是否已经注册"));  
  9.         return;  
  10.     }  
  11.     else  
  12.     {  
  13.         long ret = m_mymath.Add(1,2);//调用COM接口   
  14.         CString strTemp;  
  15.         strTemp.Format(_T("%d"),ret);  
  16.         MessageBox(strTemp);  
  17.     }  
  18.     CoUninitialize();  
  19. }  

void CFirstCOMTestDlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	CoInitialize(NULL);
	CFirstClass m_mymath;
	if (!m_mymath.CreateDispatch(_T("FirstCOM.math.1")))//建立COM对象:这里的字符串必定要和注册表中的ProgID一致!!! 
	{
		MessageBox(_T("建立COM组件失败:请检查ProgID是否正确,组件是否已经注册"));
		return;
	}
	else
	{
		long ret = m_mymath.Add(1,2);//调用COM接口 
		CString strTemp;
		strTemp.Format(_T("%d"),ret);
		MessageBox(strTemp);
	}
	CoUninitialize();
}


关于m_mymath.CreateDispatch(_T("FirstCOM.math.1")) 中字符串"FirstCOM.math.1",其实跟咱们上一章中定义类时ProgID有关,若是忘记,能够在FirstClass.rgs文件里找,rgs是组件注册的脚本文件,当你用 Regsvr32.exe注册组件时,组件内部即是调用了这个文件。rgs文件是以资源的形式存于DLL内的。
  1. HKCR  
  2. {  
  3.     FirstCOM.math.1 = s 'FirstClass Class'  
  4.     {  
  5.         CLSID = s '{C56D80DE-DA4C-4731-81A6-48B8D0BDB2FD}'  
  6.     }  
  7.     FirstCOM.math = s 'FirstClass Class'  
  8.     {         
  9.         CurVer = s 'FirstCOM.math.1'  
  10.     }  

HKCR
{
	FirstCOM.math.1 = s 'FirstClass Class'
	{
		CLSID = s '{C56D80DE-DA4C-4731-81A6-48B8D0BDB2FD}'
	}
	FirstCOM.math = s 'FirstClass Class'
	{		
		CurVer = s 'FirstCOM.math.1'
	}


其中 CurVer=s'FirstCOM.math.1' 中的  FirstCOM.math.1 就是咱们须要的那个字符串。

(4)编译运行,点击测试按钮,结果以下:



二、在SDK中调用最简单最经常使用的一种,用#import导入类型库,利用VC提供的智能指针包装类

VS2010建立Win32控制台应用程序,编写以下代码:

  1. #include "stdafx.h"  
  2.   
  3. #include "atlcomcli.h"  
  4. #import "FirstCOM.dll" no_namespace  
  5.   
  6. int _tmain(int argc, _TCHAR* argv[])  
  7. {  
  8.     CoInitialize(NULL);  
  9.     CLSID clsid;  
  10.     CLSIDFromProgID(OLESTR("FirstCOM.math.1"),&clsid);  
  11.     CComPtr<IFirstClass> pFirstClass;//智能指针  
  12.     pFirstClass.CoCreateInstance(clsid);  
  13.     long ret = pFirstClass->Add(1,2);  
  14.     printf("%d\n",ret);  
  15.     pFirstClass.Release();  
  16.     CoUninitialize();  
  17.   
  18.     return 0;  
  19. }  

#include "stdafx.h"

#include "atlcomcli.h"
#import "FirstCOM.dll" no_namespace

int _tmain(int argc, _TCHAR* argv[])
{
	CoInitialize(NULL);
	CLSID clsid;
	CLSIDFromProgID(OLESTR("FirstCOM.math.1"),&clsid);
	CComPtr<IFirstClass> pFirstClass;//智能指针
	pFirstClass.CoCreateInstance(clsid);
	long ret = pFirstClass->Add(1,2);
	printf("%d\n",ret);
	pFirstClass.Release();
	CoUninitialize();

	return 0;
}

其中头文件atlcomcli.h中定义了智能指针CComPtr。

运行结果:


还有一些调用COM组件的方法,参见VC调用COM组件

相关文章
相关标签/搜索