動態(tài)數據交換(DDE,Dynamic data exchange)是Microsoft Windows運行環(huán)境下的一個顯著特性。通過動態(tài)數據交換協(xié)議,應用程序之間可以進行各種類型的數據交換。動態(tài)數據交換還允許應用程序建立與DDE服務器的熱鏈接從而可以實時地獲取數據。熱鏈接可以完成從一個應用程序(DDE服務器)到另一個應用程序(DDE客戶機)之間的直接數據傳遞。當位于服務器上的數據發(fā)生了變化,服務器就會發(fā)送一條信息給客戶機等待處理。 自從Microsoft Windows 2.1版發(fā)布以來,動態(tài)數據交換(DDE)就已經成為Windows的一部分,并且許多應用程序都采用了DDE技術,DDE作為一種基本機制已經應用于對象鏈接與嵌入(OLE,Object Linking and Embedding)的1.0版中。但實現完全的DDE協(xié)議并不是非常容易的事情,不同的開發(fā)者對協(xié)議規(guī)約的解釋也略有不同。 近來推出的動態(tài)數據交換管理庫(DDEML,Dynamic Data Exchange management Library)中提供了DDE函數集和應用程序級協(xié)議。使用DDEML開發(fā)的應用程序無論在運行一致性方面還是在應用程序相互通信方面性能均優(yōu)于沒有使用DDEML的應用程序。而且DDEML的應用使得開發(fā)支持DDE的應用程序容易了許多。 盡管如此,要完全地實現動態(tài)數據交換也還是有許多工作要做的。文章中給出了為完成此項工作所需要的一些約定以及一個應用程序的樣代碼,這些樣代碼可以直接拿過來用于自己的應用程序中,所有這些同時也說明了一個問題,DDE在許多應用程序中得到了普遍的支持,如Microsoft Excel軟件。 另外,文中假定所有的動態(tài)數據交換是通過DDEML接口實現的。 服務器和服務名 此處的服務器指的是一個能提供一種或多種DDE服務的應用程序。而服務名是指由服務器提供的DDE服務的名稱。一個服務器可以提供一種或多種服務。通常情況下,一個服務器只提供一種服務,并且服務器的名字與它所提供的服務的名稱(即服務名)相同,這種做法對于重新連接會話非常有利。例如服務器還沒有啟動某項服務,那么客戶端就可以根據服務名推斷出應用程序名(即服務器名)。 如果你要創(chuàng)建DDE服務器,那么最好讓服務器只支持一種服務,并且將服務器與服務的命名一致。如果你一定堅持要一個服務器支持多種服務,那么你就需要給其他的應用程序使用者提供服務名列表。 Microsoft Excel軟件中就假定服務器的名字和服務名相同。 瀏覽連接 在DDE服務器應用程序(如Microsoft Excel)的用戶文檔中有所支持的服務主題的列表。為了將客戶應用程序連接到服務器,用戶需要選擇服務名(通常與服務器名相同)、服務主題名以及所感興趣的主題項名。 DDE服務器如果支持System(系統(tǒng))主題,那么就可以對主題清單和每一個主題所支持的主題項清單進行詢問。有了這項功能,用戶就可以通過DDE客戶應用程序顯示出的對話框,瀏覽當前注冊的各項DDE服務,并且可以通過鼠標選擇相應的服務(service)、主題(topics)以及主題項(items)進而完成與服務器的連接。 并不是每一個服務器都支持System服務主題,即使是支持System服務主題的服務器,通常也不會實現全部的主題及主題項,所以需要在對話框中能夠直接鍵入服務名、主題名以及項名。 連接對話框 圖1所示為應用程序示例DDERecon的連接對話框。對話框中左側的列表框中列出了當前注冊的DDE服務。圖中含有兩項DDE服務:StockSrv(Stock Service)和WinWord(Microsoft Word for Windows)。其中StockSrv被選中,在中間的列表框中則列出了相應于StockSrv服務的可用主題。由于StockSrv服務支持 System主題,所以在Service Topics的列表框中列出了該主題。因為包含System主題信息對于絕大多數終端用戶的意義并不大,所以在對話框代碼中設計了切換代碼,可以忽略這項信息,從而使得對話框更加清晰明了。 創(chuàng)建DDE鏈接的對話框與圖1的不同之處在于圖2中忽略了System主題和 System項。中間的列表框中,僅有Prices主題,且被選中,右側的列表框則列出了相應與Prices主題的可用項。注意圖1中“Formats” 和“TopicItemList”項是服務器的System主題所支持的項,在選擇Suppression(禁止)項時被排除在外。DDERecon示例的菜單中包含了一個打開/關閉System(系統(tǒng))信息顯示的選項。 重新建立DDE鏈接 當DDE客戶應用程序重啟動后,如果想通過DDE請求從DDE服務器中獲取數據,那么就不得不重新建立與DDE服務器的會話。 下面讓我們看一下重新建立鏈接所需要的步驟。 需要鏈接嗎? 開發(fā)者可以開發(fā)一應用程序,不需要進行詢問就直接重建DDE會話的連接。這種自動連接方式在許多情況下是很方便的,但是個別情況下就顯得很不方便,如開發(fā)者正在為應用程序錄制一系列處理DDE數據的宏,他并不想在錄制過程中建立鏈接。另外,如果啟動一個應用程序只是想查看一下數據在上一次使用時的狀態(tài)而并不關心數據的當前狀態(tài)時,這種自動連接方式也是很不方便的。 請求重建特定鏈接的對話框 一個DDERecon應用程序示例中所使用的詢問用戶是否需要重建鏈接的消息框。圖3所示的消息框讓用戶決定是否需要重建某一服務的特定主題/項的鏈接。在許多應用程序中都含有不只一個熱鏈接,在這種情況下,最好能提供一個消息框,詢問用戶是否重建所有的熱鏈接,而不是逐一地進行詢問。圖4所示的是Microsoft Excel所使用的詢問是否重建所有的熱鏈接的對話框。 需要說明的是圖4所示的對話框中含有一幫助(help)按鈕,這并不多余,設想大多數終端用戶可能對“Remote link”并不理解,這時就可以選擇幫助按鈕以獲取幫助。 服務器是活動的嗎? 為了確定DDE用戶所需要的服務器是否處于活動狀態(tài),客戶應用程序可以通過調用函數 DdeConnect發(fā)出一個連接請求,這里需要給出服務名(該服務中至少包含一個所支持的主題),而并不需要主題名。如果服務器處于活動狀態(tài),連接請求成功。客戶應用程序就可以繼續(xù)發(fā)出實際主題的連接請求,從而獲得所關心的主題項的當前值,最后再發(fā)出主題項的建議請求(advise request),就可以獲取項數據的更新信息。 一個應用程序可以直接根據某一主題名而不是空主題來申請建立某一主題的鏈接,從而將服務器狀態(tài)的檢測和鏈接的重建結合在一起。當應用程序直接按照名字鏈接時,如果鏈接請求失敗,要求服務器重啟動,那么一定要注意一下返回的錯誤代碼。 DDERecon應用程序示例是按兩步進行連接的。 啟動服務器 如果服務器處于非活動狀態(tài),用戶的服務請求無法實現時,應用程序可能要詢問用戶是否想通過客戶應用程序來重新啟動服務器。DDERecon示例中使用的詢問對話框如圖5所示。 如果用戶在圖5所示的對話框中選擇了“Yes”,DDERecon將試圖運行服務器應用程序。由于所感興趣的主題名可能與服務器為響應用戶的請求而打開需要的文檔同名,所以DDERecon在服務器應用程序名的后面直接附加了一個主題名,然后再發(fā)出執(zhí)行請求。假如現在DDERecon要啟動服務器STOCKSRV.EXE中的“Prices”主題,則相應的函數調用如下: WinExec(”STOCKSRV.EXE Prices”,SW_SHOWNOACTIVATE); Microsoft Excel就是按照這種方式啟動DDE服務器應用程序的。當Microsoft Excel進行響應時,它根據命令行中的第一個參數給出的服務名和主題名打開相應的文件。命令行參數的使用并不影響動態(tài)數據交換,它只是應用程序的一種調用方式。如果使用DDERecon應用程序查看Microsoft Excel,你就會看到一主題列表框,里面包含了打開文件的完整路徑。 另外,DDERecon應用程序在通過WinExec函數啟動服務器應用程序時,使用了參數SW-SHOWNOACTIVATE,所以服務器啟動后并沒有立即處于活動狀態(tài)。在這里需要注意的是,DDERecon應用程序在調用WinExec函數前,要先調用函數SetWindowPos,通過HWND_TOPMOST參數使DDERecon應用程序窗口位于最頂層,當WinExec函數調用結束后,DDERecon應用程序將再次調用函數SetWindowPos,這一次再使用參數HWND_NOTOPMOST。在調用WinExec函數前將 DDERecon應用程序窗口位于最頂層可以防止服務器應用程序啟動后,它的窗口將DDERecon窗口覆蓋掉。有關WinExec函數的詳細信息,請參見微軟網絡開發(fā)光盤中的“Ask Dr. GUI #4”部分里面的“Z-Order Changes with WinExec”介紹。 當服務器啟動后,它要注冊DDE服務名,并且要完成第一次函數GetMessage調用前的初始化工作。WinExec函數調用結束后,DDERecon應用程序就可以立即與服務器上的注冊服務建立連接。 使用函數WinExec或LoadModule來啟動應用程序可能存在一個問題,就是應用程序有可能并不在Windows的搜索路徑下。我們知道,在安裝應用程序時,通常是將應用程序安裝在以應用程序名字命名的目錄下,比如將 Microsoft Excel程序安裝在Microsoft Excel目錄下,而且不能把創(chuàng)建的目錄置于MS-DOS路徑下,因為MS-DOS路徑名長度是有限制的。 DDERecon應用程序示例假定服務器應用程序位于Windows的搜索路徑下。在函數WinExec調用失敗的情況下,DDERecon會彈出一個消息框,如圖6所示。 對于使用者,如果出現上述的消息框,可能會感到莫名其妙,找不到問題所在。在這種情況下,你可以閱讀微軟網絡開發(fā)光盤中技術部分中的“Launching Other Windows-Based Applications”,以找到解決問題的方法。 獲取數據 服務器啟動以后,DDERecon應用程序就能夠通過調用函數DdeConnect建立與服務器有關主題的對話,然后再調用函數DdeClientTransaction,使用XTYP_REQUEST選項,獲取所需主題項的當前狀態(tài)。為了完全地實現熱鏈接,DDERecon應用程序還需要最后調用一次函數DdeClientTransaction,使用XTYP_ADVSTART選項,建立一個與項的呼叫請求。所有這些工作做完之后,服務器就會在每次項數據發(fā)生變化時發(fā)送數據到DDERecon應用程序,而客戶端則通過DDE回調函數,利用 XTYP_ADVDATA選項接收數據。 友好地面向用戶 對于開發(fā)者而言,在瀏覽DDE服務器方面以及建立與服務器的熱鏈接方面可能存在一些小的技術難題,而對于使用者而言,可能會遇到一些有關DDE模糊不清的問題。所以在將動態(tài)數據交換(DDE)并入自己的應用程序中時,一定要盡可能多的為使用者考慮。要確保使用者清楚如何操作,理解為什么要這樣操作,會有什么樣的結果,比如選定某一按鈕、在對話框中輸入文本或者響應消息框。而且對于出現的錯誤信息報告要做到清晰、明確,這一點很重要,好的錯誤信息報告讓使用者一看就知道發(fā)生了什么錯誤。 |
|