先行知識:Delphi/COM/OLEAutomation/SQLServer
難度:★★☆☆☆
在前幾篇文章中我們已經討論過關於VCL和OLE的知識。在這篇文章中我們將完成一個比較有實際意義的OLEAutomation服務器程序,最後我們把他們封裝為Delphi中使用的VCL組件。
首先我們來做一個實際的程序,在它沒有變為服務器之前,這是個用來管理客戶購買記錄的程序(它自己與SQLServer連接),它可以錄入和刪除客戶的購買記錄並直觀的顯示出來,所有的數據都存放在SQLServer中。我們將它做為OLEAutomation出於這樣一種考慮,假設我們是一家大型的供貨公司,我們可能有很多系統需要使用這個客戶購買記錄程序並用它處理SQLServer中相應的數據,但我們不願意每次都重復的編寫同樣的處理代碼,我們更希望能把這個處理程序獨立出來,並向其它程序提供服務。那麼在下面的工作中我們完成了這個服務器程序,界面如下:(注意,這僅僅是一個例子,我們不評價其數據庫設計的好壞J)
我們不過多的討論這個程序的代碼(因為這和開發一般的程序沒有任何不同,你可以按照最後的地址給我來信索取這篇文章的全部代碼)。然後我們來把它變為一個服務器。選擇FileàNewàOthersàActiveXàAutomationObject。接下來Delphi為我們定義了類型庫和實現文件,我們要做的只是在類型庫中添加相應的我們要用到的服務器屬性和事件。我們簡單的給出定義這個OLEAutomation功能的接口(來自類型庫所產生的ObjectPascal代碼):
ICustFormOLE=interface(IDispatch)
['{D7AE75F9-F838-4702-A8EB-EAD0EED242DE}']
functionGet_CustName:WideString;safecall;
procedureSet_CustName(constValue:WideString);safecall;
functionGet_ProductName:WideString;safecall;
procedureSet_ProductName(constValue:WideString);safecall;
functionGet_ProductNum:Integer;safecall;
procedureSet_ProductNum(Value:Integer);safecall;
functionGet_Remark:WideString;safecall;
procedureSet_Remark(constValue:WideString);safecall;
//下面的方法和屬性都對應著原程序中相應的方法和屬性
procedureAddToData;safecall;
procedureDelData;safecall;
propertyCustName:WideStringreadGet_CustNamewriteSet_CustName;
propertyProductName:WideStringreadGet_ProductNamewriteSet_ProductName;
propertyProductNum:IntegerreadGet_ProductNumwriteSet_ProductNum;
propertyRemark:WideStringreadGet_RemarkwriteSet_Remark;
end;
ICustFormOLEDisp=dispinterface
['{D7AE75F9-F838-4702-A8EB-EAD0EED242DE}']
propertyCustName:WideStringdispid201;
propertyProductName:WideStringdispid202;
propertyProductNum:Integerdispid203;
propertyRemark:WideStringdispid204;
procedureAddToData;dispid205;
procedureDelData;dispid206;
end;
我們現在回到接口的實現文件,注意代碼中的注釋,事實上這段代碼相當的簡單:
unitCustOLEImpUnit;
{$WARNSYMBOL_PLATFORMOFF}
interface
uses
ComObj,ActiveX,CustVIEwOLE_TLB,StdVcl,Windows;
type
TCustFormOLE=class(TAutoObject,ICustFormOLE)
//注意這裡實現了我們在前面定義的ICustFormOLE接口
protected
functionGet_CustName:WideString;safecall;
functionGet_ProductName:WideString;safecall;
functionGet_ProductNum:Integer;safecall;
functionGet_Remark:WideString;safecall;
procedureAddToData;safecall;
procedureDelData;safecall;
procedureSet_CustName(constValue:WideString);safecall;
procedureSet_ProductName(constValue:WideString);safecall;
procedureSet_ProductNum(Value:Integer);safecall;
procedureSet_Remark(constValue:WideString);safecall;
end;
implementation
usesComServ,CustFormUnit;
functionTCustFormOLE.Get_CustName:WideString;
begin
result:=CustForm.CustomEdit.Text;
//可以看到,我們只是用了最初程序窗體的控件和屬性,這裡的接口實現相當於