VFP调用WIN32API之路,让你的软件更强大

我们在VFP编程时,为了弥补VFP本身功能的不足,常常会用到WIN32API函数来对VFP的功能行扩展,例如取得系统信息、对注册表进行操作等,但是由于WIN32API函数是C++的数据结构形式,在调用时与VFP的数据格式有所不同,因此在调用时往往会产生问题,而目前的一些资料所介绍的大都是VB、DELPHI等语言如何调用,对VFP如何调用介绍的比较少,更缺少具体的调用事例,下面我分几次介绍在VFP如何调用WIN32API函数,并就一些常用的WIN32API函数作一介绍,由于本人水平有限,所介绍的内容,仅供您参考,也欢迎您在我的[请您留言]中共同探讨:

一、VFP中调用WIN32API函数的格式

VFP中调用WIN32API函数的命令主要是:

DECLARE - DLL

CLEAR DLLS

1.DECLARE - DLL 它用于注册外部 Windows 32 位动态链接库 ( .DLL ) 中的

一个函数。

语法:DECLARE [cFunctionType] FunctionName IN LibraryName [AS AliasName]

   [cParamType1 [@] ParamName1, cParamType2 [@] ParamName2, ...]

说明:

cFunctionType 指定该函数返回值的类型,其类型代码如下:

SHORT   16 位整数

INTEGER   32 位整数

SINGLE    32 位浮点数

DOUBLE    64 位浮点数

STRING    字符串

FunctionName 指定要注册使用的32位函数名。注意 FunctionName 区分大小写。

  如果该函数名与Visual FoxPro的保留字相同,应使用AS参数另起别名。

IN LibraryName 指定该函数所在的外部动态链接库文件名,如果LibraryName为:WIN32API时,VFP将依次查找KERNEL32.DLL、GDI32.DLL、USER32.DLL、MPR.DLL及ADVAPI32.DLL等动态链接库文件名。

AS AliasName 当API函数的名称与Visual FoxPro的保留字相同时,另取AliasName别名,另取的别名是不区分大小写的。

cParameterType1 [@] ParamName1, cParameterType2 [@] ParamName2, ...

 指定传递给被调用的32位.DLL函数的参数类型及参数名称。其类型代码如FunctionType,如果要以传址方法传递参数则应在参数名前加上@。

2.CLEAR DLLS 释放所有利用DECLARE - DLL命令所装入的动态链接库。

一旦申明WIN32API函数成功,就可以和一般函数一样用 ?xxx()、=xxx()来调用。

下面以具体事例谈谈win32api在Vfp中的运用:

1.利用win32api函数获取指定磁盘的卷标:

Stor 0 to C_var,C_cd,C_qfC_Var='c:\'DECLARE INTEGER GetVolumeInformation IN Win32API STRING @, STRING @, INTEGER,;    INTEGER @, INTEGER @, INTEGER @, STRING @, INTEGERxx=GetVolumeInformation(C_Var,"",20,@C_var,@C_cd,@C_qf,0,0)CLEAR DLLS &&释放所有利用DECLARE - DLL命令所装入的动态链接库。

xx<>0 获取指定磁盘的卷标成功,反之则未成功。

C_var=指定磁盘的卷标,是个十进制的数值,与我们在DOS下看到的16进制不同。

C_cd=系统规定的文件名每一部分的长度,是个十进制的数值。

C_qf=文件名的大小写标志,是个十进制的数值。

怎么样很简单吧,我们可以把获取的磁盘卷标,用来加密我们的软件,这样

我们的 软件就具有防拷贝的功能了。 

2.在VFP中利用WN32API函数调用Outlook Express给你的程序建立发送 邮件的链接

利用WN32API函数我们可以在VFP程序中,通过Label标签或Command命令按钮来达到调用由系统默认的邮件收发软件的目的,也就是建立所谓的链接功能,在VFP代码中:

DECLARE INTEGER ShellExecute IN shell32.DLL INTEGER HWND, STRING,STRING; ........lpszFile,STRING ,STRING ,INTEGER*申明ShellExecute函数lpszFile='mailto:cfyns@163.net'*设定你需要发送的E-mail=ShellExecute(0,0,lpszFile , 0,0,1)*调用ShellExecute函数

一执行=ShellExecute(),就会弹出书写E-mail的窗体。

3.利用WIN32API函数,防止同一程序被重复执行。

利用WIN32API中的FindWindow()函数取得待测窗口的handle(句柄),其返回值不等于0,则表示该EXE文件已运行。

VFP代码:

DECLARE INTEGER FindWindow IN WIN32API STRING,STRINGLOCAL cTitlecTitle=_screen.captionif FindWindow(0,cTitle)<>0  =messagebox("程序已运行,无需重复!",48)endif

注意:FindWindow()函数是取得窗口的caption,如果caption在程序的运行过程中已经改变,则达不到目的。

4.利用WIN32API函数,关闭或重新启动你的电脑

VFP代码:

DECLARE INTEGER ExitWindowsEx IN USER32.DLL INTEGER , INTEGER=ExitWindowsEx(1,1) &&关闭系统如果:=ExitWindowsEx(2,1) &&重新启动系统如果:=ExitWindowsEx(0,0) &&进入登入者身份对话框

这次都写了些雕虫小技,下次将写些复杂的WIN32API函数调用,可别 错过哦! 

我们在编程中,有时需要用户指定文件夹路径,在VFP中我们往往会用GETDIR()来供用户选择,但GETDIR()提供的文件夹列表是“选择驱动器再在相应的驱动器中选择相应文件夹的界面”, 而目前我们常见的是采用类似资源管理器中“所有文件夹”界面:最上层是“桌面”,然后是“我的电脑”、驱动器A、C、D...等,   

图片

  也许有人会问,是不是又在介绍.OCX控件?如果不是在VFP中能实现这样的文件夹列表吗?

  要实现这样的文件夹列表,我们得先了解三个WIN32API函数:

   1、FindWindow &&获取窗口句柄

   2、SHBrowseForFolder &&显示文件夹夹列表窗

   3、SHGetPathFromIDList &&获取用户选择的文件夹名

 ☆FindWindow 这个API函数不用介绍了吧,在如何防止程序重复运行中介绍过。

 ☆SHBrowseForFolder 函数是实现文件夹列表功能的关键,在API帮助里是这样写的:

Displays a dialog box that enables the user to select a shell folder.

WINSHELLAPI LPITEMIDLIST WINAPI SHBrowseForFolder(LPBROWSEINFO lpbi)

typedef struct _browseinfo {

 HWND hwndOwner;     // see below

 LPCITEMIDLIST pidlRoot; // see below

 LPSTR pszDisplayName;  // see below

 LPCSTR lpszTitle;    // see below

 UINT ulFlags;      // see below

 BFFCALLBACK lpfn;    // see below

 LPARAM lParam;      // see below

 int iImage;       // see below

} BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO;

  或许您注意到了在这个函数里用到了一个BROWSEINFO类型,此类型包含了列表框使用的一些参数,比如:当前窗口句柄(hwndOwner)、从何根路径开始展开文件夹(pidlRoot)、目录树上方的标题(lpszTitle)等。

  在VFP中能否声明成功这个函数的关键是如何定义这个BROWSEINFO类型参数,从这个类型中我们可以看出它是有数值型和字符型混合组成的,而VFP没有定义结构类型的语句,这也是很多API无法在VFP声明和调用的愿因所在,那么我们又如何定义这个类型呢?

  抓住问题的关键,忽略次要因素,很多问题往往就可以解决了,在这里我们只要告诉这个函数:列表框显示在哪个主窗口里,其它的参数一概忽略,这个函数即可声明成功。那我们可以看出,在这里我们只要定义hwndOwner(数值型) 这一个参数,然后告诉SHBrowseForFolder 就可直接调用了。能行吗?您只要一 试就知道了。

  遗憾的是其它参数就只能忽略了,好在并不影响调用的结果,见上图。

 ☆SHGetPathFromIDList 函数负责取回用户在列表框中选择的结果。当我们调用

SHBrowseForFolder API函数后,如果调用成功,则返回一个数值型的指针,这个指针如果是NULL,表示用户按了取消按钮,否则返回一个非0的指针值供SHGetPathFromIDList 函数使用,以取回具体的路径名。

  三个函数介绍完了,那么在VFP代码中如何写呢?假如我们有一个表单,上面有一个Command1按钮和Label1标签,我们就在 Command1.Click事件中这样写:

Declare integer FindWindow IN WIN32API String,StringDeclare integer SHBrowseForFolder in "shell32.dll" integer @*注意integer @ 中的这个“@”符号,千万不可省略,否则无法调用成功,下同。Declare integer SHGetPathFromIDList in "shell32.dll" integer,String @ cTitle=_screen.caption        &&取当前主窗口标题。hOwner=FindWindow(0,cTitle)    &&取当前主窗口句柄pidl = SHBrowseForFolder(hOwner) &&如果成功,将显示上图列表框,供用户选择,                  &&并将选择后的列表框指针,返回给pidl变量。if not ISNULL(pidl) mpath=spac(512)           &&变量mpath预留512个空字符。 =SHGetPathFromIDList(pidl,@mpath) &&如果成功,用户选择的路径名,将自动                    *填入mpath变量中。 thisform.Label1.Caption=mpath     &&显示用户选择的路径名。endi

这样当我们一按Command1按钮,即可看到上图的列表了。

6.在VFP中利用SetLocalTime函数调用设置系统日期或时间

set date ansiset century onset hours to 24*假定设置系统日期、时间为:1999,9,1nDate=ctod('1999-09-01')oldtime=TIME()             &&取当前时间nHo=VAL(subs(oldtime,1,2))       &&取当前时间-时nSe=VAL(SUBSTR(oldtime, 4, 2))     &&取当前时间-分nMi=VAL(SUBSTR(oldtime, 7, 2))     &&取当前时间-秒nMM=VAL(RIGHT(oldtime, 2))       &&取当前时间-毫秒cBuf=h2str(YEAR(nDate))+h2str(MONTH(nDate))+h2str(DOW(nDate) - 1)+;  h2str(DAY(nDate))+h2str(nHo)+h2str(nSe)+h2str(nMi)+h2str(nMm)*&&将转换后的二进制字符连接

DECLARE SHORT SetLocalTime IN win32api STRING SystemTime  =SetLocalTime(cBuf)       &&设置系统日期Retu

*====以下是将十进制转换为二进制的自定义函数Function h2strPARAMETERS ZhszPRIVATE FhzFhz=Chr(Zhsz%256)+Chr(Zhsz/256)RETURN Fhz

  好了,就这么简单,并不象有些例子讲的那样复杂,至于如何设置系统时间,我想通过上面的例子,自己也会了吧

7.在VFP中利用WN32API函数操作系统[控制面板]

  在VFP中,我们可以利用WIN32API的WinExec函数调用各种外部程序,下面是我整理的利用WinExec函数控制WIN95/98操作系统的[控制面板]各项功能(43种)的大全:

在VFP中代码中:

Declare integer WinExec in "kernel32" string,integer

*只需申明WinExec函数一次,即可选择如下控制面板各项功能:

1.启动控制面板

x=winexec('rundll32.exe shell32.dll,Control_RunDLL',9)

2.辅助选项 属性-键盘

x=winexec('rundll32.exe shell32.dll,Control_RunDLL access.cpl,,1',9)

3.辅助选项 属性-声音

x=winexec('rundll32.exe shell32.dll,Control_RunDLL access.cpl,,2',9)

4.辅助选项 属性-显示

x=winexec('rundll32.exe shell32.dll,Control_RunDLL access.cpl,,3',9)

5.辅助选项 属性-鼠标

x=winexec('rundll32.exe shell32.dll,Control_RunDLL access.cpl,,4',9)

6.辅助选项 属性-常规

x=winexec('rundll32.exe shell32.dll,Control_RunDLL access.cpl,,5',9)

7.添加/删除程序 属性-安装/卸载

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Appwiz.cpl,,1',9)

8.添加/删除程序 属性-Windows安装程序

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Appwiz.cpl,,2',9)

9.显示 属性-外观

x=winexec('rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,2',9)

10.显示 属性-设置

x=winexec('rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,3',9)

11.添加/删除程序 属性-启动盘

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Appwiz.cpl,,3',9)

12.显示 属性-背景

x=winexec('rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,0',9)

13.显示 属性-屏幕保护程序

x=winexec('rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,1',9)

14.Internet 属性-常规

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Inetcpl.cpl,,0',9)

15.Internet 属性-安全

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Inetcpl.cpl,,1',9)

16.Internet 属性-内容

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Inetcpl.cpl,,2',9)

17.Internet 属性-连接

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Inetcpl.cpl,,3',9)

18.Internet 属性-程序

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Inetcpl.cpl,,4',9)

19.Internet 属性-高级

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Inetcpl.cpl,,5',9)

20.区域设置 属性-区域设置

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Intl.cpl,,0',9)

21.区域设置 属性-数字

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Intl.cpl,,1',9)

22.区域设置 属性-货币

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Intl.cpl,,2',9)

23.区域设置 属性-时间

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Intl.cpl,,3',9)

24.区域设置 属性-日期

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Intl.cpl,,4',9)

25.游戏控制器-一般

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Joy.cpl,,0',9)

26.游戏控制器-高级

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Joy.cpl,,1',9)

27.鼠标 属性

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Main.cpl',9)

28.多媒体 属性-音频

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Mmsys.cpl,,0',9)

29.多媒体 属性-视频

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Mmsys.cpl,,1',9)

30.多媒体 属性-MIDI

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Mmsys.cpl,,2',9)

31.多媒体 属性-CD音乐

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Mmsys.cpl,,3',9)

32.多媒体 属性-设备

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Mmsys.cpl,,4',9)

33.调制解调器 属性

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Modem.cpl',9)

34.网络

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Netcpl.cpl',9)

35.密码 属性

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Password.cpl',9)

36.扫描仪与数字相机 属性

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Sticpl.cpl',9)

37.系统 属性-常规

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Sysdm.cpl,,0',9)

38.系统 属性-设备管理器

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Sysdm.cpl,,1',9)

39.系统 属性-硬件配置文件

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Sysdm.cpl,,2',9)

40.系统 属性-性能

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Sysdm.cpl,,3',9)

41.日期/时间 属性

x=winexec('rundll32.exe shell32.dll,Control_RunDLL timedate.cpl',9)

42.电源管理 属性

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Powercfg.cpl',9)

43.拨号属性

x=winexec('rundll32.exe shell32.dll,Control_RunDLL Telephon.cpl',9)

如何利用Win32 API函数隐藏和显示windows系统工具条

先声明FindWindow API函数

DECLARE INTEGER FindWindow IN WIN32API STRING,STRINGmHandle=FindWindow('Shell_TrayWnd','') &&取得系统工具条句柄
再声明ShowWindow API函数DECLARE INTEGER ShowWindow IN WIN32API integer,integer=ShowWindow(mHandle,0) &&隐藏* =ShowWindow(mHandle,1) &&显示如何利用Win32 API函数隐藏和显示其他运行中的程序DECLARE INTEGER FindWindow IN WIN32API STRING,STRINGmHandle=FindWindow(0,'计算器') &&取得"计算器"窗口句柄if mHandle=0  wait wind '没有运行"计算器"程序...'else  DECLARE INTEGER ShowWindow IN WIN32API integer,integer  =ShowWindow(mHandle,0)  &&隐藏"计算器"窗口  * =ShowWindow(mHandle,1) &&显示"计算器"窗口endi

如何利用Win32 API函数关闭其他运行中的程序

 上面讲的是如何利用Win32 API函数隐藏和显示其他运行中程序的窗口,

那么在VFP程序中有没有办法通过代码来关闭其他运行中的程序?下面的代

码就是通过SendMessage AIP函数向其他运行中的程序发出关闭命令,从而

达到关闭它的目的:

DECLARE INTEGER FindWindow IN WIN32API STRING,STRINGmHandle=FindWindow(0,'计算器') &&取得"计算器"窗口句柄

再声明SendMessage API函数:

DECLARE SendMessage IN WIN32API ; integer,integer,integer,integer=SendMessage(mHandle,16,0,0) &&参数16在这里代表Close命令。

 

 

vfp9.0调用API制作照相软件实例 PUBLIC WM_CAP_DRIVER_DISCONNECT PUBLIC hwndc,WM_CAP_SAVEDIB,WM_CAP_FILE_SET_CAPTURE_FILEA,WM_CAP_SEQUENCE,WM_CAP_STOP DECLARE INTEGER capCreateCaptureWindowA IN "AVICAP32.DLL" STRING lpszWindowName ,INTEGER dwStyle , INTEGER x, INTEGER Y, INTEGER nWidth ,INTEGER nHeight,INTEGER ParentWin,INTEGER nId DECLARE INTEGER SendMessage IN "user32" INTEGER HWND, INTEGER wmsg,INTEGER wpar1, INTEGER wpar2 DECLARE INTEGER SendMessage IN "user32" AS SendMessageA INTEGER HWND, INTEGER wmsg,INTEGER wpar1, STRING wpar2 *!* 显示: WM_USER = 1024 WM_CAP_START = WM_USER WM_CAP_STOP = WM_CAP_START + 68 WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10 WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11 WM_CAP_SAVEDIB = WM_CAP_START + 25 WM_CAP_GRAB_FRAME = WM_CAP_START + 60 WM_CAP_SEQUENCE = WM_CAP_START + 62 WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20 WM_CAP_SEQUENCE_NOFILE =WM_CAP_START+ 63 WM_CAP_SET_OVERLAY =WM_CAP_START+ 51 WM_CAP_SET_PREVIEW =WM_CAP_START+ 50 WM_CAP_SET_CALLBACK_VIDEOSTREAM = WM_CAP_START +6 WM_CAP_SET_CALLBACK_ERROR=WM_CAP_START +2 WM_CAP_SET_CALLBACK_STATUSA= WM_CAP_START +3 WM_CAP_SET_CALLBACK_FRAME= WM_CAP_START +5 WM_CAP_SET_SCALE=WM_CAP_START+ 53 WM_CAP_SET_PREVIEWRATE=WM_CAP_START+ 52 hWndC = capCreateCaptureWindowA('My Own Capture Window',1342177280,0,0,200,150,THISFORM.HWND ,0) &&显示大小 IF hWndC 0 SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0) SendMessage(hWndC, WM_CAP_SET_CALLBACK_ERROR, 0, 0) SendMessage(hWndC, WM_CAP_SET_CALLBACK_STATUSA, 0, 0) SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0) SendMessage(hWndC, WM_CAP_SET_SCALE, 1, 0) SendMessage(hWndC, WM_CAP_SET_PREVIEWRATE, 66, 0) SendMessage(hWndC, WM_CAP_SET_OVERLAY, 1, 0) SendMessage(hWndC, WM_CAP_SET_PREVIEW, 1, 0) * THISFORM.ACTIVATE ENDIF
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加菲猫的VFP

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值