Delphi面向對象學習隨筆七:COM

作者:巴哈姆特
http://www.cnpack.org
(轉載請注明出處并保持完整)

上一篇,我們介紹了接口。如果沒有接觸過COM對象的話,你會覺得接口真的很麻煩,也許會有:“還不如直接定義一個類更方便”的想法。
????的確,沒有經過COM封裝的接口確實比較麻煩。在我看來,沒有經過COM封裝的接口似乎沒有存在的意義。那么,什么是COM對象呢?它有什么優點呢?接下來開始對COM對象進行一個簡單的介紹:

????COM是個二進制規范,它與實現的語言無關。這樣,即使COM對象由不同的編程語言創建,運行在不同的進程空間和不同的操作系統平臺,這些對象也能相互通信。COM既是規范,也是實現,它以COM庫的形式提供了訪問COM對象核心功能的標準接口以及一組API函數,這些API函數用于創建和管理COM對象。COM本質上仍然是客戶服務器模式。客戶(通常是應用程序)請求創建COM對象并通過COM對象的接口操縱COM對象。服務器根據客戶的請求創建并管理COM對象。當然,客戶和服務器這兩種角色并不是絕對的。

????記得我在剛剛接觸COM對象的時候,我師傅曾經給我說過:“COM不是Dll,雖然它可能會以后綴名為dll文件呈現在你面前,但是它絕對不是我們傳統意義上所說的dll(動態鏈接庫)”。
????其實在我看來,進程內的COM對象應該是一個以dll為載體而提供一些特殊服務的特殊的動態鏈接庫。當然,也有進程外的COM。

????現在,我們演示怎么在Delphi中利用向導建立一個簡單的COM模型。
????首先:打開Borland Delphi 7.1(不好意思,我一般都是用這個版本。什么?為什么是7.1?就是7.0加個Update1補丁包嘛-_-||)。
????然后:把Delphi默認為我們創建的Application關掉,并在菜單中選擇File->New->Other,之后在彈出的窗口中找到ActiveX頁,雙擊ActiveX Library圖標。
????雙擊圖標后,我們可以看到Delphi已經幫我們建立了一個ActiveX庫,代碼如下:

library?Project1;
uses
??ComServ;
exports
??DllGetClassObject,??? // 返回類工廠的接口
??DllCanUnloadNow,????? // 是否可以釋放該組件
??DllRegisterServer,??? // 注冊函數
??DllUnregisterServer;? // 反注冊函數
{$R *.RES}
begin
end.

我們會看到,在工程中,Delphi已經幫我們定義好了四個輸出函數(關于這幾個函數更詳細的說明,可以查閱更多的資料),我們先不管它們。
????接下來,我們再使用菜單File->New->Other并在ActiveX頁中創建Com Object,這時,我們可以看到一個對話框:其中ClassName是我們的對象名、Instancing是對象創建模式、Threading Module為線程模式。我們使用NewComServer作為對象名,其他默認。OK后可以看到一個標題為“Project11.tlb”的窗口,這個我們可以在這個窗口中為接口添加新的方法,例如我們添加一個GetMessage方法。然后我們打開Unit1.pas可以看到如下代碼:

unit?Unit1;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
??Windows, ActiveX, Classes, ComObj, Project1_TLB, StdVcl;
????// Project1_TLB 接口所在單元
type
??TNewComServer = class(TTypedComObject, INewComServer)
????// 實現接口的類
??protected
????function?GetMessage: HResult; stdcall;
??????// 我們剛剛添加的方法
????{Declare INewComServer methods here}
??end;
implementation
uses?ComServ;
function?TNewComServer.GetMessage: HResult;
begin
??MessageBox(0, \'測試\', \'提示\', $40);
??Result:= GetLastError; // 我添加的代碼
end;
initialization
??TTypedComObjectFactory.Create(ComServer, TNewComServer, Class_NewComServer, ciMultiInstance, tmApartment);
????// 類工廠
end.

?

?

之后,我們編譯這個工程(CTRL+F9)將會生成一個Project1.dll文件。保存并關閉這個工程。
??? 接著,我們編寫一段代碼來測試這個COM工程:創建一個普通的應用程序工程,并引用Project1_tlb單元:

var?// 注意,在測試代碼中也需要引用project1_tlb單元,由于我們的接口聲明在該單元內
??NewComObject: INewComObject; // 聲明接口
begin
??NewComObject:= CreateComObject(CLASS_NewComObject) as?INewComObject; // 創建COM對象,
????//CLASS_NewComObject 的定義可以在Project1_tlb.pas里找到
??if?NewComObject <> nil?then
????begin
??????NewComObject.GetMessageInfo; // 調用接口中的方法
??????NewComObject:= nil; // 釋放接口
????end
??else
????ShowMessage(\'對象創建不成功\');
end;

?

注意我們在運行這個EXE之前,需要先把我們之前的COM工程注冊給系統:開始->運行->regsvr32.exe \"...Project1.dll\"。看到注冊成功的提示信息后,我們現在可以運行我們剛剛編寫的那個測試程序來測試我們的COM對象了,看看執行測試代碼后,是否彈出了一個標題為“提示”,內容為“測試”的對話框呢?

??? 我們可以看到,在COM組件創建好以后,在EXE調用的時候是相當簡單的,而且,當我們某個方法的實現細節發生改動,只要方法聲明不變,那么在軟件升級的時候,我們可以只升級我們需要升級的COM組件,而不需要改動其它的地方。這樣可以有效的減輕維護的工作量。

??? 當然,這個演示只是一個進程內的COM,至于更詳細的說明,可以去參閱更多的資料。

??? 友情提示:ActiveX是Windows下實現COM的一個組件規范。請不要把ActiveX和COM之間劃上等號!

轉載于:https://www.cnblogs.com/songhs/p/5687178.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/271324.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/271324.shtml
英文地址,請注明出處:http://en.pswp.cn/news/271324.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

lambda

例子&#xff1a;

mysql查詢語句詳解_基于mysql查詢語句的使用詳解

1> 查詢數據表除了前三條以外的數據。起初我想到的是這條語句SELECT * FROM admin WHERE userid NOT IN (SELECT userid FROM admin ORDER BY userid LIMIT 3) ORDER BY userid DESC但是運行的時候會報 This version of MySQL doesnt yet support LIMIT & IN/ALL/ANY/SO…

數據庫技術基礎:數據庫與數據庫管理系統概念介紹

一、數據庫系統基本概念知識1、 數據&#xff08;Data&#xff09;用來描述事物的符號記錄&#xff0c;它具有多種表現形式比如文字、圖形、圖像、視頻等。信息&#xff1a;是現實事物的存在方式或狀態的反映。信息的特性有可感知、可存儲、可加工、可傳遞、可再生等。2、 數據…

unity3d collider自動調整大小_Maya模型在Unity3d中的快速烘焙【2020】

本文小姐姐將以一個Maya的室內小客廳場景為例&#xff0c;和童鞋們一起討論Unity3d快速烘焙Maya室內模型光照的方法&#xff0c;一方面是對前面知識的綜合應用&#xff0c;另一方面滿足一下做室內設計童鞋的學習需求。話不多說&#xff0c;開工&#xff01;這個例子的Maya場景模…

angualarjsdemo

AngularJs學習筆記--Forms 原版地址&#xff1a;http://code.angularjs.org/1.0.2/docs/guide/forms 控件&#xff08;input、select、textarea&#xff09;是用戶輸入數據的一種方式。Form&#xff08;表單&#xff09;是這些控件的集合&#xff0c;目的是將相關的控件進行分組…

Java中Comparator比較器的使用以及使用lamba簡化代碼

代碼例子&#xff1a; /*** 測試Comparator*/Testpublic void test17() {//原始方法Comparator<Integer> comparator new Comparator<Integer>() {Overridepublic int compare(Integer o1, Integer o2) {return Integer.compare(o1, o2);}};int compare1 compara…

php字符串轉換mysql_在PHP中將字符串轉換為MySQL時間戳格式

我使用從androidjava應用程序發送的字符串在php中編寫查詢.查詢是這樣的&#xff1a;$insertSQL sprintf("INSERT INTO app_DuckTag (taste) VALUES (%s) WHERE species%s AND timestamp%s",GetSQLValueString($_POST[taste], "text"),GetSQLValueString(…

數據庫技術基礎:數據庫管理系統的功能介紹筆記

1、DBMS功能介紹1.1 數據定義數據庫定義語言&#xff08;DDL&#xff09;&#xff1a;可以對數據庫結構描述&#xff0c;包括外模式、模式、內模式的定義&#xff1b;數據庫完整性定義&#xff1b;安全保密定義比如口令、級別和存取權限。這些定義存儲在數據字典中是DBMS運行的…

charles亂碼_基于iOS的Charles抓包實踐

奇技指南在應用開發過程中&#xff0c;通過抓包調試服務端接口的場景時常出現。Charles和Wireshark是開發過程中最常用的兩款軟件。那么今天&#xff0c;讓我們以iOS為例&#xff0c;聊一聊Charles抓包。本文來自360奇舞團QiShare團隊投稿。在日常開發中&#xff0c;我們無法看…

分珠(dfs+并查集)

1140 分珠 時間限制:500MS 內存限制:65536K提交次數:24 通過次數:18 題型: 編程題 語言: G;GCC Description 如下圖所示&#xff0c;有若干珠子&#xff0c;每顆珠子重量不同&#xff0c;珠子之間有一些細線將它們連在一起。現要求切斷一些細線&#xff0c;將它們分成兩部分…

那些程序員爆笑段子,扎心了…

1、特殊“2020是屬于程序員的一年。”“怎么說&#xff1f;”“2020-1024996。”2、真相“你們程序員是不是沒見過下班時候的太陽&#xff1f;”“也不是啦&#xff0c;夏天的時候還是能看到的。”“哦哦&#xff0c;夏天黑得比較晚。”“不是&#xff0c;是天亮得比較早。”3、…

lambda中sorted排序

準備工作&#xff0c;新建一個User類 使用stream排序操作&#xff08;默認ASC排序) stream倒序排序操作 sorted(Comparator.reverseOrder()) 代碼例子&#xff1a; /*** lambda* sorted排序*/Testpublic void test19() {List<Integer> list new ArrayList<>();…

python中的括號不是西文嗎_二級Python---python語言的基本語法元素(Day1)

一、基本輸入輸出函數Python中有三個重要的基本輸入、輸出函數&#xff0c;用于輸入、轉換和輸出&#xff0c;分別是input()、eval()、print()。1.print()作用&#xff1a;輸出運算結果&#xff1b;根據輸出內容的不同&#xff0c;有三種用法。①、僅用于輸出字符串&#xff0c…

chart.js 餅圖顯示百分比_實戰PyQt5: 135-數據可視化之QChart繪制餅圖

餅圖是數據可視圖表的基本類型&#xff0c;在QChart中&#xff0c;QPieSeries, QPieSlice處理餅圖的繪制。QPieSeriesQPieSeries類以餅圖形式顯示數據。餅圖系列由定義為QPieSlice對象的切片組成。切片可以具有任何值&#xff0c;因為QPieSeries對象計算切片的百分比與系列中所…

lambda中使用filter過濾

單一條件過濾 /*** 測試filter*/Testpublic void testFilter() {List<User> user new ArrayList<>();user.add(new User(1L, 18, "小明"));user.add(new User(2L, 20, "小王"));user.add(new User(3L, 28, "小剛"));user.add(new U…

Silverlight 打印

摘自&#xff1a;http://www.cnblogs.com/jiajiayuan/archive/2012/04/13/2444246.html Silverlight中的打印只有一個類&#xff0c;那就是PrintDocment這個對象來實現。下面我用兩種方法來實現Silverlight的打印&#xff1a;第一種&#xff1a; private void btnPrint_Click(o…

數據庫系統的體系結構知識筆記

1、集中式數據庫系統分時系統環境下的集中式數據庫系統結構誕生于20世紀60年代中期。當時的硬件和操作系統決定了分時系統環境下的集中式數據庫系統構成早期的數據庫技術的首選結構。數據和數據管理都是集中的&#xff0c;數據庫系統的所有系統&#xff0c;從形式的用戶到DBMS核…

mysql2014授權設置_mysql權限管理(2014-09-15)

本文比較碎片化&#xff0c;不過以問答的形式比較容易理解。如何查看mysql的當前登錄的用戶&#xff1f;select user();mysql -hlocalhost -uroot 與root192.168.11.100 區別&#xff1f;mysql -hlocalhost -uroot只能在本地進行登錄&#xff0c;而root192.168.11.100不能在本…

python網站后臺_Python 網站后臺掃描腳本

Python 網站后臺掃描腳本1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #!/usr/bin/python #codingutf-8 import sys import urllib import time url "http://123.207.123.228/" txt open(r"C:\Users\ww\Desk…

數據庫系統的三級模式結構知識筆記

1、數據抽象的三個層次數據庫系統利用三個層次劃分來抽象來對用戶屏蔽系統的復雜性、簡化用戶與系統的交互。1.1 物理層物理層屬于最低級層次的抽象&#xff0c;描述數據在存儲器上如何進行存儲的。物理層會詳細描述復雜的底層結構。1.2 邏輯層邏輯層屬于中間層&#xff0c;用來…