[筆記] 關於 AutoIt 實現 DDE 功能

由於諸多即時看盤軟體本身亦即為 DDE Server,可以讓支援 DDE 協定,例如 Excel 就可以成為 元大 Yeswin(支援 DDE)的 Client,可以即時擷取大盤等相關數據。 擷取 DDE 的格式為: DDEServer|Topic!Item 。 該 DDE 字串會由證券商所提供的看盤軟體相關的 Help 文件可查詢到。 例如,欲觀察 元大Yeswin 的大盤資訊—上市上漲家數, 則在 Excel 的某一欄位(Cell) 填入 YES|DQ!&TWTK2.Name

但是若每此看盤都需要打開 Excel,實在甚為不便,所擷取的數據不一定非得要透過 Excel 來處理,也有可能交給 Wealth-Lab 來分析。 所以可以利用其它亦有支援 DDE 實作的語言機制,如 VB6 是最簡單的了,來實現一個 DDE 中介的常駐程式,可以將擷取得來的數據再轉給其它的應用程式(如 Wealth-Lab)來處理; 甚至,也可以實作一個可以連結多個資料來源的 DDE Server,以確保資料的容錯性。

由於撰寫 VB6 還要準備開發環境,實在甚為不便,所以轉而尋求透過簡單但強大的自動化巨集處理的應用工具,AutoIt
AutoIt 的程式語法為 VB Script-based, 它內建支援了諸多關於如 GUI 與 字串處理等函數(Function)。 但截至目前版本(v3.2.12.1, 2008/06/12))為止, 尚未提供連結 DDE(Dynamic Data Exchange) 的函數。

但是,AutoIt 其實可以透過 VBScript 語法,直接呼叫外部 Windows 的 API 與 DLL 程式。 而其中,微軟為其 DDE 所提供的應用程式介面,稱之為 DDEML (Dynamic Data Exchange Management Library),以簡化連結 DDE 的實作。

再則,AutoIt Forum 才人備出,已有國外網友撰寫了 DDE 的函數群,其實這些函數就是一種 包裹(Wrapper) 的應用,以避免 AutoIt 的 Script 開發者,還需要涉及到實際呼叫 DDEML (包括指定路徑與DLL檔名) 的連結細節。

從上述討論串可以下載該網友所提供的 DDE 函數庫以及範例,將函數庫可以解縮至 AutoIt 的 /Include 子目錄內。但是,所提供的範例並沒有說明清楚,甚至執行還會出錯。 不過,關於 DDEML 的主體部分,則確定是完成沒有問題。

關於如何實現 DDE Client 連結 DDE Server(元大Yeswin),不得已還是必須具備 DDE 的相關知識方可,但 DDE 應該算是一個蠻早期,也比較落後的一種連結技術,可以參考的文件似乎不太多了。 最重要的文件參考來源: MSDN DDEML Overview,可以說是必要研讀的線上文件。

目前是暫時寫了一段小程式,以測試是否可以透過 AutoIt 連結 元大Yeswin 的 DDE Server。測試性的程式碼如下:


#include <DDEML.au3>
#include <DDEMLClient.au3>

Global $hConvSrv = 0

_DdeInitialize("", BitOR($APPCMD_CLIENTONLY, $CBF_SKIP_ALLNOTIFICATIONS))

ExecDDECmd()

Func ExecDDECmd()
    Local $hszService = 0
    Local $hszTopic = 0
    If 0 = $hConvSrv Then
        $hszService = _DdeCreateStringHandle("YES")
        $hszTopic = _DdeCreateStringHandle("DQ")
        $hConvSrv = _DdeConnect($hszService, $hszTopic)
    EndIf
    If 0 = $hConvSrv Then
        MsgBox(0, "DDE Client", "無法連結 DDE 伺服器")
	Else
		$sz = "&TWTK2.Price"
		$str_handle = _DdeCreateStringHandle($sz)
		$Data = _DdeClientTransaction($XTYP_REQUEST, $hConvSrv, 0, 10000, $str_handle, $CF_TEXT)
		$res = _DdeGetDataAsString($Data)
		MsgBox(0, "String Handle is: ", $res)
		_DdeDisconnect($hConvSrv)
	EndIf

    If 0 <> $hszService Then _DdeFreeStringHandle($hszService)
    If 0 <> $hszTopic Then _DdeFreeStringHandle($hszTopic)
EndFunc

連結 DDE Server 相當地簡單,但是要下字串(Item)取得相對應的數據,不知道是否是因為晚上 Yeswin 沒有提供即時數據的關係,有些 Item 可以取得數據,而有些又不行...。 還有比較重要的一個問題是,我對 DDE 在建立 conversation 後,Client 與 Server 的交易處理(transaction management)問題,我還是陌生不熟悉,這仍有待再研讀 MSDN 上的文件。

待上述問題解決後,我應該會再把更完成的原始程式碼公布出來,最起碼要展現一下我目前最想要的,可以即時顯示「漲家跌家趨勢圖」。 🙂