COM1 --- 小例子

來源:互聯網
上載者:User

標籤:com 組件編程 執行個體

測試環境: VS2008 + SP1 補丁     XP 32位系統


1、啟動VS2008,建立項目,

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/3E/D0/wKioL1PHw17htmhdAAHvKe8xWCQ531.jpg" title="1.jpg" alt="wKioL1PHw17htmhdAAHvKe8xWCQ531.jpg" />


2、再次建立項目,

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/3E/D0/wKioL1PHxDjSAzg_AAIuhgFNed0404.jpg" title="1.jpg" alt="wKioL1PHxDjSAzg_AAIuhgFNed0404.jpg" />


需要注意的就是  在 Solution 那裡 選擇 Add to Solution ,同時,上面的 Location 會自動定位到當前的解決方案裡。這個項目,直接點擊Finish 結束就行了。


3、將視圖切換到檔案視圖(View 菜單中的 Solution Explorer) ,

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/3E/D0/wKioL1PHxl7ikFiBAAG2IGH781E225.jpg" title="1.jpg" alt="wKioL1PHxl7ikFiBAAG2IGH781E225.jpg" />

可以看到這裡面有 類似 檔案夾的 東東,,它們是 Filter  就是將某一些相同類型的檔案 整理在一起的功能,我們將它們全部摺合起來。


還有一點,我們會看到這裡有兩個項目 ,帶 PS 的那個,我們暫時用不到,直接 在 它上面 右擊,選擇 Remove 即可 ,這樣,我們這個解決方案裡就只有一個 項目 了。


然後,我們 選中 QMath 這個 項目 ,然後在 Project功能表項目 中 選擇 Add Class ,為它添加一個類

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M01/3E/D1/wKioL1PHx5Lz9MH9AAHNRSaymy4105.jpg" title="1.jpg" alt="wKioL1PHx5Lz9MH9AAHNRSaymy4105.jpg" />


左邊選擇 ATL ,右邊選擇 ATL SIMPLE OBJECT 。然後點擊 ADD。

在彈出的對話方塊中,只需要要在  C++  SHORT NAME 中 寫上 QPrimerMath  即可,

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/3E/D1/wKiom1PHxyCSYRf_AAGawumowXo557.jpg" title="1.jpg" alt="wKiom1PHxyCSYRf_AAGawumowXo557.jpg" />

然後點擊下一步,這裡比較重要,我們一定要選擇  Custom

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/3E/D1/wKioL1PHyHrSDR11AAF-4Cli_rE329.jpg" title="1.jpg" alt="wKioL1PHyHrSDR11AAF-4Cli_rE329.jpg" />


然後就可以點擊 Finish了。


切換到類別檢視,我們可以看到 多了 兩個東東,,一個 是 I.... ,這個就是介面啦,一個是C...,這個就是組件類了。


650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/3E/D1/wKiom1PHx8Lzeuk9AAD0zNJR1uw627.jpg" title="1.jpg" alt="wKiom1PHx8Lzeuk9AAD0zNJR1uw627.jpg" />


然後,我們要為 介面添加 方法 ,在介面 上右擊 ,選擇  Add  -->  Add Method 彈出圖示對話方塊


650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/3E/D1/wKiom1PHyEnQU020AAFA3dF3zvI663.jpg" title="1.jpg" alt="wKiom1PHyEnQU020AAFA3dF3zvI663.jpg" />


在這裡面,我們可以 為 我們的介面添加 方法 ,這個 地方的步驟 ,我還是一步一步寫下來吧,

1、輸入 方法名 ,如 Add

2、點擊 in  ,然後 參數類型 輸入  LONG  參數名稱 輸入 nA,然後點擊Add ,這樣就添加了一個輸入參數,然後再次點擊 in ,同之前的操作一樣,添加第二個參數,nB ,在COM 中 傳回值是要用指標往外帶值的,但是我們看到 retval  這個參數屬性又是灰掉的,,腫麼辦?  先在 參數類型中 輸入  LONG* ,然後你就看到 out 和 retval 都可以用了,然後輸入 參數名,其它的都一樣操作了。


650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/3E/D2/wKioL1PHys6RMNZ3AAFml7Pp5qY487.jpg" title="1.jpg" alt="wKioL1PHys6RMNZ3AAFml7Pp5qY487.jpg" />


這樣來理解一下,這個函數 叫  Add, 有兩個輸入參數,一個通過指標向外帶的 傳回值,OK。


然後直接 點擊 Finish 就可以了。


在整個過程中,時刻要記得儲存代碼。


下面,我們就在  組件類中 實現代碼


650) this.width=650;" src="http://s3.51cto.com/wyfs02/M01/3E/D2/wKioL1PHy4LCT1oHAAFrVi1W5Mk109.jpg" title="1.jpg" alt="wKioL1PHy4LCT1oHAAFrVi1W5Mk109.jpg" />


雙擊 這個 Add 方法,然後為它 寫上 實現代碼。

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/3E/D2/wKiom1PHytizW8tLAAKSzvj7_d0716.jpg" title="1.jpg" alt="wKiom1PHytizW8tLAAKSzvj7_d0716.jpg" />


好了,然後我們 迅速的 再 做 其它 4 個 方法 ,,Sub,Mul,Div,Mod

,,,,等等,,迅速,怎麼迅速呢?當然是 手工添加啦,因為這些函數  參數都是類似的,,只是函數名 和 實現代碼不同而以。


1、為 介面  添加上 其它 4 個方法 ,如何快速呢? 這裡要告訴你幾個小技巧,快速複製一行,滑鼠只要在當前行,按下 CTRL + C 就複製了當前行,不需要選中哦。雙擊 介面 中的 Add 的聲明 ,定位到了如下 位置

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M01/3E/D3/wKioL1PHzPWAagdMAAKeshVDPFs361.jpg" title="1.jpg" alt="wKioL1PHzPWAagdMAAKeshVDPFs361.jpg" />



其實它裡面就 一行,

[helpstring("method Add")] HRESULT Add([in] LONG nA, [in] LONG nB, [out,retval] LONG* nResult);
我們只要將 游標 定位 到這一行,注意,不要選中 任何東東,,直接 CTRL + C ,然後 CTRL + V 四次。 效果如


650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/3E/D3/wKioL1PHzXOijeFgAAJoXsh5AG8235.jpg" title="1.jpg" alt="wKioL1PHzXOijeFgAAJoXsh5AG8235.jpg" />


哈哈,是不是 很方便 ,然後 就是 修改函數名,這裡也有小技巧,,就是 塊選,我先示範一下效果,

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/3E/D3/wKioL1PHzcyytYX1AABUCUwyQpg924.jpg" title="1.jpg" alt="wKioL1PHzcyytYX1AABUCUwyQpg924.jpg" />

不只是可以 塊選擇,還可以塊複製 和 粘貼 ,所以嘛,你懂的,,先改 前面的 五個,然後 複製,然後再 選中 後面的 五個,再 粘貼,那麼到底怎麼塊選擇呢,技巧就是 在選擇的時候 按住 ALT 鍵。


其實很多編輯類的軟體都提供了這一功能哦,比如 NOTEPAD++。


介面中 聲明了 這五個方法 了,,在 組件類 中 也要 進行聲明 ,並且 還要實現它們的功能。


直接開啟組件類對應的 標頭檔, 或者  直接 雙擊 組件類 的類名 也可以,在這裡面,我們可以找到 如所示的 Add函式宣告 


650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/3E/D3/wKioL1PHztyAQ_ExAABnaZgl2uc123.jpg" title="1.jpg" alt="wKioL1PHztyAQ_ExAABnaZgl2uc123.jpg" />


所以嘛,其它的我也不用說了,你都會了,不要忘記 塊操作哦。


650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/3E/D3/wKiom1PHzhjxcmhYAAEhYH0Uk6M194.jpg" title="1.jpg" alt="wKiom1PHzhjxcmhYAAEhYH0Uk6M194.jpg" />

OK,類中,我們也聲明完了,,接下來,我們就是 要到 類中 實現 操作了。其實,在這裡,還有小技巧,那就是 VS中快速鍵的 定製,我相信你,如果看到這裡了,你的VS 應該是 安裝有 VAX 外掛程式了,,。沒有的話,你可以百度一下 VS2008 VAX 外掛程式了。


然後我們  點擊  工具 菜單下   自訂 ,彈出

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/3E/D3/wKioL1PHz76SeXhWAAG12oSCl3k039.jpg" title="1.jpg" alt="wKioL1PHz76SeXhWAAG12oSCl3k039.jpg" />


點擊 左下角 的 鍵盤,


650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/3E/D4/wKiom1PHzwGilo3pAAIiSXRZyS0155.jpg" title="1.jpg" alt="wKiom1PHzwGilo3pAAIiSXRZyS0155.jpg" />


在 Show commands containing 中 輸入 VAssistX.RefactorCreateIm  ,下面的列表中 就會只剩餘一項了,然後 在下面 可以為它 指定  加速鍵 ,我指定為 了 CTRL + Q,按兩次。


好了,我相信你可以搞定它。


那麼這個功能是做什麼用的呢,說白了 就是 為我們 自動 添加 實現代碼的,,然後我們將 滑鼠 放在 組件類 中 聲明 的  Sub 方法 上, 按下 上面的  加速鍵, 會發現,CPP檔案中 自動添加了


如下的 代碼650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/3E/D4/wKioL1PH0RqTexyvAACbbOLbIXY434.jpg" title="1.jpg" alt="wKioL1PH0RqTexyvAACbbOLbIXY434.jpg" />


這個時候,如果我們 按 CTRL + TAB  鍵,則會 切換 加  標頭檔中,按一下 下方向鍵,就會定位到 Mul 這三個字母上,然後再 CTRL + Q 兩次,是不是很方便呢。


快速添加完五個函數的實現。


同時呢,我們的五個 函數的 具體實現 也 差不多,只是 運算子不一樣而以,複製行,粘貼,但是在粘貼的時候要注意,這個 複製行 在複製的時候 ,將分行符號也複製了,,而且在 粘貼的時候 是 將資料 粘貼在 滑鼠所在 當前行的 上一行。

所以,我們先 將 滑鼠 放在

*nResult = nA + nB;   這一行上


然後 複製,

STDMETHODIMP CQPrimerMath::Sub( LONG nA, LONG nB, LONG* nResult )
{
    return S_OK;    然後將滑鼠 放在 這一行上,再 粘貼

}


上面都是一些技巧,掌握了這些技巧 ,你的效率會高出很多哦。


由於 除法中  nB 是不可以 為0 的,,但是我們只是 為了示範 ,不做 特殊處理。


這樣,我們就 製作了一 個 組件類了,,是不是感覺 很棒呢。


我們編譯產生一下。然後大家去網上下載一個 OLEVIEW 的工具,,VS2008中好像沒有,但 2010中又有了。

開啟這個工具,

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/3E/D4/wKioL1PH0vySs3qNAACEyU031cg610.jpg" title="1.jpg" alt="wKioL1PH0vySs3qNAACEyU031cg610.jpg" />


然後點擊 工具列中 3個紅色箭頭的 表徵圖,然後,開啟我們產生的 DLL 檔案

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/3E/D4/wKioL1PH04Hwlg_bAAEd729UqdA572.jpg" title="1.jpg" alt="wKioL1PH04Hwlg_bAAEd729UqdA572.jpg" />


好,我們按上面的方法 ,再添加一個組件類,名字叫做 QAdvancedMath  ,注意一定要選擇 CUSTOM 。

為它添加 一個 求 階乘的 方法。

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/3E/D5/wKiom1PH03Oznk9MAADhpDMuy48535.jpg" title="1.jpg" alt="wKiom1PH03Oznk9MAADhpDMuy48535.jpg" />


很簡單,然後我們再產生 一下。


哦,我的產生出錯了。

1>LINK : fatal error LNK1168: cannot open Debug\QMath.dll for writing

這是因為我的OLEVIEW 還在使用著 這個DLL,所以 要關掉它。

然後再產生 就OK了。


再用工具查看一下

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/3E/D5/wKioL1PH1Q3wZLs8AAEG4ajN9Iw156.jpg" title="1.jpg" alt="wKioL1PH1Q3wZLs8AAEG4ajN9Iw156.jpg" />



我們發現,我們這裡有兩個 COCLASS,也叫做 組件類,下面,我們要 來 畫一下,這裡面的 繼承關係


650) this.width=650;" src="http://s3.51cto.com/wyfs02/M01/3E/D5/wKiom1PH1cHzkPPTAAEVlI1JRCw527.jpg" title="1.jpg" alt="wKiom1PH1cHzkPPTAAEVlI1JRCw527.jpg" />


好,這就是 它的 最基本的 繼承 圖表啦。。當然 ,中間的 兩個 介面 還 繼承了 其它 的 介面,這個暫時不討論它。


中 的 第三層,,是表示  組件類的,,每個組件類 都有一個 類ID,也叫 CLSID ,其形式 表示為  CLSID_類名 ,但是類名 是要 去年 最前面的 字母 C 的。

中 的 第二層,,是表示  介面的,每個介面也都有一個 介面ID,也叫 IID,其形式 表示 為

IID_I類名 ,但是類名 是要 去年 最前面的 字母 C 的。


因為組件類 是 二進位 共用的 ,所以 每個  組件類 實現的 功能 只能由 介面負責 調用,為了區分開 所有的 組件類,就使用了上面的 類ID 和 介面ID。


在OLEVIEW 裡,可以看到它們的具體定義。



好了,既然是 共用使用的,那麼我們就示範一下 在MFC 中 如何使用 它。


點擊 File -- Add -- Add New Project  選擇MFC  應用程式,

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/3E/D6/wKiom1PH15zgMXM-AAHm2w76Lzs497.jpg" title="1.jpg" alt="wKiom1PH15zgMXM-AAHm2w76Lzs497.jpg" />


下面的有一步 要對著 所示進行選擇


650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/3E/D6/wKiom1PH2BaTWp6hAAH1_wEQYOQ477.jpg" style="float:none;" title="1.jpg" alt="wKiom1PH2BaTWp6hAAH1_wEQYOQ477.jpg" />

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M01/3E/D6/wKioL1PH2TDww-3cAAGuzGgg-is009.jpg" style="float:none;" title="2.jpg" alt="wKioL1PH2TDww-3cAAGuzGgg-is009.jpg" />

這裡選擇 Active Accessibility 主要是 讓 MFC 做 COM 的自動 初始化 ,加上這句話後,在


BOOL CTestQMathApp::InitInstance()  中 會添加如下 語句。


    if (!AfxOleInit())
    {
        AfxMessageBox(IDP_OLE_INIT_FAILED);
        return FALSE;
    }


然後,我們 在對話方塊 中 添加 兩個 按鈕 

ID 分別為

IDC_BTN_PRIMER_MATH  
IDC_BTN_ADVANCED_MATH
標題分別為

Test Primer Math
Test Advanced Math

添加響應函數

void CTestQMathDlg::OnBnClickedBtnPrimerMath(){    IQPrimerMath *    pPrimerMath = NULL;    HRESULT  hr = CoCreateInstance(CLSID_QPrimerMath,NULL,CLSCTX_INPROC_SERVER,IID_IQPrimerMath,(LPVOID *)&pPrimerMath);    if (FAILED(hr))        return;    LONG n1 = 100,n2 = 25, nResult = 0;    pPrimerMath->Add(n1,n2,&nResult);    pPrimerMath->Sub(n1,n2,&nResult);    pPrimerMath->Mul(n1,n2,&nResult);    pPrimerMath->Div(n1,n2,&nResult);    pPrimerMath->Mod(n1,n2,&nResult);    pPrimerMath->Release();    CoFreeUnusedLibraries();}void CTestQMathDlg::OnBnClickedBtnAdvancedMath(){    IQAdvancedMath    * pAdvancedMath = NULL;    HRESULT  hr = CoCreateInstance(CLSID_QAdvancedMath,NULL,CLSCTX_INPROC_SERVER,IID_IQAdvancedMath,(LPVOID *)&pAdvancedMath);    if (FAILED(hr))        return;    LONG    nVal = 10 ,nResult = 0;    pAdvancedMath->Factorial(nVal,&nResult);        SetDlgItemInt(IDC_BTN_ADVANCED_MATH,nResult);    pAdvancedMath->Release();    CoFreeUnusedLibraries();}



好了,一編譯會出很多錯誤。

這是為什麼呢,因為我們沒有引入相關的定義,這些定義在哪裡呢? 我們DLL 項目中 還有一個過濾器呢,就是它們兩個啦,只要將它們  加入 我們 的 對話方塊 項目 中就 可以了。

650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/3E/D8/wKioL1PH3G-S3AnkAADR-fr-iNg701.jpg" title="1.jpg" alt="wKioL1PH3G-S3AnkAADR-fr-iNg701.jpg" />



#include "../QMath/QMath_i.h"
#include "../QMath/QMath_i.c"


好了,最後呢,我們的代碼 還是有一個小問題呢,,就留給大家去發現,,去解決啦。。。


TIPS:  就是 求 階乘 那裡,,,我們沒有 對 *nResult 賦值為 1,所以結果 一直是 0.。大家自己改改吧,,我們不是來說明這些東西的,,大家要弄清楚 重點。


好了,,就倒這裡,,,2個半小時 過去了。。。


本文出自 “千千闕歌” 部落格,謝絕轉載!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.