轉(zhuǎn) Windows API 函數(shù)在VFP中的運用
2010年07月23日
Windows API 函數(shù)在VFP中的運用
VFP中常用WIN32API函數(shù)調(diào)用事例
我們在VFP編程時,為了彌補VFP本身功能的不足,常常會用到WIN32API函數(shù)
來對VFP的功能行擴展,例如取得系統(tǒng)信息、對注冊表進行操作等,但是由于
WIN32API函數(shù)是C++的數(shù)據(jù)結(jié)構(gòu)形式,在調(diào)用時與VFP的數(shù)據(jù)格式有所不同,因此在
調(diào)用時往往會產(chǎn)生問題,而目前的一些資料所介紹的大都是VB、DELPHI等語言如
何調(diào)用,對VFP如何調(diào)用介紹的比較少,更缺少具體的調(diào)用事例,下面我分幾次
介紹在VFP如何調(diào)用WIN32API函數(shù),并就一些常用的WIN32API函數(shù)作一介紹,由于
本人水平有限,所介紹的內(nèi)容,僅供您參考,也歡迎您在我的[請您留言]****同
探討:
.................一、VFP中調(diào)用WIN32API函數(shù)的格式
VFP中調(diào)用WIN32API函數(shù)的命令主要是:
DECLARE - DLL
CLEAR DLLS
1.DECLARE - DLL 它用于注冊外部 Windows 32 位動態(tài)鏈接庫 ( .DLL ) 中的
一個函數(shù)。
語法: DECLARE [cFunctionType] FunctionName IN LibraryName [AS AliasName]
.......[cParamType1 [@] ParamName1, cParamType2 [@] ParamName2, ...]
說明:
cFunctionType 指定該函數(shù)返回值的類型,其類型代碼如下:
SHORT 16 位整數(shù)
INTEGER 32 位整數(shù)
SINGLE 32 位浮點數(shù)
DOUBLE 64 位浮點數(shù)
STRING 字符串
FunctionName 指定要注冊使用的32位函數(shù)名。注意 FunctionName 區(qū)分大小寫。
如果該函數(shù)名與Visual FoxPro的保留字相同,應(yīng)使用AS參數(shù)另起
別名。
IN LibraryName 指定該函數(shù)所在的外部動態(tài)鏈接庫文件名,如果LibraryName為:
WIN32API時,VFP將依次查找KERNEL32.DLL、GDI32.DLL、
USER32.DLL、MPR.DLL及ADVAPI32.DLL等動態(tài)鏈接庫文件名。
AS AliasName 當API函數(shù)的名稱與Visual FoxPro的保留字相同時,另取
AliasName別名,另取的別名是不區(qū)分大小寫的。
cParameterType1 [@] ParamName1, cParameterType2 [@] ParamName2, ...
指定傳遞給被調(diào)用的32位.DLL函數(shù)的參數(shù)類型及參數(shù)名稱。其類
型代碼如FunctionType,如果要以傳址方法傳遞參數(shù)則應(yīng)在參數(shù)
名前加上@。
2.CLEAR DLLS 釋放所有利用DECLARE - DLL命令所裝入的動態(tài)鏈接庫。
....一旦申明WIN32API函數(shù)成功,就可以和一般函數(shù)一樣用 ?xxx()、=xxx()
來調(diào)用。
....下面以具體事例談?wù)剋in32api在Vfp中的運用:
1.利用win32api函數(shù)獲取指定磁盤的卷標:
Stor 0 to C_var,C_cd,C_qf
C_Var='c:\'
DECLARE INTEGER GetVolumeInformation IN Win32API STRING @, STRING @, INTEGER,;
INTEGER @, INTEGER @, INTEGER @, STRING @, INTEGER
xx=GetVolumeInformation(C_Var,"",20,@C_var,@C_cd,@C_qf,0,0)
CLEAR DLLS &&釋放所有利用DECLARE - DLL命令所裝入的動態(tài)鏈接庫。
xx0 獲取指定磁盤的卷標成功,反之則未成功。
C_var=指定磁盤的卷標,是個十進制的數(shù)值,與我們在DOS下看到的16進制不同。
C_cd=系統(tǒng)規(guī)定的文件名每一部分的長度,是個十進制的數(shù)值。
C_qf=文件名的大小寫標志,是個十進制的數(shù)值。
.....怎么樣很簡單吧,我們可以把獲取的磁盤卷標,用來加密我們的軟件,這樣
我們的 軟件就具有防拷貝的功能了。
2.在VFP中利用WN32API函數(shù)調(diào)用Outlook Express給你的程序建立發(fā)送
郵件的鏈接
..... 利用WN32API函數(shù)我們可以在VFP程序中,通過Label標簽或Command命令按
鈕來達到調(diào)用由系統(tǒng)默認的郵件收發(fā)軟件的目的,也就是建立所謂的鏈接功能,
在VFP代碼中:
DECLARE INTEGER ShellExecute IN shell32.DLL INTEGER HWND, STRING,STRING; ........lpszFile,STRING ,STRING ,INTEGER
*申明ShellExecute函數(shù)
lpszFile='mailto:cfyns@163.net'
*設(shè)定你需要發(fā)送的E-mail
=ShellExecute(0,0,lpszFile , 0,0,1)
*調(diào)用ShellExecute函數(shù)
.....一執(zhí)行=ShellExecute(),就會彈出書寫E-mail的窗體。
3.利用WIN32API函數(shù),防止同一程序被重復執(zhí)行。
.... 利用WIN32API中的FindWindow()函數(shù)取得待測窗口的handle(句柄),其
返回值不等于0,則表示該EXE文件已運行。
VFP代碼:
DECLARE INTEGER FindWindow IN WIN32API STRING,STRING
LOCAL cTitle
cTitle=_screen.caption
if FindWindow(0,cTitle)0
...=messagebox("程序已運行,無需重復!",48)
endif
注意:FindWindow()函數(shù)是取得窗口的caption,如果caption在程序的運行過
程中已經(jīng)改變,則達不到目的。
4.利用WIN32API函數(shù),關(guān)閉或重新啟動你的電腦
VFP代碼:
DECLARE INTEGER ExitWindowsEx IN USER32.DLL INTEGER , INTEGER
=ExitWindowsEx(1,1) &&關(guān)閉系統(tǒng)
如果:=ExitWindowsEx(2,1) &&重新啟動系統(tǒng)
如果:=ExitWindowsEx(0,0) &&進入登入者身份對話框
.5.在VFP中利用WN32API函數(shù)獲取當前所有邏輯驅(qū)動器
利用GetDriveType、GetLogicalDriveStrings函數(shù),我們可以很快找到
當前所有邏輯驅(qū)動器的根驅(qū)動器路徑。下面介紹兩種用法:
?。剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑?======
(1) 利用GetDriveType函數(shù):
Declare integer GetDriveType in "kernel32" String
Dgs=0
For I = 65 To 90
vName=Chr(I) + ":"
Lx=GetDriveType(vName)
Do Case
Case Lx=2
Dgs=Dgs+1
wait wind '這是個軟盤'
Case Lx=3
Dgs=Dgs+1
wait wind '這是個硬盤'
Case Lx=4
Dgs=Dgs+1
wait wind '這是個可移去式驅(qū)動器或網(wǎng)絡(luò)驅(qū)動器'
Case Lx=5
Dgs=Dgs+1
wait wind '這是個光盤'
Case Lx=6
Dgs=Dgs+1
wait wind '這是個RAM盤'
Endc
Endf
Wait wind '本機共有:'+str(Dgs)+'個驅(qū)動器'
?。剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑剑?br> (2) 利用GetLogicalDriveStrings函數(shù):
Declare integer GetLogicalDriveStrings in "kernel32" Long, string @cc
CC=Spac(81)
=GetLogicalDriveStrings(81,@cc)
*CC中返回了這樣的字符串"a:\ c:\ d:\ e:\ f:\ "每個名字都用一個NULL字符
分隔,在最后一個名字后面用兩個NULL表示中止。
X=(len(allt(cc))-1)/4 &&x中包含本機邏輯驅(qū)動器個數(shù)
*如果你想知道每個具體的驅(qū)動器名,則寫如下代碼:
Dime Dve(X)
For I=1 to X
Dve(I)=Subs(CC,1,3)
CC=Subs(CC,5)
Endf
*這樣在Dve這個數(shù)組里就是每個驅(qū)動器的盤符及":\" 了。
*如果你還想知道每個驅(qū)動器的類型,則再添加和改寫如下代碼:
Declare integer GetDriveType in "kernel32" String
Dime Dve(X,2)
For I=1 to X
Dve(I,1)=Subs(CC,1,3)
Lx=GetDriveType(Dve(I,1))
Do Case
Case Lx=2
Dve(I,2)='軟盤'
Case Lx=3
Dve(I,2)='硬盤'
Case Lx=4
Dve(I,2)='可移去式驅(qū)動器或網(wǎng)絡(luò)驅(qū)動器'
Case Lx=5
Dve(I,2)='光盤'
Case Lx=6
Dve(I,2)='RAM盤'
Endc
CC=Subs(CC,5)
Endf
.6.在VFP中利用SetLocalTime函數(shù)調(diào)用設(shè)置系統(tǒng)日期或時間
set date ansi
set century on
set hours to 24
*假定設(shè)置系統(tǒng)日期、時間為:1999,9,1
nDate=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)
*&&將轉(zhuǎn)換后的二進制字符連接
DECLARE SHORT SetLocalTime IN win32api STRING SystemTime
=SetLocalTime(cBuf) &&設(shè)置系統(tǒng)日期
Retu
*====以下是將十進制轉(zhuǎn)換為二進制的自定義函數(shù)
Function h2str
PARAMETERS Zhsz
PRIVATE Fhz
Fhz=Chr(Zhsz%256)+Chr(Zhsz/256)
RETURN Fhz
好了,就這么簡單,并不象有些例子講的那樣復雜,至于如何設(shè)置系統(tǒng)時間,
我想通過上面的例子,自己也會了吧
.... ... ... 待續(xù)
7.在VFP中利用WN32API函數(shù)操作系統(tǒng)[控制面板]
在VFP中,我們可以利用WIN32API的WinExec函數(shù)調(diào)用各種外部程序,下面是我整
理的利用WinExec函數(shù)控制WIN95/98操作系統(tǒng)的[控制面板]各項功能(43種)的大全:
在VFP中代碼中:
Declare integer WinExec in "kernel32" string,integer
*只需申明WinExec函數(shù)一次,即可選擇如下控制面板各項功能:
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.輔助選項 屬性-常規(guī)
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.顯示 屬性-設(shè)置
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 屬性-常規(guī)
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 屬性-內(nèi)容
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.區(qū)域設(shè)置 屬性-區(qū)域設(shè)置
x=winexec('rundll32.exe shell32.dll,Control_RunDLL Intl.cpl,,0',9)
21.區(qū)域設(shè)置 屬性-數(shù)字
x=winexec('rundll32.exe shell32.dll,Control_RunDLL Intl.cpl,,1',9)
22.區(qū)域設(shè)置 屬性-貨幣
x=winexec('rundll32.exe shell32.dll,Control_RunDLL Intl.cpl,,2',9)
23.區(qū)域設(shè)置 屬性-時間
x=winexec('rundll32.exe shell32.dll,Control_RunDLL Intl.cpl,,3',9)
24.區(qū)域設(shè)置 屬性-日期
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.多**** 屬性-設(shè)備
x=winexec('rundll32.exe shell32.dll,Control_RunDLL Mmsys.cpl,,4',9)
33.調(diào)制解調(diào)器 屬性
x=winexec('rundll32.exe shell32.dll,Control_RunDLL Modem.cpl',9)
34.網(wǎng)絡(luò)
x=winexec('rundll32.exe shell32.dll,Control_RunDLL Netcpl.cpl',9)
35.密碼 屬性
x=winexec('rundll32.exe shell32.dll,Control_RunDLL Password.cpl',9)
36.掃描儀與數(shù)字相機 屬性
x=winexec('rundll32.exe shell32.dll,Control_RunDLL Sticpl.cpl',9)
37.系統(tǒng) 屬性-常規(guī)
x=winexec('rundll32.exe shell32.dll,Control_RunDLL Sysdm.cpl,,0',9)
38.系統(tǒng) 屬性-設(shè)備管理器
x=winexec('rundll32.exe shell32.dll,Control_RunDLL Sysdm.cpl,,1',9)
39.系統(tǒng) 屬性-硬件配置文件
x=winexec('rundll32.exe shell32.dll,Control_RunDLL Sysdm.cpl,,2',9)
40.系統(tǒng) 屬性-性能
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)
注:WIN32API功能調(diào)用的函數(shù)還很多,比如象操作注冊表、MCI(Media Control
Interface)****控制接口等,有的是這方面介紹的資料較多,有的是調(diào)用過于
煩瑣,所有我不準備繼續(xù)下去了,歡迎對此有興趣的朋友,來E-Mail 探討。
如何利用Win32 API函數(shù)隱藏和顯示windows系統(tǒng)工具條
先聲明FindWindow API函數(shù)
DECLARE INTEGER FindWindow IN WIN32API STRING,STRING
mHandle=FindWindow('Shell_TrayWnd','') &&取得系統(tǒng)工具條句柄
再聲明ShowWindow API函數(shù)
DECLARE INTEGER ShowWindow IN WIN32API integer,integer
=ShowWindow(mHandle,0) &&隱藏
* =ShowWindow(mHandle,1) &&顯示
如何利用Win32 API函數(shù)隱藏和顯示其他運行中的程序
DECLARE INTEGER FindWindow IN WIN32API STRING,STRING
mHandle=FindWindow(0,'計算器') &&取得"計算器"窗口句柄
if mHandle=0
wait wind '沒有運行"計算器"程序...'
else
DECLARE INTEGER ShowWindow IN WIN32API integer,integer
=ShowWindow(mHandle,0) &&隱藏"計算器"窗口
* =ShowWindow(mHandle,1) &&顯示"計算器"窗口
endi
如何利用Win32 API函數(shù)關(guān)閉其他運行中的程序
上面講的是如何利用Win32 API函數(shù)隱藏和顯示其他運行中程序的窗口,
那么在VFP程序中有沒有辦法通過代碼來關(guān)閉其他運行中的程序?下面的代
碼就是通過SendMessage AIP函數(shù)向其他運行中的程序發(fā)出關(guān)閉命令,從而
達到關(guān)閉它的目的:
DECLARE INTEGER FindWindow IN WIN32API STRING,STRING
mHandle=FindWindow(0,'計算器') &&取得"計算器"窗口句柄
再聲明SendMessage API函數(shù):
DECLARE SendMessage IN WIN32API ; integer,integer,integer,integer
=SendMessage(mHandle,16,0,0) &&參數(shù)16在這里代表Close命令。
VFP中利用WIN32API函數(shù)實現(xiàn)系統(tǒng)文件夾列表
?。ū疚囊淹陡澹?
我們在編程中,有時需要用戶指定文件夾路徑,在VFP中我們往往會用GETDIR()來供用
戶選擇,但GETDIR()提供的文件夾列表是“選擇驅(qū)動器再在相應(yīng)的驅(qū)動器中選擇相應(yīng)文件
夾的界面”, 而目前我們常見的是采用類似資源管理器中“所有文件夾”界面: 最上層
是“桌面”,然后是“我的電腦”、驅(qū)動器A、C、D...等,見下圖:
也許有人會問,是不是又在介紹.OCX控件?如果不是在VFP中能實現(xiàn)這樣的文件夾
列表嗎?
要實現(xiàn)這樣的文件夾列表,我們得先了解三個WIN32API函數(shù):
1、FindWindow &&獲取窗口句柄
2、SHBrowseForFolder &&顯示文件夾夾列表窗
3、SHGetPathFromIDList &&獲取用戶選擇的文件夾名
☆FindWindow 這個API函數(shù)不用介紹了吧,在如何防止程序重復運行中介紹過。
☆SHBrowseForFolder 函數(shù)是實現(xiàn)文件夾列表功能的關(guān)鍵,在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;
或許您注意到了在這個函數(shù)里用到了一個BROWSEINFO類型,此類型包含了列表框使
用的一些參數(shù),比如:當前窗口句柄(hwndOwner)、從何根路徑開始展開文件夾(pidlRoot)、
目錄樹上方的標題(lpszTitle)等。
在VFP中能否聲明成功這個函數(shù)的關(guān)鍵是如何定義這個BROWSEINFO類型參數(shù),從這
個類型中我們可以看出它是有數(shù)值型和字符型混合組成的,而VFP沒有定義結(jié)構(gòu)類型的語
句,這也是很多API無法在VFP聲明和調(diào)用的愿因所在,那么我們又如何定義這個類型呢?
抓住問題的關(guān)鍵,忽略次要因素,很多問題往往就可以解決了,在這里我們只要告
訴這個函數(shù):列表框顯示在哪個主窗口里,其它的參數(shù)一概忽略,這個函數(shù)即可聲明成
功。那我們可以看出,在這里我們只要定義hwndOwner(數(shù)值型) 這一個參數(shù),然后
告訴SHBrowseForFolder 就可直接調(diào)用了。能行嗎?您只要一 試就知道了。
遺憾的是其它參數(shù)就只能忽略了,好在并不影響調(diào)用的結(jié)果,見上圖。
☆SHGetPathFromIDList 函數(shù)負責取回用戶在列表框中選擇的結(jié)果。當我們調(diào)用
SHBrowseForFolder API函數(shù)后,如果調(diào)用成功,則返回一個數(shù)值型的指針,這個指針
如果是NULL,表示用戶按了取消按鈕,否則返回一個非0的指針值供
SHGetPathFromIDList 函數(shù)使用,以取回具體的路徑名。
三個函數(shù)介紹完了,那么在VFP代碼中如何寫呢? 假如我們有一個表單,上面有一個
Command1按鈕和Label1標簽,我們就在 Command1.Click事件中這樣寫: ============================================================================
Declare integer FindWindow IN WIN32API String,String
Declare integer SHBrowseForFolder in "shell32.dll" integer @
*注意integer @ 中的這個“@”符號,千萬不可省略,否則無法調(diào)用成功,下同。
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預(yù)留512個空字符。
=SHGetPathFromIDList(pidl,@mpath) &&如果成功,用戶選擇的路徑名,將自動
*填入mpath變量中。
thisform.Label1.Caption=mpath &&顯示用戶選擇的路徑名。
endi
===========================================================================
這樣當我們一按Command1按鈕,即可看到上圖的列表了。
如果您看了上面的介紹,還不能達到目的,這里有實例下載。
本文介紹的代碼在WIN95/98、中文VFP3.0 - 6.0中通過。
/**/