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組件

相關文章
相關標籤/搜索