【摘要】重復調用外部程序會占據大量的系統資源,甚至會導致系統不堪重負而崩潰。本文介紹了在Authorware中,如何借助外部擴展函數,通過程序的類名或標題名獲得外部程序窗口的句柄,然后用函數操作該句柄,來改變程序窗口的顯示狀態,從而避免程序被多次同時執行的方法。
【關鍵詞】Authorware,外部擴展函數,窗口句柄,窗口顯示狀態
【中圖分類號】G434
【文獻標識碼】B
【論文編號】1009—8097(2006)04—0057—03
一、問題提出
在用Authorware(AW)制作課件時,我們常常會遇到需要調用外部程序的情況。這種被調用的外部程序若沒有隨活動窗口(Actived Window)的轉移而自動退出,它的界面就有可能會被其他窗口所遮蓋,尤其是在全屏顯示的模式下。用戶在不知情的情況下,可能會頻繁調用該程序,這就有可能導致系統不堪重負而崩潰。如何才能保證調用的外部程序始終只有一個唯一運行的實例(Instance),即一個外部程序在桌面上只打開唯一的一個窗口呢?初學者常常為此困惑。
筆者在制作《交大電子年鑒》的時候,就碰到了類似的問題:我們為用戶設計的系列功能中包含了【查詢信息】的功能。在具體程序設計時發現AW制作檢索的功能比較簡單,于是就考慮用第三方軟件來彌補它的不足。筆者用Help builder制作了一個CHM文件,可是如何實現外部程序(CHM文件)與AW程序(a7p文件)之間的無縫連接呢?
我們知道,在AW中,利用內置的系統函數JumpOutReturn可以實現外部程序的調用及返回。但是該函數并沒有提供關閉外部程序窗口的功能。那么若再次調用,AW又將新開一個窗口,這就會造成多個窗口副本(實例)同時運行的情況。而且由于每次打開的都是新文件,用戶上次查詢結果沒有被保留。這不是用戶所期待的檢索功能。
理想的情形是:
1、用戶在使用過【檢索功能】后,沒有關閉此窗口,而是將焦點(Focus)轉到其他窗口。此時該窗口會被隱藏到后臺,當用戶再次需要檢索功能時,上次使用過的那個窗口就會置頂,即成為活動窗口。
2、用戶在使用【檢索功能】后關閉了窗口,那么當他再次點擊檢索功能后,新的窗口被打開且置頂。
二、基本概念
為了進一步描述外部程序窗口的管理方法,先解釋一下幾個概念。
1、什么叫做窗口句柄(Window Handle)?
一個窗口句柄是一個定義窗口的編號。每個窗口都有唯一的句柄。可以使用此句柄來控制這個窗口。比如讓窗口在最前面(stay on top),關閉窗口(close)等等。
2、什么是窗口的類(Class)?
每一個窗口都有一個類名。這是由程序員指定的。類常被用作查找一個特定窗口。例如:MS Word 窗口的類名為“OpusApp”,Authorware窗口的類名為\"APWMainClass\"等。常用程序的類名參見下表。[1]
表1 常用程序的類名
3、什么是窗口的標題(Title)?
窗口的標題一般就在程序窗口的左上角,如(圖1)所示。對于標題名不顯示在窗口界面上的程序,可以在任務欄中查看其窗口標題,如(圖2)所示。
圖1 程序窗口標題
圖2 任務欄中查看其窗口標題
三、實現方法一
我們可以用外部擴展函數Budapi.u32來實現這個功能。Budapi函數集是一組與計算機操作系統相關的LINGO函數。這里用到了它的窗口函數集( Window Functions )中兩個子函數BaFindWindow和BaSetWindowState。在進行制作前,首先要確定您的計算機中必須有Budapi.u32文件,這個文件可以從網上下載,也可以從一些多媒體光盤中找到。把它拷貝到AW的安裝目錄下即可。至于AW中導入外部函數的方法,本文中不再贅述。
如何獲得窗口句柄或窗口的類呢?我們知道,在AW中有一個叫做WindowHandle的系統變量,它存儲的是AW演示窗口的句柄信息。但是它不能提供外部程序窗口的句柄及類信息。BaFindWindow幫助我們實現這個功能。
BaFindWindow返回一個窗口句柄,此函數可以使用一個或兩個參數作為查找的標志。[2]
用法: Result:= BaFindWindow( Class, Title )
參數: Class 是窗口的類名;Title 是窗口的標題名
返回值: 整型。返回窗口句柄,如果沒找到窗口,返回值為0
例如查找一個WORD窗口句柄,可以使用BaFindWindow
( \"OpusApp\", \"\" )。如果知道要查找窗口的標題,也可以使用Title參數來查找。例如:BaFindWindow( \"\" , \" mydoc.doc-Microsoft Word\" )。在獲得了外部程序窗口的句柄之后,我們就可以將它作為其他函數的參數來使用了。
lBaSetWindowState函數用于改變窗口的狀態。[2]
用法: BaSetWindowState( WinHandle, State )
變量: WinHandle 參數是被改變窗口的句柄;
state參數是指窗口被改變后的新狀態,具體取值如下所示:
\"Hidden\"――隱藏窗口并且取消它的激活狀態;
\"Restored\"――激活、顯示一個窗口,如果窗口為最大(小)化,則使窗口還原;
\"Normal\"――激活、顯示一個窗口,使它保留當前尺寸和位置
\"Maximised\"――激活、顯示一個窗口并使它最大化
\"Minimised\"――激活、顯示一個窗口并使它最小化,以圖標方式顯示
\"MinNotActive\"――最小化一個窗口并使它以圖標方式顯示,但不激活它。
\"NotActive\"――使窗口以原來狀態顯示,但不激活它。
\"ShowNotActive\"――使窗口以當前尺寸和位置顯示,但不激活它。
\"StayOnTop\"――使窗口成為頂部窗口
\"DontStayOnTop\"――準許窗口在其他窗口之后顯示。
返回值: 空
在本示例中,我們要查找的外部程序為search.chm,程序窗口的標題名為“上海交通大學2005年年鑒”。我們用Restored狀態作為程序窗口的新狀態。具體程序流程如下所示(圖3)。
在計算圖標【判斷查詢窗口是否已打開】中,輸入以下語句:
hnd:=BaFindWindow(\"HH Parent\", \"上海交通大學2005年年鑒\")
――獲得標題為\"上海交通大學2005年年鑒\"的查詢窗口的句柄,將其值賦給變量hnd
if hnd<>0 then
BaSetWindowState( hnd, \"Restored\")
GoTo(IconID@\"wait\")
end if
――判斷變量hnd的值,如果不為0,說明此窗口已打開,則將這個已打開的窗口激活并顯示。并且將流程跳轉至等待圖標“wait”;如果hnd的值為0,說明窗口已關閉,則不執行判斷語句,進入下一個計算圖標【打開查詢窗口】。
在計算圖標【打開查詢窗口】中,輸入以下語句:
JumpOutReturn(\"\" , FileLocation^\"search.chm\")
圖3程序流程
――打開search.chm文件。
四、實現方法二
由于Budapi是一個第三方的擴展函數集,我們可能無法獲得。那么用AW自帶的WinAPI函數集可以實現同樣的功能。我們用到了WinAPI中的兩個子函數:FindWindow與Show
WindowAsync來實現。簡單介紹一下這兩個子函數的用法:
FindWindow函數的作用是獲得指定的窗口的句柄。
用法: FindWindow( LPCSTR lpClassName , LPCSTR lpWindowName)
參數: LPCSTR lpClassName是類名,LPCSTR lpWindowName是窗口的標題。
返回值:找到的窗口的句柄。如未找到相符合的窗口,則返回零。
ShowWindowAsync函數用來控制窗口是否可見。
用法: ShowWindowAsync( HWND hWnd, int nCmdShow)
參數: hWnd是窗口句柄;
nCmdShow定義如何顯示程序啟動后的窗口形式。取值如下:
0 ――隱藏窗口,活動狀態給另一個窗口
1或9 ――用原來的大小和位置顯示一個窗口,同時令其進入活動狀態
2 ――最小化窗口,并將其激活
3 ――最大化窗口,并將其激活
4 ――用最近的大小和位置顯示一個窗口,同時不改變活動窗口
5 ――用當前的大小和位置顯示一個窗口,同時令其進入活動狀態
6 ――最小化窗口,活動狀態給另一個窗口
7 ――最小化一個窗口,同時不改變活動窗口
8 ――用當前的大小和位置顯示一個窗口,不改變活動窗口
編程的思路與前面是相似的:首先用FindWindow來獲得調用的那個窗口的句柄信息,然后利用ShowWindowAsync來顯示這個窗口于最頂層。
參考文獻
[1] 鄧椿志. Authorware 多媒體設計專家門診[M].清華大學出版社,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
“本文中所涉及到的圖表、注解、公式等內容請以PDF格式閱讀原文”