为VFP可视类增添绘图功能 2000年 第6期   Visual Foxpro中提供了基于 _Screen和表单窗口的绘图方法,如用Pset、Line画点、线等。然而感到其方法较有限,如有时需绘制圆弧、扇形或想对多边形填充,却发现Visual Foxpro可视类未提供相应的方法。现笔者找到两种解决方法: 解决方法之一,可用控件自身的Pset及Point方法根据图形学基本算法设计子程序,该方法速度慢得让人无法忍受且效果不好。解决方法二,调用Windows API函数。Windows执行过程中常常通过动态连接库(DLLs)支持其所需的许多功能。这些动态函数库加载在内存中根据需要与用户程序进行连接。API 库中有丰富的图形操作函数。调用API函数有许多优点:功能全、速度快、程序代码小。   有关访问API函数的文章已不少,这里不再重复。然而使用API函数在窗口或设备中绘图时,必须得到该窗口或设备的句柄HDC。在Visual Foxpro参考函数中却找不到获得HDC的方法,虽然可用API中的GetDc函数获得某窗口的HDC。但该函数又需用到窗口句柄作参数。如何获得窗口句柄呢?API函数(如:GetActiveWindow,GetWindow等)直接返回的是整个应用程序窗口句柄,而用户窗口一般是VFP应用程序中的一个文档窗。其实在VFP中返回用户窗口一个很方便的方法是通过FOXTOOLS.FLL库中WOnTop和WhToHwnd函数。上述函数语法如下:   WHANDLE WonTop()* 返回用户使用的活动窗口WHandle   HWND WhToHwnd(WHandle)* 返回相应的窗口句柄hWnd。   HDC GetDC(hWnd)* 返回指定窗口hWnd的设备句柄hDC   有了设备句柄调用绘图函数则很容易,例如:画矩形的API函数语法如下:   BOOL Rectangle(hDC,x1,y1,x2,y2)   其中x1,y1,x2,y2为矩形对角线的x,y坐标   使用这些API函数绘图需注意几点:   1.API函数使用前需用declare声明,另外应注意函数名称大小写(具体用法见文后程序)。   2.调用以上函数时,WHandle、hWnd、hDc、x1、y1、x2、y2参数及BOOL均可用Integer类型进行说明,以上函数返回值若为0,表示调用失败。   3.Visual FoxPro设置前景色、填充色等属性设置不影响API函数中绘图方式。   4.使用Visual FoxPro原类方法的绘图方法时,会清除API画的图形。因此,两者最好不要混合使用。   5.API函数参数中若有复合数据结构或数组,则应将该数据结构转换成String型。如下例语句可在VFP中调用Polygon函数绘制多边形。   declare integer Polygon in win32api integer,string,integer   dime point(3,2)* point为三角形顶点坐标   trangle=′′   for i=1 to 3   point(i,1)=100+100*rand()* I点X坐标为(100~200)随机数   point(i,2)=100+100*rand()* I点Y坐标为(100~200)随机数   以下两条语句将多边形顶点的数值转化为字符,并连入字符串   trangle=trangle+chr(point(i,1))+chr(0)+chr(0)+chr(0)   trangle=trangle+chr(point(i,2))+chr(0)+chr(0)+chr(0)   endfor   polygon(thisform.hdc,trangle,3)   VPF中打开一个表单,在表单中新建属性并新建API函数编制的绘图方法,最后将其保存为新类库。这样一个集绘图与原表单各种功能的可视类就建好了。   以下是Visual Foxpro中用API函数动态设计饼形图的简单实例。图为执行程序后屏幕输出。三个文本框中任一数据改变后,饼形图将立即重绘。   程序:   为Form对象增加新属性hDc和新方法Pie。   Form1的Load 事件:   declare integer GetDC in win32api integer   declare integer Pie in win32api integer,integer,integer,integer,; integer,integer,integer,integer,integer   declare integer CreateSolidBrush in win32api long   declare integer SelectObject in win32api integer,integer   declare integer CreatePen in win32api integer,integer,long   set library to sys(2004)+″foxtools.fll″   Form1的Activate事件   whandle=_WOnTop()   hwnd=_WhToHwnd(whandle)   set library to   thisform.hDC=GetDC(hwnd)   Form1的Pie方法   lparameters x1,y1,x2,y2,x3,y3,x4,y4   hbrush=CreateSolidBrush(thisform.fillcolor)   hpen=Createpen(thisform.drawstyle,thisform.drawwidth,thisform.forecolor)   =selectobject(thisform.hdc,hbrush)   =selectobject(thisform.hdc,hpen)   =pie(thisform.hdc,x1,y1,x2,y2,x3,y3,x4,y4)   Form1的Unload事件   clear dlls   将本表单保存为新的可视类FORMDRAW。   创建一个Form(FORMDRAW为其可视类)、添加四个Label、三个Text(Value属性分别赋三个数值)和三个Shape对象,属性设置略(使其外观如^06020401a^),为FORM增加方法Drawchar。   表单的Drawchart方法:   x1=thisform.text1.value   x2=thisform.text2.value   x3=thisform.text3.value   total=x1+x2+x3   a1=2*pi()*x1/total   a2=2*pi()*x2/total   x1=250   y1=50   x2=350   y2=150   mx=(x1+x2)/2-1   my=(y1+y2)/2-1   thisform.fillcolor=255   =thisform.pie(x1,y1,x2,y2,mx+10,my,mx+10*cos(a1),my-10*sin(a1))   thisform.fillcolor=rgb(0,255,0)   =thisform.pie(x1,y1,x2,y2,mx+10*cos(a1),my-10*sin(a1),mx+10*cos(a1+a2),my;   -10*sin(a1+a2))   thisform.fillcolor=rgb(0,0,255)   =thisform.pie(x1,y1,x2,y2,mx+10*cos(a1+a2),my-10*sin(a1+a2),mx+10,my)   Text1、Text2、Text3的Valid事件:   Thisform.drawchart   表单的Paint事件   Thisform.drawchart   用API函数绘图与Visual FoxPro自身方法相比,使用更灵活、绘图性能强且速度快。关于Windows API 函数功能及用法请查阅有关资料。本文所述方法亦可在能与API函数通讯的其它软件中使用。