通信原理
兩個同時運行的程式間通過DDE方式交換數據時是客戶/伺服器關係,一旦客戶和伺服器建立起來連線關係,則當伺服器中的數據發生變化後就會馬上通知客戶。通過DDE方式建立的數據連線通道是雙向的,即客戶不但能夠讀取伺服器中的數據,而且可以對其進行修改。DDE和剪貼簿一樣既支持標準數據格式(如文本、點陣圖等),又可以支持自定義的數據格式。但它們的數據傳輸機制卻不同,一個明顯區別是剪貼簿操作幾乎總是用作對用戶指定操作的一次性應答,如從選單中選擇貼上命令。儘管DDE也可以由用戶啟動,但它繼續發揮作用,一般不必用戶進一步干預。
交換方式
(1)冷連線(CoolLink):數據交換是一次性數據傳輸,與剪貼簿相同。當伺服器中的數據發生變化後不通知客戶,但客戶可以隨時從伺服器讀寫數據;(2)溫連線(WarmLink):當伺服器中的數據發生變化後馬上通知客戶,客戶得到通知後將數據取回;
(3)熱連線(HotLink):當伺服器中的數據發生變化後馬上通知客戶,同時將變化的數據直接送給客戶。
DDE客戶程式向DDE伺服器程式請求數據時,它必須首先知道伺服器的名稱(即DDEService名)、DDE主題名稱(Topics名),還要知道請求哪一個數據項的項目名稱(Items名)。DDEService名應該具有唯一性,否則容易產生混亂。通常DDEService就是伺服器的程式名稱,但不是絕對的,它是由程式設計人員在程式內部設定好的,並不是通過修改程式名稱就可以改變的。Topics名和Items名也是由DDEService在其內部設定好的,所有服務程式的Service名、Topics名都是註冊在系統中,當一個客戶向一個伺服器請求數據時,客戶必須向系統報告伺服器的Service名和Topics名。只有當Service名、Topics名與伺服器內部設定的名稱一致時,系統才將客戶的請求傳達給伺服器。
當服務名和Topics名相符時,伺服器馬上判斷Items名是否合法。如果請求的Item名是伺服器中的合法數據項,伺服器即建立此項連線,建立連線的數據發生數值變化後,伺服器會及時通知客戶。一個伺服器可以有多個Topics名,Items名的數量也不受限制。
DDE交換可以發生在單機或網路中不同計算機的應用程式之間。開發者還可以定義定製的DDE數據格式,進行應用程式之間特別目的IPC,它們有更緊密耦合的通信要求。大多數基於Windows的應用程式都支持DDE。但DDE有個明顯的缺點就是,通信效率低下,當通信量較大時數據刷新速度慢,在數據較少時DDE較實用。
編寫程式
早期的DDE基於訊息機制,應用程式間的訊息傳遞需程式設計師調度。由於DDE訊息通信牽涉的操作細節頗多,實現完全的DDE協定不是非常容易的事情,而且不同的開發者對協定的解釋也略有不同。為了使用方便起見,微軟提供DDE管理庫(TheDDEManagementLibrary,簡稱DDEML)。DDEML專門協調DDE通信,給DDE應用程式提供句柄字元串和數據交換的服務,消除了早期由於DDE協定不一致所引起的問題。使用DDEML開發的應用程式(客戶/伺服器)無論在運行一致性方面,還是在程式相互通信方面,性能均優於沒有使用DDEML的應用程式。而且DDEML的套用使得開發支持DDE的應用程式容易了許多,因為DDEML(這是個DLL)擔起了內務府總管的工作。使用DDEML後,實際上客戶和伺服器之間的多數會話並不是直達對方的,而是經由DDEML中轉,即用CALLBACK函式處理DDE交易(Transaction),而早期的訊息通信是直接的。
在調用其他DDEML函式前,客戶/伺服器必須調用DdeInitialize()函式,以獲取實例標識符,註冊DDECallback函式,並為Callback函式指定事務過濾。對於伺服器,在使用DdeInitialize()初始化後,調用DdeCreateStringHandle()建立Service名、Topics名和Items名等標識的句柄,再通過DdeNameService()在作業系統中註冊伺服器的名字。根據這些句柄,客戶就可以使用它提供的DDE服務了。
為了執行某個DDE任務,許多DDEML函式需要獲得字元串的訪問權。例如:一個客戶在調用DdeConnect()函式來請求同伺服器建立會話時,必須指定Service名和Topics名。可以通過調用DdeCreateStringHandle()函式來獲取特定字元串句柄。例如:
HSZhszServName=DdeCreateStringHandle(idInst,"MyServer",CP_WINANSI);
HSZhszSysTopic=DdeCreateStringHandle(idInst,SZDDESYS_TOPIC,CP_WINANSI);
一個應用程式的DDE回調函式在大多DDE事務中接收多個字元串句柄。比如:在XTYP_REQUEST事務處理期間,一個DDE伺服器接收兩個字元串句柄:一個標識Topics名字元串,另一個標識Items名字元串。可以通過調用DdeQueryString()函式來獲取相應於字元串句柄的字元串長度,並且複製字元串到應用程式定義的buffer中。例如:
DWORDidInst;
DWORDcb;
HSZhszServ;
PSTRpszServName;
cb=DdeQueryString(idInst,hszServ,(LPSTR)NULL,0,CP_WINANSI)+1;
pszServName=(PSTR)LocalAlloc(LPTR,(UINT)cb);
DdeQueryString(idInst,hszServ,pszServName,cb,CP_WINANSI);
根據微軟MSDN,現有的基於訊息DDE協定的應用程式與DDEML應用程式是相容的,也就是說,基於訊息通信的DDE應用程式可以與DDEML應用程式對話和交易。在使用DDEML時,必須在源程式檔案中包括ddeml.h頭檔案,連線user32.lib檔案,並保證ddeml.dll檔案正確的系統路徑。