【摘要】重復(fù)調(diào)用外部程序會(huì)占據(jù)大量的系統(tǒng)資源,甚至?xí)?dǎo)致系統(tǒng)不堪重負(fù)而崩潰。本文介紹了在Authorware中,如何借助外部擴(kuò)展函數(shù),通過程序的類名或標(biāo)題名獲得外部程序窗口的句柄,然后用函數(shù)操作該句柄,來改變程序窗口的顯示狀態(tài),從而避免程序被多次同時(shí)執(zhí)行的方法。
【關(guān)鍵詞】Authorware,外部擴(kuò)展函數(shù),窗口句柄,窗口顯示狀態(tài)
【中圖分類號(hào)】G434
【文獻(xiàn)標(biāo)識(shí)碼】B
【論文編號(hào)】1009—8097(2006)04—0057—03
一、問題提出
在用Authorware(AW)制作課件時(shí),我們常常會(huì)遇到需要調(diào)用外部程序的情況。這種被調(diào)用的外部程序若沒有隨活動(dòng)窗口(Actived Window)的轉(zhuǎn)移而自動(dòng)退出,它的界面就有可能會(huì)被其他窗口所遮蓋,尤其是在全屏顯示的模式下。用戶在不知情的情況下,可能會(huì)頻繁調(diào)用該程序,這就有可能導(dǎo)致系統(tǒng)不堪重負(fù)而崩潰。如何才能保證調(diào)用的外部程序始終只有一個(gè)唯一運(yùn)行的實(shí)例(Instance),即一個(gè)外部程序在桌面上只打開唯一的一個(gè)窗口呢?初學(xué)者常常為此困惑。
筆者在制作《交大電子年鑒》的時(shí)候,就碰到了類似的問題:我們?yōu)橛脩粼O(shè)計(jì)的系列功能中包含了【查詢信息】的功能。在具體程序設(shè)計(jì)時(shí)發(fā)現(xiàn)AW制作檢索的功能比較簡單,于是就考慮用第三方軟件來彌補(bǔ)它的不足。筆者用Help builder制作了一個(gè)CHM文件,可是如何實(shí)現(xiàn)外部程序(CHM文件)與AW程序(a7p文件)之間的無縫連接呢?
我們知道,在AW中,利用內(nèi)置的系統(tǒng)函數(shù)JumpOutReturn可以實(shí)現(xiàn)外部程序的調(diào)用及返回。但是該函數(shù)并沒有提供關(guān)閉外部程序窗口的功能。那么若再次調(diào)用,AW又將新開一個(gè)窗口,這就會(huì)造成多個(gè)窗口副本(實(shí)例)同時(shí)運(yùn)行的情況。而且由于每次打開的都是新文件,用戶上次查詢結(jié)果沒有被保留。這不是用戶所期待的檢索功能。
理想的情形是:
1、用戶在使用過【檢索功能】后,沒有關(guān)閉此窗口,而是將焦點(diǎn)(Focus)轉(zhuǎn)到其他窗口。此時(shí)該窗口會(huì)被隱藏到后臺(tái),當(dāng)用戶再次需要檢索功能時(shí),上次使用過的那個(gè)窗口就會(huì)置頂,即成為活動(dòng)窗口。
2、用戶在使用【檢索功能】后關(guān)閉了窗口,那么當(dāng)他再次點(diǎn)擊檢索功能后,新的窗口被打開且置頂。
二、基本概念
為了進(jìn)一步描述外部程序窗口的管理方法,先解釋一下幾個(gè)概念。
1、什么叫做窗口句柄(Window Handle)?
一個(gè)窗口句柄是一個(gè)定義窗口的編號(hào)。每個(gè)窗口都有唯一的句柄??梢允褂么司浔鷣砜刂七@個(gè)窗口。比如讓窗口在最前面(stay on top),關(guān)閉窗口(close)等等。
2、什么是窗口的類(Class)?
每一個(gè)窗口都有一個(gè)類名。這是由程序員指定的。類常被用作查找一個(gè)特定窗口。例如:MS Word 窗口的類名為“OpusApp”,Authorware窗口的類名為\"APWMainClass\"等。常用程序的類名參見下表。[1]
表1 常用程序的類名
3、什么是窗口的標(biāo)題(Title)?
窗口的標(biāo)題一般就在程序窗口的左上角,如(圖1)所示。對于標(biāo)題名不顯示在窗口界面上的程序,可以在任務(wù)欄中查看其窗口標(biāo)題,如(圖2)所示。
圖1 程序窗口標(biāo)題
圖2 任務(wù)欄中查看其窗口標(biāo)題
三、實(shí)現(xiàn)方法一
我們可以用外部擴(kuò)展函數(shù)Budapi.u32來實(shí)現(xiàn)這個(gè)功能。Budapi函數(shù)集是一組與計(jì)算機(jī)操作系統(tǒng)相關(guān)的LINGO函數(shù)。這里用到了它的窗口函數(shù)集( Window Functions )中兩個(gè)子函數(shù)BaFindWindow和BaSetWindowState。在進(jìn)行制作前,首先要確定您的計(jì)算機(jī)中必須有Budapi.u32文件,這個(gè)文件可以從網(wǎng)上下載,也可以從一些多媒體光盤中找到。把它拷貝到AW的安裝目錄下即可。至于AW中導(dǎo)入外部函數(shù)的方法,本文中不再贅述。
如何獲得窗口句柄或窗口的類呢?我們知道,在AW中有一個(gè)叫做WindowHandle的系統(tǒng)變量,它存儲(chǔ)的是AW演示窗口的句柄信息。但是它不能提供外部程序窗口的句柄及類信息。BaFindWindow幫助我們實(shí)現(xiàn)這個(gè)功能。
BaFindWindow返回一個(gè)窗口句柄,此函數(shù)可以使用一個(gè)或兩個(gè)參數(shù)作為查找的標(biāo)志。[2]
用法: Result:= BaFindWindow( Class, Title )
參數(shù): Class 是窗口的類名;Title 是窗口的標(biāo)題名
返回值: 整型。返回窗口句柄,如果沒找到窗口,返回值為0
例如查找一個(gè)WORD窗口句柄,可以使用BaFindWindow
( \"OpusApp\", \"\" )。如果知道要查找窗口的標(biāo)題,也可以使用Title參數(shù)來查找。例如:BaFindWindow( \"\" , \" mydoc.doc-Microsoft Word\" )。在獲得了外部程序窗口的句柄之后,我們就可以將它作為其他函數(shù)的參數(shù)來使用了。
lBaSetWindowState函數(shù)用于改變窗口的狀態(tài)。[2]
用法: BaSetWindowState( WinHandle, State )
變量: WinHandle 參數(shù)是被改變窗口的句柄;
state參數(shù)是指窗口被改變后的新狀態(tài),具體取值如下所示:
\"Hidden\"――隱藏窗口并且取消它的激活狀態(tài);
\"Restored\"――激活、顯示一個(gè)窗口,如果窗口為最大(小)化,則使窗口還原;
\"Normal\"――激活、顯示一個(gè)窗口,使它保留當(dāng)前尺寸和位置
\"Maximised\"――激活、顯示一個(gè)窗口并使它最大化
\"Minimised\"――激活、顯示一個(gè)窗口并使它最小化,以圖標(biāo)方式顯示
\"MinNotActive\"――最小化一個(gè)窗口并使它以圖標(biāo)方式顯示,但不激活它。
\"NotActive\"――使窗口以原來狀態(tài)顯示,但不激活它。
\"ShowNotActive\"――使窗口以當(dāng)前尺寸和位置顯示,但不激活它。
\"StayOnTop\"――使窗口成為頂部窗口
\"DontStayOnTop\"――準(zhǔn)許窗口在其他窗口之后顯示。
返回值: 空
在本示例中,我們要查找的外部程序?yàn)閟earch.chm,程序窗口的標(biāo)題名為“上海交通大學(xué)2005年年鑒”。我們用Restored狀態(tài)作為程序窗口的新狀態(tài)。具體程序流程如下所示(圖3)。
在計(jì)算圖標(biāo)【判斷查詢窗口是否已打開】中,輸入以下語句:
hnd:=BaFindWindow(\"HH Parent\", \"上海交通大學(xué)2005年年鑒\")
――獲得標(biāo)題為\"上海交通大學(xué)2005年年鑒\"的查詢窗口的句柄,將其值賦給變量hnd
if hnd<>0 then
BaSetWindowState( hnd, \"Restored\")
GoTo(IconID@\"wait\")
end if
――判斷變量hnd的值,如果不為0,說明此窗口已打開,則將這個(gè)已打開的窗口激活并顯示。并且將流程跳轉(zhuǎn)至等待圖標(biāo)“wait”;如果hnd的值為0,說明窗口已關(guān)閉,則不執(zhí)行判斷語句,進(jìn)入下一個(gè)計(jì)算圖標(biāo)【打開查詢窗口】。
在計(jì)算圖標(biāo)【打開查詢窗口】中,輸入以下語句:
JumpOutReturn(\"\" , FileLocation^\"search.chm\")
圖3程序流程
――打開search.chm文件。
四、實(shí)現(xiàn)方法二
由于Budapi是一個(gè)第三方的擴(kuò)展函數(shù)集,我們可能無法獲得。那么用AW自帶的WinAPI函數(shù)集可以實(shí)現(xiàn)同樣的功能。我們用到了WinAPI中的兩個(gè)子函數(shù):FindWindow與Show
WindowAsync來實(shí)現(xiàn)。簡單介紹一下這兩個(gè)子函數(shù)的用法:
FindWindow函數(shù)的作用是獲得指定的窗口的句柄。
用法: FindWindow( LPCSTR lpClassName , LPCSTR lpWindowName)
參數(shù): LPCSTR lpClassName是類名,LPCSTR lpWindowName是窗口的標(biāo)題。
返回值:找到的窗口的句柄。如未找到相符合的窗口,則返回零。
ShowWindowAsync函數(shù)用來控制窗口是否可見。
用法: ShowWindowAsync( HWND hWnd, int nCmdShow)
參數(shù): hWnd是窗口句柄;
nCmdShow定義如何顯示程序啟動(dòng)后的窗口形式。取值如下:
0 ――隱藏窗口,活動(dòng)狀態(tài)給另一個(gè)窗口
1或9 ――用原來的大小和位置顯示一個(gè)窗口,同時(shí)令其進(jìn)入活動(dòng)狀態(tài)
2 ――最小化窗口,并將其激活
3 ――最大化窗口,并將其激活
4 ――用最近的大小和位置顯示一個(gè)窗口,同時(shí)不改變活動(dòng)窗口
5 ――用當(dāng)前的大小和位置顯示一個(gè)窗口,同時(shí)令其進(jìn)入活動(dòng)狀態(tài)
6 ――最小化窗口,活動(dòng)狀態(tài)給另一個(gè)窗口
7 ――最小化一個(gè)窗口,同時(shí)不改變活動(dòng)窗口
8 ――用當(dāng)前的大小和位置顯示一個(gè)窗口,不改變活動(dòng)窗口
編程的思路與前面是相似的:首先用FindWindow來獲得調(diào)用的那個(gè)窗口的句柄信息,然后利用ShowWindowAsync來顯示這個(gè)窗口于最頂層。
參考文獻(xiàn)
[1] 鄧椿志. Authorware 多媒體設(shè)計(jì)專家門診[M].清華大學(xué)出版社,2004,(10)
[2] Budapi中文幫助[EB/OL].http://www.authorware.cn
How to Avoid Duplicated Loading of Routine in Authorware
He QingHuang Jian
Shanghai JiaoTong University,Shanghai,200030
Abstract:The duplicated loading of a routine will consume vast system resource, and even result in a system crash. This paper introduces the way to eliminate the concurrent running of one routine in Authorware: by means of the external function, which can get window’s Handle from its class or title name and can change the window’s display status.
Keywords:Authorware,External Funtions,Window Handel,Window Display Status
“本文中所涉及到的圖表、注解、公式等內(nèi)容請以PDF格式閱讀原文”