自定義了一個消息結構(VbMsg),并在程序的主窗體內,建立一個消息廣播引擎,主要由一個消息隊列和一個定時消息廣播器所組成。消息廣播器固定隔一定時間檢查一次消息隊列,如果有消息存在,就將其發送給所有的打開的窗口,并將該消息從隊列中刪除。如此再定義一個全局的消息發送過程(SendMsg),將要發送的消息(VbMsg)送入消息隊列。這樣當需要廣播消息時,只需填充好消息結構,調用SendMsg過程即可。這里較為復雜的是消息廣播器如何將消息發送到各窗口:這需要作個硬性規定,就是每一個窗體都必須定義一個形式完全相同的消息接收函數(RecMsg),在這個函數中對接收到的消息進行處理,當然也可以什么都不做。有了這樣的規定之后,消息廣播器在進行廣播時,就可以是利用VB系統定義的全局變量Forms,遍歷所有的窗體,并調用一遍每個窗體的消息接收函數,其樣子大致如下:
PublicSubSendMsgToForms(msgasVbMsg)
DimfrmasForm
ForEachfrmInForms
frm.RecMsgmsg
Nextfrm
EndSub
通過上面的這些過程,就可以實現在獨立的程序中,對隨機事件進行異步處理。這一方法我曾經在早期開發的幾個系統中使用,效果基本還是令人滿意的。但是它有幾個較大的局限性,當開發更大一些的系統時,就顯得不能夠滿足需要。主要有以下幾點:
定時檢查消息隊列,需要利用Timer控件進行觸發。這在程序運行時,就必然要犧牲一部分效率;
消息廣播的范圍限定在一個程序模塊內,如果整個系統分成多個大的模塊,那么存在于動態連接模塊(.DLL)中的窗體,將不能直接接收到廣播消息。而要想實現進程間的消息傳遞,這一方法就更加不可能;
消息的接收者只能是窗體,而做為真正的基礎單元--“類”卻無法直接接收消息。
為了打破上面的幾點局限性,就必須尋找新的解決辦法。非常慶幸的是,VB5.0企業版的推出,給VB增添了許多強有力的特性,有幾點特性,正好可以幫助我們解決難題。先讓我介紹一下這幾個特性:
用戶自定義事件:在類模塊中,可以使用Event關鍵字來定義用戶自定義事件,使用RaiseEvent語句來產生該事件,這一機制給處理隨機事件帶來極大的方便。上面說的消息廣播引擎,就可以不再使用Timer控件做支持,而是當收到需要廣播的消息時,產生一個預定義的事件,而需要處理消息的客體對象,只需截獲該事件,就完成了消息的傳遞。
ActiveXEXE部件:利用VB,可以方便地將共享代碼封裝在ActiveX部件之中。將消息廣播引擎實現于一個ActiveX部件之中,不僅方便了在程序中使用,而且更為重要的一點是,可以實現跨進程間的消息傳遞。因為ActiveX部件有內部(DLL)外部(EXE)兩種,對于外部部件,可以對模塊內的全局數據實現共享(關于ActiveX兩種代碼部件的區別,請閱讀VB的聯機幫助文件)。
遠程自動化連接:ActiveX部件,是一種標準的客戶機/服務器結構,利用Windows平臺的COM模型,VB已能方便地將這種結構擴展到整個網絡的范圍。所以,我們的消息廣播設計,在實現了進程間的消息傳遞之后,進而實現網絡上的消息傳遞,也成為可能。
通過上面的幾點介紹,這一方式的設計思想也就比較清楚了,在具體設計時,我通過四個模塊之間的相互協作,完成了消息的發送、廣播及接收,并將這四個模塊封裝在一個ActiveXEXE部件之中。下面就是這三個類模塊的簡單介紹及源代碼:
類模塊之一:Msg.cls
在該模塊中,定義了消息數據結構VbMsg類,它是消息傳遞中的載體。這里只是一個簡單的例子,如果想實現更多的功能,如建立兩點間的數據通道,而不是單純的廣播消息,則可能需要對該結構進行一些擴充。
VERSION1.0CLASS
BEGIN
MultiUse=-1'True
END
AttributeVB_Name="VbMsg"
AttributeVB_GlobalNameSpace=False
AttributeVB_Creatable=True
AttributeVB_ PubliciDescr 只應由消息服務器(MsgServer)調用 PublicPropertyGetKey()AsString Key="ID:"&ID EndProperty
新聞熱點
疑難解答
圖片精選