很近沒有更新了,閑話少說,直奔主題。
微軟做任何技術(shù)的思路:在實(shí)現(xiàn)一個(gè)標(biāo)準(zhǔn)的時(shí)候,往往預(yù)留出一個(gè)通用的擴(kuò)展機(jī)制。呃,貌似很多大公司都是如此,通過擴(kuò)展把開發(fā)者跟自己捆綁。舉例:微軟的ie可以嵌入ActiveX控件、可以用BHO擴(kuò)展;richedit中支持OLE擴(kuò)展。這種擴(kuò)展機(jī)制主要是基于其OLE框架,這也是微軟操作系統(tǒng)框架的基石。開發(fā)層面目前的趨勢是,淡化OLE強(qiáng)調(diào).NET,有一種無奈叫騎虎難下,有一種錯(cuò)誤叫脫離群眾,在開發(fā)平臺、技術(shù)百花齊放,開發(fā)資源極大豐富的今天,開發(fā)者對微軟的依賴已經(jīng)不那么強(qiáng)烈,以至于現(xiàn)在的Windows開發(fā)者有點(diǎn)小苦逼,尤其是C++開發(fā)者有一種被拋棄的感覺,扯遠(yuǎn)了。
談?wù)?/span>OLE/COM/ACTIVEX的關(guān)系。很模糊,有一些說不清,有歷史原因,也有普及程度關(guān)系。侯捷說玩模板有三境界:會用標(biāo)準(zhǔn)庫,讀懂標(biāo)準(zhǔn)庫源碼,會用模板做設(shè)計(jì)。我覺得COM相關(guān)的也是如此,使用COM組件往往是容易。我的理解:OLE是技術(shù)規(guī)范,COM是語言規(guī)范,而ACTIVEX則是用這2東東來實(shí)做的可服用組件的稱謂。對于OLE的支撐主要在MFC庫中,而ATL庫則是更純粹的OLE/COM框架。MFC跟OFFICE有一衣帶水的關(guān)系,OFFICE的應(yīng)用框架促使著MFC的發(fā)展(早期如此,但UI方面早已分道揚(yáng)鑣),OFFICE的應(yīng)用模型也就是MFC的應(yīng)用開發(fā)模型。
之所以提及MFC又OFFICE,只是想說通用的擴(kuò)展機(jī)制沒有那么多條條框框,即便是ACTIVEX框架這種東西。對于OLE實(shí)踐,也就是微軟最熱衷,其中Windows操作系統(tǒng)和OFFICE系列軟件要最典型,其它則很牽強(qiáng)。OLE技術(shù)標(biāo)準(zhǔn)接口只有極少數(shù)是必須實(shí)現(xiàn),而大部分則是可選實(shí)現(xiàn)或者部分實(shí)現(xiàn),其中richedit更是如此。OLE對服務(wù)器和客戶端都做了行為規(guī)范,如果一方(一般是服務(wù)器)自行決定如何實(shí)施,則另一方也只需對應(yīng)實(shí)現(xiàn)。
呃,我說了這么多,只是為了闡述我的險(xiǎn)惡用心,或許沒人明白。ATL框架定義了四個(gè)標(biāo)準(zhǔn)導(dǎo)出函數(shù)用于規(guī)范注冊、反注冊、加載、卸載,這些跟實(shí)際的OLE功能無關(guān),尤其是在richedit擴(kuò)展中。或許你在網(wǎng)上諸多示例中看到用ATL模板創(chuàng)建一個(gè)控件然后如何簡單的插入位圖就以為掌握了核心科技,那么我就要潑冷水了,這些東西無關(guān)大局。既然Windows能用OLE搭建框架,既然MFC可以實(shí)踐OLE,那么我們也可以用純正的C++代碼玩OLE,我的意思無非就是沒必要遵循ATL,也沒必要一定去注冊一個(gè)東西,問題的核心不是這些東西,目前我們僅僅是為了插入一個(gè)動畫。
Richedit是一個(gè)不完全的OLE實(shí)踐,前面提到能完全實(shí)踐OLE的框架不多。因?yàn)?/span>richedit實(shí)現(xiàn)了圖文混排,所以在IM領(lǐng)域很受歡迎,尤其是早期(現(xiàn)在基于chromium的擴(kuò)展或許可以改變現(xiàn)狀)。Richedit是一個(gè)容器,可以容納OLE控件進(jìn)入,典型的擴(kuò)展就是動畫控件。基于ATL框架開發(fā),你可以實(shí)現(xiàn)一個(gè)標(biāo)準(zhǔn)的控件,但當(dāng)你面對一個(gè)非標(biāo)準(zhǔn)的容器時(shí),那些條條框框顯得不是那么重要,這也是為什么能做好動畫控件不容易的原因。
根據(jù)我的調(diào)查(呃,通過實(shí)踐,通過QueryInterface觀察),我發(fā)現(xiàn)實(shí)現(xiàn)一個(gè)richedit中的動畫控件只需要實(shí)現(xiàn)二個(gè)接口:IOleObject、IViewObject2,前者為了融入到richedit環(huán)境中,后者為了渲染顯示。由于richedit默認(rèn)只喜好無窗口模式,所以針對IOleInPlaceSiteWindowless之類的,你去實(shí)現(xiàn)意義也不大,因?yàn)槿思胰萜鞑徽J(rèn)你,當(dāng)然還有IPersist系列接口,對于標(biāo)準(zhǔn)的環(huán)境有用(比如IDE),但這里并不是很需要,所以認(rèn)清核心問題能減少很多困惑。更顯然的是我的控件沒有用ATL框架,因?yàn)榇丝丶撾x了richedit環(huán)境生存的意義也不大,更有甚者我沒必要讓使其成為標(biāo)準(zhǔn)(也沒可能),僅僅是為了在一個(gè)系統(tǒng)中的richedit中更好地展示。實(shí)現(xiàn)的接口越少,引入的麻煩越少,這樣才能使精力集中在主要問題上。
綜上所述,我的控件是一個(gè)C++類,只實(shí)現(xiàn)了兩個(gè)接口:
X_INTERFACE_PART(IMRichPicture, IID_IOleObject, OleObject)
X_INTERFACE_PART(IMRichPicture, IID_IViewObject, ViewObject)
X_INTERFACE_PART(IMRichPicture, IID_IViewObject2, ViewObject)
X_END_INTERFACE_MAP()
其中大部分接口都可以無視,因?yàn)槲覀冎恍枰@個(gè)控件在richedit中能夠占位(長寬),能夠展示(效率關(guān)鍵),至于其他的可編程、在位激活、對象識別都不重要。我觀察了QQ的動畫控件,呃,比現(xiàn)在網(wǎng)上流行的要改變很多(網(wǎng)上內(nèi)容沒有與時(shí)俱進(jìn))。現(xiàn)在的`QQ的動畫控件很簡單(后面會講述如何找到這個(gè)控件),看起來只是作為一個(gè)占位工具,如何觸發(fā)動畫則是由host控制。觀其接口:
};
interface IRichPicObj : IDispatch {
[id(0x00000001), propput, helpstring("property src")]
HRESULT src([in] BSTR rhs);
[id(0x00000002), propput, helpstring("property static")]
HRESULT na([in] long rhs);
[id(0x00000003), propput, helpstring("property autoHeight")]
HRESULT autoHeight([in] long rhs);
[id(0x00000004), propput, helpstring("property autoWidth")]
HRESULT autoWidth([in] long rhs);
[id(0x00000005), propput, helpstring("property maxAutoWidth")]
HRESULT maxAutoWidth([in] int rhs);
[id(0x00000006), propput, helpstring("property onerror")]
HRESULT onerror([in] BSTR rhs);
[id(0x00000007), propput, helpstring("property objid")]
HRESULT objid([in] BSTR rhs);
};
IrichFrameObj的作用我不是很理解,居然一個(gè)接口都沒有,而后者模糊的能夠理解一些:src大概就是動畫圖片路徑,auto系列是為了動態(tài)縮放。現(xiàn)在的QQ只允許一個(gè)自定義動畫,依據(jù)老衲猜測,因?yàn)樽远x動畫往往是截圖,比較大,在一行容易引起點(diǎn)擊時(shí)視圖跳躍。再有其他的屬性是為了識別所用,無法推測具體行為。
呃,事情看起來沒有那么復(fù)雜,的確,我只實(shí)現(xiàn)了2個(gè)接口,而其中大部分也都是返回E_NOTIMPL,因?yàn)?/span>richedit確實(shí)沒有那么標(biāo)準(zhǔn),你實(shí)現(xiàn)的再標(biāo)準(zhǔn)也無濟(jì)于事。當(dāng)然richeit也在更新,win8的sdk對其改動最大,但win7的sdk也暴露了一些更早的功能,這或許是目前實(shí)現(xiàn)的最大亮點(diǎn)(技術(shù)含量,高風(fēng)險(xiǎn)高回報(bào),一般人難以置信)。
對于動畫控件闡述到此為止,或許很多人會很失望,但也僅僅如此,因?yàn)樗旧硎裁炊紱]有,尤其是在你真正明白之后,所以這里或許你會很失望,但是真正的內(nèi)容就這么多,我也不知怎么添油加醋。
最后一個(gè)建議,希望尊重所有的玩技術(shù)的:
1、中國官本位思想很嚴(yán)重,技術(shù)搞得不錯(cuò)(或許是運(yùn)氣)立馬轉(zhuǎn)管理
2、文人相輕
3、資本運(yùn)作,體制運(yùn)作,技術(shù)作用不明顯
4、吃飽肚皮,難以維系理想
大道無形,大音希聲,牛叉的技術(shù)很多都是巧工,而真正的產(chǎn)業(yè)才是大無畏的研發(fā),我們只不過在投機(jī)取巧。