1、在PB中实现多平台统一的API调用 (深圳:独孤求败 2003-05-27) ---- 一.问题的提出: ---- 我们知道,PB是一个支持多平台的软件开发工具。它主要用于C/S应用程序的客户端软件开发。PB支持用户在不同的平台上创建应用程序。而PB的API(Aplication Program Interface)调用是指PB能够利用其所挂的操作平台所提供的函数来完成某些功能。由于PB能应用在不同的平台上,因此随平台环境的不同。PB的API调用形式也因此不同。这就涉及到如何在PB的应用程序中开发出独立于操作系统的统一的API调用以保证不管实际的API函数调用是什么,都能为应用程序编写
2、出一致的界面。 ---- 二.解决问题的方法: ---- 用PB提供的非可视化定制类用户对象,使用继承,封装和重载的手段就能解决上述问题。具体地说,就是在应用程序中建立一个祖先类用户对象(基类),该祖先对象是一个非可视化定制类用户对象,在祖先类用户对象中封装能为每个环境定义的全部函数(这些函数是原型化的用户对象函数而不是外部声明的函数)。在祖先类用户对象中封装的函数不完成任何工作(即不完成任何功能,定义为虚函数)。具体的函数(即实际的对不同的操作系统的API调用)附加于祖先类用户对象的后代类用户对象中。即在后代类用户对象中重载祖先类用户对象中的所有函数,在后代类用户对象中进行API调用
3、的实际外部函数声明和调用。每一个后代类用户对象对应于一个操作系统。在应用程序对象的open事件的script中,用PB提供的GetEnvirnment()函数查询应用程序的环境以判断当前应用程序运行于哪一种操作系统中,将用祖先类用户对象声明的实例变量实例化为对应的操作系统所相应的后代类用户对象的实例。以便在运行时根据实例变量所具体实例化的类型来决定调用哪一个后代类用户对象中相应的函数(类的多态性)。 ---- 三.举例说明: ---- 下面以一个简单的例子说明如何在PB中实现多平台统一的API调用。 ---- 在本例中,需要实现这样一个功能:在打开应用程序的窗口时,能让它居于屏幕的
4、中心。这个功能由全局外部函数fun_centerwindow()完成。该函数的原型声明为: fun_centerwindow(window w_active)returns (None) ---- 在该函数中,我们要调用microsoft提供的函数GetSystemMetrics()来访问当前屏幕的宽度和高度,并利用以象素为单位的转换因子进行修改,再转换为PB单位。GetSystemMetrics()函数是windows操作系统提供的函数,在PB中调用这个函数时,要进行函数的外部声明。该函数的外部声明因操作系统的不同而不同。例如,在windows3.x和windows95中,该函数的
5、外部声明分别为: //win31 FUNCTION Int GetSystemMetrics(Int index) LIBRARY "USER.EXE" //win32 FUNCTION Int GetSystemMetrics (Int index) LIBRARY "USER32.DLL" ---- 下面,我们就以windows3.1和windows95这两个操作系统为例来实现对GetSystemMetrics()函数的统一调用界面。 ---- 首先,定义祖先类用户对象uo_apictrl。打开 user object画板,选中New,定义祖先类用户对象uo_ap
6、ictrl,为uo_apictrl定义user object function: uf_getsysmetrics(integer a_nindex)returns integer ---- 其具体代码为: return 1 ---- 其次,定义对应于windows3.1操作系统的后代类用户对象uo_apictrl_winapi。打开 user object画板,选中Inherit...,在Inherit From User Object对话框中选中刚才定义的祖先类用户对象uo_apictrl,在打开的user object画板下定义uo_apictrl_winapi,为uo_a
7、pictrl_winapi声明局部外部函数: PRIVATE FUNCTION Int GetSystemMetrics (Int index) LIBRARY "USER.EXE" ---- 为uo_apictrl_winapi重载uo_apictrl中的函数uf_getsysmetrics(integer a_nindex)returns integer。该重载函数的代码为: return GetSystemMetrics(a_nindex) ---- 以同样的方式定义对应于windows95操作系统的后代类用户对象uo_apictrl_win32。为uo_apict
8、rl_win32声明局部外部函数: PRIVATE FUNCTION Int GetSystemMetrics(Int index) LIBRARY "USER32.DLL" ---- 为uo_apictrl_win32重载uo_apictrl中的函数uf_getsysmetrics(integer a_nindex)returns integer。该重载函数的代码为: return GetSystemMetrics(a_nindex) ---- 第三步,在应用程序对象g_App中声明如下一个实例变量apictrl: uo_apictrl apictrl ---
9、 并在应用程序对象g_App的open事件的script中将apictrl实例化为对应的后代类用户对象的实例。该段代码如下: Environment env //定义一个环境对象env integer rtn rtn = GetEnvironment(env) IF rtn < > 1 THEN RETURN CHOOSE CASE env.OSType //测试操作环境类型 CASE Windows!//在windows操作系统 下再测试具体的windows操作系统版本 IF env.OSMajorRevision = 4 THEN //windows95 apict
10、rl = Create uo_apictrl_win32 ELSEIF env.OSMajorRevision = 3 THEN //windows3.x apictrl = Create uo_apictrl_winapi END IF CASE WindowsNT! apictrl = Create uo_apictrl_win32 CASE Else SetNull(apictrl) END CHOOSE ---- 最后,定义全局外部函数fun_centerwindow()。函数原型为: fun_centerwindow(window w_acti
11、ve) returns (None) ---- 具体代码为: int lWidth,lHeight int offsetX,offsetY //取当前屏幕的宽度和高度并转换为PB单位 lWidth = g_App.apictrl.uf_getsysmetrics(0) * (686/150) lHeight = g_App.apictrl.uf_getsysmetrics(1) * (801/200) offsetX = lWidth - w_active.Width offsetY = lHeight - w_active.Height //设定窗口的左上
12、角坐标 w_active.X = offsetX/2 w_active.Y = offsetY/2 ---- 四.小结 ---- 有了fun_centerwindow()函数后,只须在应用程序的窗口的open事件的script中编写如下代码 fun_centerwindow(this) ---- 即可将该窗口居中。请注意,这段代码除了无法使MDI应用程序中的工作表居中外对其它类型的窗口都有效。如要使MDI应用程序中的工作表居中,则须引用MDI框架的客户区。通过以上的例子我们可以知道,由于PB对多平台的支持,使程序开发者能利用同一种开发工具开发出运行于各种平台上的应用程序。而PB提供的环境对象允许在运行时修改应用程序来访问每一个指定平台的对象。






