在Visual FoxPro 中实现拨号上网功能,难点在于如何调用相应的WINDOWS API函数。与拨号网络相关的几个API函数需要复杂的结构类型的参数,在VFP帮助文件“程序员指南—访问API”中有相关说明,但较为简单,不足以解决问题,在此作进一步探讨。希望通过本文能解决实现拨号上网的实际问题,更希望通过这个例子帮助了解如何在VFP环境下调用参数复杂的API函数,以扩展VFP的应用。
因篇幅所限,本文仅论述关键部分,相关细节说明请参阅参考文件。
WINDOWS API中RasDial函数可实现拨号上网功能,可在MSDN帮助中查到,其参数简述如下:
其中结构RASDIALPARAMS描述如下:
以上RAS_MaxEntryName等预定义值,可从RAS.H与LMCONS.H中查出。难点在于dwSize值的确定:将结构中各变量字节长度累加应为1049字节,但将1049代入dwSize去调用RasDial函数却返回错误。启动VC++6.0定义了一个RASDIALPARAMS型结构变量后,发现其长度为1052字节,即最接近1049且能被4(DWORD所占字节数)整除的值。
分析至此,函数RasDial的各项参数已清楚,VFP中调用程序如下:
*!* 先注册函数
断线的程序如下:
注意以下几点:
* 指针参数(p或lp开头)通常按引用传递。NULL指针为特殊情况,其值为0,在VFP中对应值为0的INTEGER类型变量。句柄参数(H开头)对应INTERGER变量。
* API函数中空字符的ASCII码为0,即CHR(0)。
本文中的程序在Visual FoxPro 6.0下编译通过,在WINDOWS98、WINDOWS2000下运行成功。
因篇幅所限,本文仅论述关键部分,相关细节说明请参阅参考文件。
WINDOWS API中RasDial函数可实现拨号上网功能,可在MSDN帮助中查到,其参数简述如下:
DWORD RasDial( // 返回四字节整数,对应VFP的INTEGER型变量 LPRASDIALEXTENSIONS lpRasDialExtensions, // 指针,置NULL即可 LPCTSTR lpszPhonebook, // 指针,置NULL即可 LPRASDIALPARAMS lpRasDialParams, // 指针,指向参数结构变量RASDIALPARAMS DWORD dwNotifierType, // 四字节整数,置0即可 LPVOID lpvNotifier, // 指针,置NULL即可 LPHRASCONN lphRasConn // 指针,指向远程访问连接句柄HRASCONN。 // 调用RasDial前需先置HRASCONN为NULL ); |
其中结构RASDIALPARAMS描述如下:
typedef struct _RASDIALPARAMS { DWORD dwSize; // 4字节,值为本结构占用总字节数 // 调用此函数前必须给此变量赋值 TCHAR szEntryName[RAS_MaxEntryName + 1]; // 257字节,拨号网络电话簿中连接名, // 为空则在第一个MODEM端口上,用下述电话号码、用户名、密码建立连接 TCHAR szPhoneNumber[RAS_MaxPhoneNumber + 1]; // 129字节,电话号码 TCHAR szCallbackNumber[RAS_MaxCallbackNumber + 1]; // 129字节,回叫号码,置空 TCHAR szUserName[UNLEN + 1]; // 257字节,用户名 TCHAR szPassword[PWLEN + 1]; // 257字节,密码 TCHAR szDomain[DNLEN + 1] ; // 16字节,域名,置空 #if (WINVER >= 0x401) // 缺省情况下,WINVER=Ox400,无以下两项 DWORD dwSubEntry; DWORD dwCallbackId; #endif } RASDIALPARAMS; |
以上RAS_MaxEntryName等预定义值,可从RAS.H与LMCONS.H中查出。难点在于dwSize值的确定:将结构中各变量字节长度累加应为1049字节,但将1049代入dwSize去调用RasDial函数却返回错误。启动VC++6.0定义了一个RASDIALPARAMS型结构变量后,发现其长度为1052字节,即最接近1049且能被4(DWORD所占字节数)整除的值。
分析至此,函数RasDial的各项参数已清楚,VFP中调用程序如下:
*!* 先注册函数
DECLARE INTEGER RasDial in rasapi32 ; INTEGER , ; && lpRasDialExtensions INTEGER , ; && lpszPhonebook STRING @ , ; && 指向RasDialParams INTEGER , ; && dwNotifierType INTEGER , ; && lpvNotifier INTEGER @ && 指向hRasConn *!* 给结构变量RasDialParams中各变量赋初值 dwSize= CHR(28)+ CHR(4)+ CHR(0)+ CHR(0) && 即4*256+28=1052 szEntryName=REPLICATE(CHR(0), 257) && 不使用电话簿 sTemp="95963" && 服务器(INTERNET服务商或自建)的电话号码 TszPhoneNumber = sTemp +REPLICATE(CHR(0),129-LEN(sTemp)) && 补足129字节 szCallbackNumber=REPLICATE(CHR(0), 129) && 回拨号码,置空 sTemp="263" && 用户名 szUserName = sTemp +REPLICATE(CHR(0),257-LEN(sTemp)) && 补足字节数 sTemp="263" && 密码 szPassword = sTemp +REPLICATE(CHR(0),257-LEN(sTemp)) && 补足字节数 szDomain=REPLICATE(CHR(0), 16) && 如为自建服务器,可填入相应域名 *!* 生成结构变量RasDialParams初值 RasDialParams=dwSize+szEntryName+TszPhoneNumber+szCallbackNumber ; +szUserName+szPassword+szDomain +REPLICATE(CHR(0), 3) hRasConn=0 && 远程访问连接句柄,初值为0 DialResult=RasDial(0,0, @RasDialParams,0,0,@hRasConn) |
断线的程序如下:
DECLARE INTEGER RasHangUp in rasapi32 INTEGER HangResult=RasHangUp(hRasConn) |
注意以下几点:
* 指针参数(p或lp开头)通常按引用传递。NULL指针为特殊情况,其值为0,在VFP中对应值为0的INTEGER类型变量。句柄参数(H开头)对应INTERGER变量。
* API函数中空字符的ASCII码为0,即CHR(0)。
本文中的程序在Visual FoxPro 6.0下编译通过,在WINDOWS98、WINDOWS2000下运行成功。