在Visual FoxPro 中實(shí)現(xiàn)撥號(hào)上網(wǎng)功能,難點(diǎn)在于如何調(diào)用相應(yīng)的WINDOWS API函數(shù)。與撥號(hào)網(wǎng)絡(luò)相關(guān)的幾個(gè)API函數(shù)需要復(fù)雜的結(jié)構(gòu)類型的參數(shù),在VFP幫助文件“程序員指南—訪問API”中有相關(guān)說明,但較為簡單,不足以解決問題,在此作進(jìn)一步探討。希望通過本文能解決實(shí)現(xiàn)撥號(hào)上網(wǎng)的實(shí)際問題,更希望通過這個(gè)例子幫助了解如何在VFP環(huán)境下調(diào)用參數(shù)復(fù)雜的API函數(shù),以擴(kuò)展VFP的應(yīng)用。
因篇幅所限,本文僅論述關(guān)鍵部分,相關(guān)細(xì)節(jié)說明請(qǐng)參閱參考文件。
WINDOWS API中RasDial函數(shù)可實(shí)現(xiàn)撥號(hào)上網(wǎng)功能,可在MSDN幫助中查到,其參數(shù)簡述如下:
DWORD RasDial( // 返回四字節(jié)整數(shù),對(duì)應(yīng)VFP的INTEGER型變量
LPRASDIALEXTENSIONS lpRasDialExtensions, // 指針,置NULL即可
LPCTSTR lpszPhonebook, // 指針,置NULL即可
LPRASDIALPARAMS lpRasDialParams,
// 指針,指向參數(shù)結(jié)構(gòu)變量RASDIALPARAMS
DWORD dwNotifierType, // 四字節(jié)整數(shù),置0即可
LPVOID lpvNotifier, // 指針,置NULL即可
LPHRASCONN lphRasConn // 指針,指向遠(yuǎn)程訪問連接句柄HRASCONN。
// 調(diào)用RasDial前需先置HRASCONN為NULL
);
其中結(jié)構(gòu)RASDIALPARAMS描述如下:
typedef struct _RASDIALPARAMS {
DWORD dwSize; // 4字節(jié),值為本結(jié)構(gòu)占用總字節(jié)數(shù)
// 調(diào)用此函數(shù)前必須給此變量賦值
TCHAR szEntryName[RAS_MaxEntryName + 1];
// 257字節(jié),撥號(hào)網(wǎng)絡(luò)電話簿中連接名,
// 為空則在第一個(gè)MODEM端口上,用下述電話號(hào)碼、用戶名、密碼建立連接
TCHAR szPhoneNumber[RAS_MaxPhoneNumber + 1]; // 129字節(jié),電話號(hào)碼
TCHAR szCallbackNumber[RAS_MaxCallbackNumber + 1];
// 129字節(jié),回叫號(hào)碼,置空
TCHAR szUserName[UNLEN + 1]; // 257字節(jié),用戶名
TCHAR szPassword[PWLEN + 1]; // 257字節(jié),密碼
TCHAR szDomain[DNLEN + 1] ; // 16字節(jié),域名,置空
#if (WINVER >= 0x401) // 缺省情況下,WINVER=Ox400,無以下兩項(xiàng)
DWORD dwSubEntry;
DWORD dwCallbackId;
#endif
} RASDIALPARAMS;
以上RAS_MaxEntryName等預(yù)定義值,可從RAS.H與LMCONS.H中查出。難點(diǎn)在于dwSize值的確定:將結(jié)構(gòu)中各變量字節(jié)長度累加應(yīng)為1049字節(jié),但將1049代入dwSize去調(diào)用RasDial函數(shù)卻返回錯(cuò)誤。啟動(dòng)VC++6.0定義了一個(gè)RASDIALPARAMS型結(jié)構(gòu)變量后,發(fā)現(xiàn)其長度為1052字節(jié),即最接近1049且能被4(DWORD所占字節(jié)數(shù))整除的值。分析至此,函數(shù)RasDial的各項(xiàng)參數(shù)已清楚,VFP中調(diào)用程序如下:
*!* 先注冊(cè)函數(shù)
DECLARE INTEGER RasDial in rasapi32 ;
INTEGER , ; && lpRasDialExtensions
INTEGER , ; && lpszPhonebook
STRING @ , ; && 指向RasDialParams
INTEGER , ; && dwNotifierType
INTEGER , ; && lpvNotifier
INTEGER @ && 指向hRasConn
*!* 給結(jié)構(gòu)變量RasDialParams中各變量賦初值
dwSize= CHR(28)+ CHR(4)+ CHR(0)+ CHR(0) && 即4*256+28=1052
szEntryName=REPLICATE(CHR(0), 257) && 不使用電話簿
sTemp="95963" && 服務(wù)器(INTERNET服務(wù)商或自建)的電話號(hào)碼
TszPhoneNumber = sTemp +REPLICATE(CHR(0),129-LEN(sTemp)) && 補(bǔ)足129字節(jié)
szCallbackNumber=REPLICATE(CHR(0), 129) && 回?fù)芴?hào)碼,置空
sTemp="263" && 用戶名
szUserName = sTemp +REPLICATE(CHR(0),257-LEN(sTemp)) && 補(bǔ)足字節(jié)數(shù)
sTemp="263" && 密碼
szPassword = sTemp +REPLICATE(CHR(0),257-LEN(sTemp)) && 補(bǔ)足字節(jié)數(shù)
szDomain=REPLICATE(CHR(0), 16) && 如為自建服務(wù)器,可填入相應(yīng)域名
*!* 生成結(jié)構(gòu)變量RasDialParams初值
RasDialParams=dwSize+szEntryName+TszPhoneNumber+szCallbackNumber ;
+szUserName+szPassword+szDomain +REPLICATE(CHR(0), 3)
hRasConn=0 && 遠(yuǎn)程訪問連接句柄,初值為0
DialResult=RasDial(0,0, @RasDialParams,0,0,@hRasConn)
斷線的程序如下:
DECLARE INTEGER RasHangUp in rasapi32 INTEGER
HangResult=RasHangUp(hRasConn)
注意以下幾點(diǎn):
* 指針參數(shù)(p或lp開頭)通常按引用傳遞。NULL指針為特殊情況,其值為0,在VFP中對(duì)應(yīng)值為0的INTEGER類型變量。句柄參數(shù)(H開頭)對(duì)應(yīng)INTERGER變量。
* API函數(shù)中空字符的ASCII碼為0,即CHR(0)。
本文中的程序在Visual FoxPro 6.0下編譯通過,在WINDOWS98、WINDOWS2000下運(yùn)行成功