在VFP中巧用字符串调用Widndows API

来源:互联网 发布:海军陆战队 知乎 编辑:程序博客网 时间:2024/06/06 07:29

在VFP中巧用字符串调用Widndows API

Gary DeWitt

Windows应用程序编程接口(API)是由C程序员编写开发的,它对数据类型的严格要求对于FoxPro开发者来说就可能是件头疼的事。在Gary DeWitt系列讲解的第三部分中,介绍了可以通过巧用字符串,蒙骗Windows API从而满足自己的开发需要。

类是一个非常好的思想,它能够代表抽象的概念。命名的属性可以用来存储数据,并且访问这些数据是很方便的。例如,无论在命名方面,还是在跟踪变量方面,Sue.Name和Gary.Name这种方式显然比这种IcName1和IcName2方式清晰明了的多。

Windows API的编程语言--C语言并不支持类(而C++支持类),但是C语言支持结构,结构与类有许多共同之处。结构是一些成员变量的组合,代表一系列相关的数据项。在Windows API中会常常遇到这样的结构。

这是系列讲解的第三部分,将介绍应用Windows API需要的三个基本技能的最后一个。在九月份的讲解中,已经声明了一些外部函数,并且讲解了如何调用这些外部函数。在十月份的讲解中,说明了如何通过指针调用API函数。通过增强对结构的理解和使用,同样可以完成图形界面的制作。

内存块
结构定义完之后,程序将开辟一块连续的内存单元用来存储结构的成员变量。例如下面就是一个结构的定义:

typedef struct _RECT {
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT

结构RECT定义了Windows应用程序界面(Windows API)的矩形区域。该结构中含有四个成员变量:left、top、right、bottom。每个成员变量皆为长整型,占4字节。所以RECT结构将占16字节的内存单元,left变量占4字节,top变量占4字节,依次类推。用这种方法存储相关数据即简单又有效。访问成员变量也比较容易,例如myRect是一个指向RECT结构的指针,那么myRect->left、myRect->top就表示结构RECT中的成员变量left、top,其他成员变量的表示与此相同。

Visual Foxpro的内存管理功能强大,如分配、释放内存以及整理内存,而开发者可以不去理会到底如何分配存储器。可是另一方面,开发者对物理空间的分配能力就减弱了许多。唯一可以确定的是VFP例程中的字符串将会占用某一块连续的内存单元,并且只要该字符串处于活动状态,VFP就不会变化字符串所占的内存单元。由于结构就是一块连续的内存单元,所以可以通过巧用字符串来开辟这样的一块连续的内存单元。

巧用字符串
我们可以很容易地用字符串来代表一个结构。例如,上面的RECT结构要占有16字节的内存单元,就可以用下面的语句定义一个16字节长度的零字符串。

IcRect = REPLICATE ( CHR (0) , 16 )

这一行代码所产生的16字节内存单元里的数据就能够用来表示一个宽度、高度为0,左上角位于屏幕的左上角(0,0)的一个矩形区域。通常情况下,为结构分配内存使用语句CHR(0)。如果不使用语句CHR(0),而是用语句SPACE(),那么对于上面,就将产生一个宽度、高度皆为538976288,左上角位于538976288,538976288的矩形区域。这可能并没有什么错误,但最好是使用语句CHR(0)初始化内存单元以避免出现不可预知的数据。

现在,让我们来看看如何使用RECT结构。记得上个月,我在使用Microsoft PowerPoint时,发现了它的顶层窗口,并且将它置于屏幕顶部。这个月将通过RECT结构以及2个API函数来控制这个窗口。假定已经得到了该窗口句柄,并且通过字符串IcRect的定义得到一虚RECT结构:

DECLARE INTEGER GetWindowRect IN Win32API ;
INTEGER, STRING @
InSuccess = GetWindowRect ( InHandle, @IcRect )

调用GetWindowRect() API函数时需给出PowerPoint窗口的位置数据,也就是结构中成员变量的值。由于是通过字符串的定义开辟的内存单元才得到的RECT结构,所以必须将这16字节的字符串从语法上分割为4个4字节长度的小段字符串,再将小段字符串转换成数值型数据。函数CharToBin()(可从网址www.pinpub.com/foxtalk/下载得到)就可以完成字符型数据到数值型数据的转换,另外函数BinToChar()可以将数值型数据转换为字符型数据。

InLeft = CharToBin (SUBSTR(IcRect,1,4))
InTop = CharToBin (SUBSTR (IcRect,5,4))
InRight = CharToBin (SUBSTR (IcRect,9,4))
InBottom = CharToBin (SUBSTR (IcRect,13,4))
假定矩形区域窗口数据如下:
InLeft = 0
InTop = 0
InRight = 200
InBottom = 200
现在想把该窗口向下、向右移动20个象素,并且使它位于顶层,同时处于非激活状态。下面的API函数就可以完成该窗口的移动和窗口状态的控制:
DECLARE INTEGER SetWindowPos IN Win32API ;
INTEGER hWnd, INTEGER InsertAfter, ;
INTEGER left, INTEGER top, ;
INTEGER width, INTEGER height, ;
INTEGER flags
SetWindowPos ( InHandle, HWND_TOP, ;
InLeft + 20, InTop + 20, ;
InRight + 20, InBottom + 20, ;
SWP_NOACTIVATE)
HWND_TOP为一常数,值为0,意味着窗口位于顶层;SWP_NOACTIVATE值为16,意味着窗口处于非激活状态。

小花招
你可能要问为什么要坚持使用这一个小花招。原因很简单:FoxPro不支持结构,通过字符串可以开辟一块连续内存单元,这有些类似Windows API中使用的结构。而对结构的完全支持将会使编程更轻松,但在FoxPro支持结构之前,这样做至少Windows API对其中的不同没有察觉。

我可以保证,如果你已经掌握了在过去三个月的时间里我所介绍的知识,那么你就可以使用Win32API中所包含的大部分函数了。事实上,这个星期有一位被问题困扰的编辑问我如何确定EXE的版本号。那么在下个月我就介绍有关方面的知识,同时还要介绍一种你可能在FoxPro中从未用过的API函数。
注:可在网址www.pinpub.com/foxtalk/下载11DEWITT.ZIP

Gary DeWitt:Medsoft公司的一名高级软件师,Medsoft公司是加拿大Tahoe市的一个医疗业务管理软件公司。他热衷于Visual FoxPro开发工具,同时也进行C++、Java和Visual Basic编程。他是微软认证专业人员。73512.57@compuserve.com或gdewitt@sierra.net

要了解更多的有关Foxtalk以及Pinnacle出版公司的情况,请访问下列站点:
http://www.pinpub.com/foxtalk/
注意:上面的站点并不是微软站点,微软对其内容概不负责。

这篇文章源自1997年11月的Foxtalk出版物。版权归Pinnacle出版公司所有,翻版必究。Foxtalk是Pinnacle出版公司独家发行的出版物。未经许可,不得以任何形式和手段复制或抄袭有关内容(重要文章的引用除外)。
Pinnacle出版公司的联系电话:
(800)788-1900或(206)251-1900