PowerBuilder开发应用系列讲座(21)


使用PowerBuilder另外500个函数(下)

激活另一个应用实现

首先声明下列local external函数
Subroutine BringWindowToTop(int hWnd) Library "User"
Function uint GetNextWindow(uint hWnd, int Flag) Library "user"
Function uint GetWindowText(uint hWnd, REF string Title, uint Size )Library "user"Function uint ShowWindow(uint hWnd, int CmdShow) Library "user"
Function integer IsIconic(uint hWnd) Library "user"
Function integer OPenIcon(uint hWnd) Library "user"
Function integer FindWindow(string ClassName, string WindowName) Library "user"Function integer FindWindow(long ClassName, string WindowName) Library "user"Function integer FindWindow(string ClassName, long WindowName) Library "user"键入下面的窗口级函数:
fw_make_app_active
//返回:boolean
//参数:
//string as_title
boolean lb_cont = TRUE
integer li_result, li_size
string ls_title
uint li_handle
li_handle = Handle ( this )
li_size = Len ( at_title ) + 1
//li_handle = FindWindow ( 0, "Control Panel" )
DO WHILE lb_cont
li_handle = GetNextWindow ( li_handle, 1 )
If li_handle = Handle ( this ) THEN Return FALSE
li_result = GetWindowText ( li_handle, ls_title, li_size )
IF ls_title = as_title THEN lb_cont = FALSE
LOOP
//ShowWindow ( li_handle, 3 )
IF IsIconic ( li_handle ) > 0
THEN
OpenIcon ( li_handle )
ELSE
BringWindowToTop ( li_handle )
END IF
Return TRUE
工作原理
获得另一个应用最顶层窗口引用的最简单方法就是用FindWindow函数来查找。FindWindow函数有两个参数:要找的窗口的类名和窗口的标题。注意,我们在local external函数中用三种方式声明了这一函数。这是因为可以用null作为"通配符"分别传递两个参数。为了传递null,必须将参数类型定义成long型,其值为0。所以我们需要为每一种可能的调用形式定义一个local external函数。当我们真正使用这个函数时,PowerBuilder自动判断要用哪一种形式。
例如,在窗口函数fw_make_app_active中,我们可以用这种手段使FindWindow函数搜索ControlPanel窗口。接下来只要将FindWindow函数返回的窗口句柄传递给BringWindowToTop函数就可以激活ControlPanel窗口了。
但是这种做法有两点缺陷:
1.无法知道某个应用的顶层窗口的全名。例如当使用Microsoft Word时,当前打开的
文档的名字也将出现在窗口的标题上。因此,这种情况下,寻找顶层窗口需要另一种方法。
2.如果要激活的窗口正处于最小化状态,BringWindowToTop函数将不能正常工作。
实际上,上面提到的第二个问题比较容易解决。我们加入IsIconic函数判断要激活的窗口是否最小化。如果不是最小化状态,就使用BringWindowsToTop函数。如果是最小化状态,就用OpenIcon函数来激活该窗口。这种方法只假定以窗口最小化前的大小及位置显示该窗口。我们也可以用Show Window函数来对要显示的其它应用的窗口施以更多的控制。
本例中,我们传送一个参数使被激活窗口以最大化方式显示。下表是不同激活窗口方式的参数对照:
解决第二个问题时,我们声明了另外两个函数:GetNextWindow和GetWindowsText。如果我们将一个窗口句柄传递给GetNextWindow函数,它将在父窗口所属的所有子窗口之间循环。如果将一个顶层窗口句柄传递给该函数,该函数将在所有顶层窗口之间循环。我们希望得到的是后一种方式,所以我们首先要获取自己应用的顶层窗口句柄。
当我们在顶层窗口之间循环时,用GetWindowText函数返回它们的标题。该函数有三个参数:窗口句柄、一个用以返回标题的字符串以及返回字符串的最大长度。我们要充分利用最后一个参数,因为我们并不想要匹配整个窗口标题,而是要匹配能保证我们发现所要寻找的窗口的长度。例如,如果我们把"Microsoft Word"传递给这个窗口函数时,这个函数判断文本的长度并将它加1,这样只将我们要比较的字符串的长度传递给了GetWindowText函数,该函数在顶层窗口之间循环,寻找以该字符串开头的窗口。如果我们没有发现匹配,将在循环到我们自己的应用窗口时退出循环。这时,我们简单地退出函数。