服務(wù)器應(yīng)用程序
容器應(yīng)用程序
ActiveX控件可以看成是一個(gè)極小的服務(wù)器應(yīng)用程序
OCX是ActiveX控件的一種后綴名
典型的ActiveX控件唁情,具有方法宛琅、屬性沸呐、事件這三種特性
一個(gè)文件可以包含多個(gè)ActiveX控件.
我們常用的word就是一個(gè)容器應(yīng)用程序垮耳,例如,若在word文檔中可以嵌入或鏈接一個(gè)Excel表格對(duì)象瘟檩,則這時(shí)的Excel就是服務(wù)器應(yīng)用程序。 在雙擊word文檔中嵌入或鏈接的這個(gè)Excel表格對(duì)象后澈蟆,將啟動(dòng)Excel程序來(lái)完成對(duì)這個(gè)表格的編輯工作墨辛。Excel就是擁有這個(gè)表格對(duì)象的服務(wù)器應(yīng)用程序,而word程序則是可以容納這個(gè)表格對(duì)象的容器應(yīng)用程序趴俘。另外睹簇,我們也可以在word文檔中嵌入或鏈接一個(gè)Excel文檔對(duì)象,因此對(duì)word來(lái)說(shuō)哮幢,它不僅僅只是一個(gè)容器應(yīng)用程序带膀,同時(shí)它也是一個(gè)服務(wù)器應(yīng)用程序。
MFC ActiveX ControlWizard生成3個(gè)類
CClockApp
CClockCtrl 消息映射橙垢、調(diào)度映射垛叨、事件映射
CClockPropPage
調(diào)度映射是指DISPATCH_MAP
這個(gè)是把你的成員方法映射到Invoke,使得腳本語(yǔ)言也能夠使用你的接口柜某。
事件映射是指EVENT_MAP
這個(gè)是自動(dòng)生成一個(gè)連接點(diǎn)事件的方法(該方法是給你調(diào)用嗽元,由COM客戶來(lái)實(shí)現(xiàn)),并發(fā)布該事件喂击,是COM客戶可以使用連接點(diǎn)訂閱你的事件以得到相關(guān)通知
兩個(gè)映射都可以用類向?qū)?/p>
另外剂癌,讀者可以看到在該工程中還有兩項(xiàng)內(nèi)容:_DClock和_DClockEvents,前面都有一個(gè)像平放著小勺一樣的圖標(biāo)()翰绊,該圖標(biāo)表示對(duì)應(yīng)的項(xiàng)是接口佩谷,接口是控件與外部程序進(jìn)行通信的協(xié)議旁壮。
可以把接口看作是函數(shù)的集合,外部程序通過(guò)這個(gè)接口所暴露出來(lái)的方法去訪問控件的屬性和方法谐檀。
實(shí)際上抡谐,可以把接口看作是一個(gè)抽象基類,在此接口中定義的所有函數(shù)都是純虛函數(shù)桐猬,這些函數(shù)的實(shí)現(xiàn)是在CClockCtrl類中完成的麦撵。MFC通過(guò)底層的封裝,讓CClockCtrl類繼承自接口:_DClock溃肪,所以通過(guò)該接口調(diào)用的函數(shù)實(shí)際上是調(diào)用CClockCtrl類中真正實(shí)現(xiàn)的函數(shù)免胃。
ActiveX控件中的接口與計(jì)算機(jī)機(jī)硬件的接口是類似的,例如惫撰,在計(jì)算機(jī)硬件中羔沙,主板與顯卡間的通信是通過(guò)主板上的插槽完成的,這個(gè)插槽就是主板與顯卡進(jìn)行通信的接口润绎,一旦我們制定了這個(gè)接口撬碟,就可以任意地選擇一塊主板與一塊顯卡進(jìn)行通信。因?yàn)樵摻涌谑菢?biāo)準(zhǔn)的莉撇,所以選擇任一廠商生產(chǎn)的主板呢蛤,任一廠商生產(chǎn)的顯示都是可以的,只要它們的接口遵從共同的標(biāo)準(zhǔn)棍郎。主板通過(guò)該接口所暴露出來(lái)的方法去調(diào)用顯卡的顯示功能其障,而顯卡需要實(shí)現(xiàn)該接口所暴露出來(lái)的方法。
顯卡就相當(dāng)于這里的ActiveX控件涂佃,而主板就相當(dāng)于與控件通信的外部容器励翼。如果兩個(gè)通信實(shí)體要通過(guò)接口進(jìn)行通信,那么肯定是其中的一個(gè)實(shí)體實(shí)現(xiàn)該接口所暴露出來(lái)的方法辜荠,而另一個(gè)實(shí)體通過(guò)接口調(diào)用這些方法汽抚。這里,就是ActiveX控件實(shí)現(xiàn)接口所暴露出來(lái)的方法伯病,而容器調(diào)用這些方法造烁。
這里,我們利用Build(F7)命令生成Clock控件程序午笛,然后在該工程所在目錄的Debug目錄下惭蟋,可以看到生成了一個(gè)Clock.ocx文件,這就是程序生成的ActiveX控件文件药磺。在使用時(shí)告组,只需要將這個(gè)文件傳遞給使用方,經(jīng)過(guò)注冊(cè)后就可以使用該控件了癌佩。
ActiveX控件不能獨(dú)立運(yùn)行木缝,它必須嵌入到一個(gè)容器中運(yùn)行便锨。
所有的ActiveX控件必須在注冊(cè)后才能使用
生成ActiveX控件時(shí),VC++編譯器會(huì)調(diào)用regsvr32程序去注冊(cè)clock控件我碟。將該控件的所有信息鸿秆,包括其所在路徑,都寫入注冊(cè)表中怎囚。
invalidate函數(shù),使窗口無(wú)效桥胞,這樣就可以使窗口重繪恳守。
屬性
屬性是由ActiveX控件和控件所在的客戶端展示提供的。共有四種基本屬性:
1贩虾、Ambient屬性是由容器向控件提供的催烘。為了適應(yīng)需要,控件必須使用這些屬性缎罢。常用的ambient屬性有容器的背景顏色伊群、默認(rèn)字體以及前景色等。
2策精、extended屬性是由容器實(shí)現(xiàn)的舰始,但看起來(lái)是由控件生成的。例如咽袜,容器中各種各樣控件的制表順序便屬于extended屬性丸卷。
3、stock屬性是由ActiveX控件開發(fā)工具實(shí)現(xiàn)的控件屬性询刹。Stock屬性的例子有控件的字體谜嫉、標(biāo)題文本和前景色及背景色等。
4凹联、custom屬性是由用戶實(shí)現(xiàn)的控件屬性沐兰。
事件
事件是用于向控件的容器發(fā)送通知信息的。例如當(dāng)點(diǎn)擊鼠標(biāo)或發(fā)生其他事件時(shí)蔽挠,控件用事件通知容器住闯。共有兩種基本類型的事件:
1、 stock事件是由ActiveX控件開發(fā)工具實(shí)現(xiàn)的象泵,可以像調(diào)用fireError等函數(shù)那樣調(diào)用stock事件寞秃。
2、 custom事件是由用戶實(shí)現(xiàn)的偶惠,盡管在實(shí)現(xiàn)過(guò)程中MFC和ATL類庫(kù)以及Visual C++做了大量的工作春寿。
方法
由ActiveX控件實(shí)現(xiàn)的方法類似于自動(dòng)化中所述的自動(dòng)化實(shí)現(xiàn)的方法。實(shí)際上忽孽,方法主要是使用IDispatch接口通過(guò)自動(dòng)化來(lái)實(shí)現(xiàn)的绑改。
用MFC構(gòu)件的ActiveX控件總是通過(guò)IDispatch來(lái)提供它的方法谢床,而用ATL構(gòu)建的控件為了提供組件的方法,既可以使用雙工接口厘线,也可以使用定制接口识腿。
事件前面多了一個(gè)source,這表明事件是一個(gè)源接口造壮,這表明控件將用這個(gè)源接口向容器來(lái)發(fā)送通知事件渡讼,這個(gè)接口中實(shí)現(xiàn)的代碼需要用戶在容器上編寫,而不是在控件內(nèi)部耳璧。
控件上子定義屬性設(shè)置的長(zhǎng)期有效性:
對(duì)于自定義屬性值成箫,如果在VB程序中設(shè)置好了值后,關(guān)閉工程旨枯,當(dāng)再次打開工程的時(shí)候蹬昌,發(fā)現(xiàn)原先設(shè)置好的屬性值沒有被保存下來(lái)。
在CCtrl類中的DoPropExchange方法中提供了屬性值保存的長(zhǎng)期有效性攀隔,在其中可以調(diào)用以PX打頭大方法讓用戶自定義的屬性值長(zhǎng)期有效皂贩。調(diào)用哪種PX打頭的方法取決于自定義屬性所對(duì)應(yīng)的內(nèi)部成員變量的類型,這里以PX_SHORT舉例昆汹,第一個(gè)參數(shù)是DoPropExchange方法中參數(shù)指針明刷,第二個(gè)參數(shù)是屬性的外部名稱,第三個(gè)是屬性所對(duì)應(yīng)的內(nèi)部成員變量名稱筹煮。第四個(gè)是屬性的默認(rèn)填充值遮精。
還有一個(gè)問題,對(duì)于自定義的屬性败潦,發(fā)現(xiàn)如果在屬性頁(yè)中對(duì)屬性值進(jìn)行了修改本冲,但在容器的對(duì)應(yīng)屬性框中該值沒有相應(yīng)的改變,但系統(tǒng)屬性是可以的劫扒。在屬性通知方法OnIntervalChanged內(nèi)調(diào)用BoundPropertyChanged方法即可檬洞,參數(shù)是屬性ID,可以在類視圖中雙擊屬性名稱即可看到(id(XXX)沟饥,XXX即為屬性ID)添怔。
檢測(cè)容器的環(huán)境屬性:
檢測(cè)控件是在容器的運(yùn)行模式
還是在設(shè)計(jì)模式下可調(diào)用方法:AmbientUserMode。關(guān)于ActiveX的詳細(xì)學(xué)習(xí)可以參考MSDN中COleControl頁(yè)贤旷,點(diǎn)擊頁(yè)面下方的ActiveX鏈接广料。
VC調(diào)用ActiveX控件:
方法一:直接在對(duì)話框上右鍵選擇Insert ActiveX Control
方法二:菜單project->add to project->component and controls,選擇已經(jīng)注冊(cè)的ActiveX控件幼驶。向?qū)?huì)自動(dòng)添加一個(gè)關(guān)于控件的類艾杏,在該類中有ActiveX控件定義好的屬性和方法,它Create方法可以動(dòng)態(tài)創(chuàng)建一個(gè)ActiveX控件盅藻,其操作過(guò)程很動(dòng)態(tài)創(chuàng)建button很類似购桑。至于給控件添加事件畅铭,可以在控件上右鍵選擇Event即可。