??? 摘? 要: 討論Plug-in的基本原理和開(kāi)發(fā)方法,實(shí)現(xiàn)了一個(gè)H.263解碼器的插件,并研究了如何把應(yīng)用程序通過(guò)Plug-in技術(shù)嵌入瀏覽器中,。
關(guān)鍵詞: 瀏覽器? Netscape/Mozilla? Plug-in? 插件? MIME
?
Plug-in是擴(kuò)展瀏覽器功能的一項(xiàng)重要技術(shù),。通過(guò)Plug-in技術(shù),各種應(yīng)用程序和集成軟件能夠以插件模型直接嵌入到網(wǎng)頁(yè)中,提供靈活的Web應(yīng)用。但是對(duì)于一些大型的獨(dú)立應(yīng)用程序很難將其改造成插件模型,。本文主要介紹如何利用Plug-in技術(shù)把一個(gè)大型或單獨(dú)運(yùn)行的應(yīng)用程序嵌入到瀏覽器中,。
1? Plug-in的開(kāi)發(fā)結(jié)構(gòu)
1.1 Plug-in的基本原理
Plug-in是Netscape公司提出的一種瀏覽器插件技術(shù)。Plug-in插件的生存周期完全由網(wǎng)頁(yè)控制,。具體控制過(guò)程如下,。
(1)當(dāng)瀏覽器讀取HTML網(wǎng)頁(yè)時(shí),若遇到MIME類(lèi)型的標(biāo)記時(shí),它首先搜索是否有注冊(cè)該類(lèi)型的Plug-in插件。
(2)如果有,將該P(yáng)lug-in插件的代碼載入內(nèi)存。
(3)瀏覽器初始化Plug-in的環(huán)境,。
(4)創(chuàng)建該P(yáng)lug-in插件的實(shí)例,用于處理和顯示網(wǎng)頁(yè)中指定的數(shù)據(jù)流,。
(5)當(dāng)該網(wǎng)頁(yè)關(guān)閉或轉(zhuǎn)到后臺(tái)時(shí),瀏覽器銷(xiāo)毀該P(yáng)lug-in插件的實(shí)例。
(6)瀏覽器關(guān)閉前,退出Plug-in的環(huán)境,。
由如上過(guò)程可以看出,Plug-in在運(yùn)行時(shí)完全作為瀏覽器的一部分,。但是,由于Plug-in的編寫(xiě)一般由第三方創(chuàng)建,所以Plug-in插件的開(kāi)發(fā)必須遵循Netscape公司提出的標(biāo)準(zhǔn)規(guī)范。Plug-in技術(shù)的應(yīng)用非常廣泛,一般瀏覽器中的多媒體顯示都是通過(guò)插件的方式由第三方提供的,如Flash等,。
1.2 Plug-in的基本結(jié)構(gòu)
Plug-in雖然是一個(gè)獨(dú)立的模塊,但它是由Mozilla瀏覽器來(lái)調(diào)用的,。本質(zhì)上說(shuō),Plug-in接管了一個(gè)指定大小的顯示窗口,窗口的繪制和內(nèi)容顯示則完全由Plug-in插件來(lái)控制。所以開(kāi)發(fā)者可以將所提供的任何功能和應(yīng)用放置在該窗口中,。
Netscape/Mozilla制訂了瀏覽器和Plug-in的標(biāo)準(zhǔn)通信過(guò)程,但是整個(gè)運(yùn)行過(guò)程的核心是瀏覽器和Plug-in插件互操作過(guò)程,如圖1所示,。
?
圖中以NPP開(kāi)頭的函數(shù)是在Plug-in中實(shí)現(xiàn)的由瀏覽器調(diào)用的接口,而以NPN開(kāi)頭的函數(shù)是在瀏覽器中實(shí)現(xiàn)的由Plug-in調(diào)用的接口。這二類(lèi)標(biāo)準(zhǔn)函數(shù)保證了瀏覽器和Plug-in能夠進(jìn)行數(shù)據(jù)交換和操作,。這些操作主要分為以下幾類(lèi),。
(1)窗口的內(nèi)容繪制、顯示和事件處理,。其中最主要的是函數(shù)NPP_SetWindow,它使瀏覽器指定了Plug-in插件所操縱的窗口顯示區(qū)域。
(2)數(shù)據(jù)流的處理,用于瀏覽器和Plug-in之間的數(shù)據(jù)及文件內(nèi)容的雙向傳遞,主要通過(guò)流的方式傳遞數(shù)據(jù),。
(3)URL的處理,用于控制瀏覽器中超鏈的檢索,、顯示和跳轉(zhuǎn)。
(4)內(nèi)存操作和其他相關(guān)信息,。
這些接口適用于Netscape4.0和最新的Mozilla瀏覽器版本,。由于Plug-in程序必須以動(dòng)態(tài)庫(kù)的形式由瀏覽器調(diào)用,因此針對(duì)不同的操作系統(tǒng)其實(shí)現(xiàn)方式也不同,但是其API的設(shè)計(jì)非常靈活。
2?完整Plug-in程序的開(kāi)發(fā)
根據(jù)Plug-in程序的基本原理和結(jié)構(gòu),可以針對(duì)特定的操作系統(tǒng)(Windows或Linux)開(kāi)發(fā)相應(yīng)的Plug-in程序,。通常Plug-in插件的顯示是通過(guò)HTML網(wǎng)頁(yè)中的Embed或Object的標(biāo)簽進(jìn)行設(shè)置的,。在瀏覽器對(duì)網(wǎng)頁(yè)進(jìn)行顯示時(shí),如遇到Embed或Object標(biāo)簽,瀏覽器會(huì)根據(jù)指定的大小創(chuàng)建一個(gè)窗口句柄,并通過(guò)調(diào)用函數(shù)NPP_SetWindow把該窗口句柄傳遞給Plug-in插件。至于窗口內(nèi)容的顯示和操作完全由Plug-in插件來(lái)控制和處理,而Plug-in所需要的數(shù)據(jù)或文件則通過(guò)Stream流進(jìn)行通信,。
本文設(shè)計(jì)了一個(gè)獨(dú)立的Plug-in插件,其功能是播放一個(gè)H.263格式的圖像壓縮文件,。顯示結(jié)構(gòu)為。
其核心部分是通過(guò)函數(shù)NPP_SetWindow傳遞窗口句柄并通過(guò)Stream流傳遞H.263的文件內(nèi)容,然后設(shè)置Plug-in插件的回調(diào)函數(shù),即窗口處理函數(shù),。針對(duì)本H.263插件的處理過(guò)程如下,。
(1)在函數(shù)NPP_SetWindow中,調(diào)用SubclassWindow(mhWnd,(WNDPROC)WinProc),使該窗口能夠截取窗口消息并繪制窗口。
(2)通過(guò)函數(shù)NPP_StreamAsFile把網(wǎng)頁(yè)中URL指定的服務(wù)器上H.263文件內(nèi)容保存為一個(gè)本地臨時(shí)文件并傳遞給Plug-in插件,。當(dāng)Plug-in偵聽(tīng)到該臨時(shí)文件后,將H.263文件解壓為YUV內(nèi)容,并顯示,。
(3)在回調(diào)函數(shù)WinProc中,處理該窗口中的WM_PAINT消息,最終完成YUV文件的顯示播放。
本例中回調(diào)函數(shù)WinProc僅僅處理了最簡(jiǎn)單的WM_PAINT消息,。但是一個(gè)功能強(qiáng)大的Plug-in插件,可以實(shí)現(xiàn)更復(fù)雜的回調(diào)函數(shù),使Plug-in窗口包含鍵盤(pán),、鼠標(biāo)的操作和菜單、工具欄的功能等,。例如在該P(yáng)lug-in中可以加入播放,、暫停,、結(jié)束、循環(huán)等一般性操作,這些操作經(jīng)過(guò)消息映射后都可以實(shí)現(xiàn),。
3?應(yīng)用程序嵌入瀏覽器中
一個(gè)完整的Plug-in插件可以根據(jù)需求實(shí)現(xiàn)各種應(yīng)用,。但是為了嵌入到瀏覽器中,這類(lèi)程序不能很大、很復(fù)雜,其功能是有限的,。在開(kāi)發(fā)辦公自動(dòng)化等應(yīng)用集成的一類(lèi)系統(tǒng)中,經(jīng)常需要把某些獨(dú)立的程序和第三方軟件集成到B/S應(yīng)用的系統(tǒng)中,。如何把獨(dú)立的應(yīng)用程序嵌入瀏覽器中顯得尤為重要。
由于許多大型程序無(wú)法被改造為Plug-in的方式,因此,需要通過(guò)Plug-in技術(shù)為應(yīng)用程序嵌入到瀏覽器中提供橋梁,。通常一個(gè)應(yīng)用程序是無(wú)法直接嵌入瀏覽器的網(wǎng)頁(yè)中,為此必須直接修改應(yīng)用程序的源碼,。本文研究了一個(gè)普通的Windows程序的修改和實(shí)現(xiàn)過(guò)程。
3.1 Plug-in的橋接
因?yàn)镹etscape/Mozilla之類(lèi)的瀏覽器直接調(diào)用第三方程序時(shí)只能通過(guò)Plug-in的方式實(shí)現(xiàn),所以必須事先完成一個(gè)Plug-in插件,用于橋接瀏覽器和應(yīng)用程序之間的通信,。該P(yáng)lug-in插件的內(nèi)容與上一節(jié)中完整Plug-in插件的開(kāi)發(fā)類(lèi)似,但是并非必須實(shí)現(xiàn)其中的函數(shù)NPP_StreamAsFile,。因?yàn)檫@種把應(yīng)用程序嵌入瀏覽器的方法通常是直接操縱本地硬盤(pán)的文件,不需要通過(guò)瀏覽器接受服務(wù)器上的數(shù)據(jù)流。
3.2 應(yīng)用程序的修改
把獨(dú)立應(yīng)用程序直接嵌入到瀏覽器的實(shí)現(xiàn)方式如下,。
(1)在Plug-in插件的函數(shù)NPP_SetWindow中必須把窗口句柄mhWnd傳遞給應(yīng)用程序,。
(2)應(yīng)用程序在命令行參數(shù)中接收窗口句柄,或者應(yīng)用程序采用偵聽(tīng)的方式等待Plug-in插件傳送過(guò)來(lái)的窗口句柄。
(3)應(yīng)用程序在CreateWindow操作前設(shè)置自己的主窗口屬性,例如在VC的程序中CMainFrame∷PreCreateWindow設(shè)置的父窗口句柄就是Plug-in中傳來(lái)的mhWnd,并把自己窗口屬性設(shè)置為WS_CHILD以作為一個(gè)子窗口顯示在Plug-in窗口中,。
(4)設(shè)置窗口的回調(diào)函數(shù),并指定該窗口所能接收的消息和操作,。一般用程序自身的回調(diào)函數(shù)即可,不需要修改。
3.3 程序接口的輸出
通過(guò)以上過(guò)程,即可把一個(gè)應(yīng)用程序完全地嵌入瀏覽器中,。但是在通常的辦公自動(dòng)化應(yīng)用中,還需要使該程序支持Script腳本的調(diào)用,例如支持JavaScript的調(diào)用是一種常見(jiàn)的需求和應(yīng)用,。為了使這種Plug-in插件支持Script腳本,Plug-in需要輸出一些額外的接口,簡(jiǎn)要過(guò)程為:(1)給Plug-in的每個(gè)輸出接口分配一個(gè)UID號(hào),可以用Windows下的uuidgen程序產(chǎn)生。(2)編寫(xiě)接口的IDL文件,。(3)在Plug-in程序中實(shí)現(xiàn)該接口的定義,。
由于在Plug-in程序中輸出的接口函數(shù)通常必須由應(yīng)用程序自己來(lái)實(shí)現(xiàn),所以如果應(yīng)用程序要支持Script腳本的調(diào)用,就必須采用某種機(jī)制接收特定消息,如采用Socket的偵聽(tīng)或組件模型來(lái)實(shí)現(xiàn)。
3.4 實(shí)際演示
通過(guò)以上方式,一個(gè)應(yīng)用程序可以嵌入到瀏覽器中,并且可以支持Script腳本的調(diào)用,。圖2是利用Plug-in技術(shù)把一個(gè)YUV實(shí)時(shí)播放程序嵌入到Mozilla瀏覽器中,。由圖2可以看出,一個(gè)獨(dú)立的應(yīng)用程序可以作為網(wǎng)頁(yè)的一部分嵌入到瀏覽器中。這樣對(duì)基于B/S模式的辦公自動(dòng)化系統(tǒng),普通用戶完全可以在瀏覽器中直接完成所有的工作,如經(jīng)過(guò)定制后的發(fā)文,、收文,、撰寫(xiě)和視頻會(huì)議系統(tǒng)等。這樣不僅增強(qiáng)了這類(lèi)集成系統(tǒng)的友好性和易用性,而且簡(jiǎn)化了用戶的學(xué)習(xí)和使用過(guò)程,具有良好的應(yīng)用需求,。
?
4? 結(jié)? 論
通過(guò)Plug-in方式能夠?qū)崿F(xiàn)瀏覽器的各種增強(qiáng)功能,。本文根據(jù)Plug-in開(kāi)發(fā)模式,實(shí)現(xiàn)了一個(gè)多媒體播放的Plug-in插件,使得用戶能夠通過(guò)瀏覽器訪問(wèn)并播放網(wǎng)上的H.263多媒體文件。本文還研究了如何把一個(gè)獨(dú)立的應(yīng)用程序通過(guò)Plug-in技術(shù)嵌入到Mozilla瀏覽器中,。這種技術(shù)大大豐富了瀏覽器的應(yīng)用環(huán)境,對(duì)現(xiàn)有基于B/S模式的應(yīng)用集成系統(tǒng)具有十分重要的使用價(jià)值,。
?
參考文獻(xiàn)?
1?Netscape Communications.Netscape Gecko Plug-in?API Reference.http://devedge.netscape.com/library/?
manuals/2002/plugin/1.0/,2002-10-05?
2?劉毅.Plug-in結(jié)構(gòu)應(yīng)用程序設(shè)計(jì).計(jì)算機(jī)應(yīng)用,2002;22(4)?
3?沈慧杰.利用Plug-in技術(shù)增強(qiáng)瀏覽器/服務(wù)器功能.計(jì)算機(jī)應(yīng)用,1998;18(11)?