请教如何自动拨号(100分)

  • 主题发起人 主题发起人 ghd
  • 开始时间 开始时间
G

ghd

Unregistered / Unconfirmed
GUEST, unregistred user!
请问在程序中如何让程序自动拨号某个已建好的连接,如果拨号成功,则回一值
 
在DELPHI程序中拨号上网


用MODEM拨号上网,仍是大多数个人网民选择上网的方式.如果能在我们的应用程序中启动拨号连接(如IE浏览器程序中的自动拨号功能),无疑将会方便我们的软件用户(不用再切换应用程序,运行拨号网络),提高我们的软件的友好性从而提高软件的竞争力.

在WIN9X下,如果安装了拨号网络,则在WINDOWS系统的系统目录System下将有两个拨号网络管理程序库RasApi32.DLL和RasApi16.DLL,我们可利用其中的函数来创建、修改拨号连接,并利用指定的拨号连接进行拨号上网。


一、新建拨号连接

当WIN9X系统中已经建立了拨号连接,则可利用现成的拨号连接。如果没有拨号连接,则需要新建一个拨号连接。RasAPI中提供了相应的函数,其函数名为RasCreatePhonebookEntryA,函数原型为:

function RasCreatePhonebookEntryA( hwnd : THandle;lpszPhonebook: pchar ) : DWORD;

stdcall; { 位于interface部分 }

function RasCreatePhonebookEntryA ; external ’Rasapi32.dll’;{ 位于implementation部分 }

参数:

hwnd(THandle):新建拨号连接窗口的父窗口的句柄,可以为TForm的Handle,为NIL表;Windows桌面(DeskTop)

lpszPhonebook(pchar):电话本名称

在Win9X下无作用

可设为空字符串

函数返回值:

0表示执行成功;否则为错误.


下面是一个新建拨号连接的例子.

{ 新建拨号连接 }

procedure TForm1.Button1Click(Sender: TObject);

var

dwResult : DWORD;

begin

//在当前窗口中新建拨号连接

dwResult := RasCreatePhonebookEntryA( handle

’’ );

if dwResult = 0 then

memo1.lines.add(’新建拨号连接成功!’)

else

memo1.lines.add(’新建拨号连接失败!’)

end;


二、修改指定拨号连接的属性

如果用户需要修改拨号连接的属性如电话号码、国家及区号、连接方式、服务器类型等,可以用RasAPI函数来实现,其函数名为RasEditPhonebookEntryA,函数原型为:

function RasEditPhonebookEntryA( hwnd : THandle; lpszPhonebook: pchar;

lpszEntryName: pchar ) : DWORD;stdcall; { 位于interface部分 }

function RasEditPhonebookEntryA; external ’Rasapi32.dll’;{ 位于implementation部分 }

参数:

hwnd(THandle):新建拨号连接窗口的父窗口的句柄,可以为TForm的Handle,为NIL表示

Windows桌面(DeskTop)

lpszPhonebook(pchar):电话本名称

在Win9X下无作用

可设为空字符串

lpszEntryName:( pchar):要修改的拨号连接的名称,如’163’、’169’等

函数返回值:

0表示执行成功;否则为错误.


下面是一个修改指定拨号连接属性的例子.

{ 修改指定拨号连接属性 }

procedure TForm1.Button2Click(Sender: TObject);

var

dwResult : DWORD;

strDialName : string;

begin

strDialName := ’163’;//拨号连接的名称设为163

//在当前窗口中指定修改拨号连接的属性

dwResult := RasEditPhonebookEntryA( handle

’’

PChar( strDialName ) );

if dwResult = 0 then

memo1.lines.add(’修改拨号连接’ + strDialName + ’成功!’)

else

memo1.lines.add(’修改拨号连接’ + strDialName + ’失败!’)

end;


三、获取当前系统中可用的拨号连接名称

为了让用户选择使用拨号连接进行拨号,我们需要获取系统中已建立的拨号连接的名称。在建立了拨号连接后,WIN9X将拨号连接的名称和属性写在了注册表中,我们可以从注册表中获取当前系统中可用的拨号连接名称及在Internet Explorer中设置的默认连接名称。

在注册表的HKEY_USERS/.Default/RemoteAccess/Addresses下,列出了已经在拨号网络中建立了的拨号连接的名称及其属性设置,其中各项目的名称即为可用的拨号连接的名称;各项目的值即为各拨号连接的属性设置.我们只要读出各项目的名称即可获取当前系统中可用的拨号连接名称.

如果在Internet Explorer中设置了默认连接名称(查看=》Internet选项=》连接=》连接=》设置=》使用以下拨号网络连接),则在注册表的HKEY_USERS/.Default/RemoteAccess下,有一个字符串类型的键值,键值名InternetProfile,其值即为Internet Explorer中设置的默认连接名称。


下面是一个获取当前系统中可用的拨号连接名称的例子.

{ 注意在Uses中增加Registry单元,用于操作注册表 }

{ 获取当前系统中可用的拨号连接名称 }

procedure TForm1.Button3Click(Sender: TObject);

var

registryTemp : TRegistry;

stringsTemp : TStringlist;

intIndex : integer;

begin

registryTemp := TRegistry.Create;

stringsTemp := TStringlist.Create;

with registryTemp do

begin

RootKey := HKEY_USERS;//根键设置为HKEY_USERS

//如果存在子键.Default/RemoteAccess/Addresses

if OpenKey(’.Default/RemoteAccess/Addresses’

false) then

GetValueNames( stringsTemp );//读出各项目的名称,即拨号连接名称

CloseKey;

end;

//当前系统中可用的拨号连接

memo1.lines.add( ’******************当前系统中有’+ IntToStr( stringsTemp.count )

+’个可用的拨号连接如下****************’);

for intIndex := 0 to stringsTemp.count - 1 do

memo1.lines.add( stringsTemp.strings[ intIndex ] );


//列出Internet Explorer中设置的默认连接名称

if registryTemp.OpenKey(’.Default/RemoteAccess’

false) then

memo1.lines.add( ’Internet Explorer中设置的默认连接名称为’ +

registryTemp.ReadString(’InternetProfile’) );


//释放内存

registryTemp.free;

stringsTemp.free;

end;


四、用指定的拨号连接拨号

以上的三个工作的目的就是为了拨号上网,现在就来看看如果用指定的拨号连接拨号上网。最好的方法就是调用WIN9X的拨号网络服务了,就是运行WIN9X下的现成程序。

在Delphi程序中可以用如下代码实现拨号上网:

winexec(’rundll32.exe rnaui.dll

RnaDial 163’

SW_SHOWNORMAL);

其中字符串中的最后一个参数“163”为拨号连接的名称。


下面是一个用指定的拨号连接拨号上网的例子.

{ 用指定的拨号连接拨号上网 }

procedure TForm1.Button4Click(Sender: TObject);

var

strDialName : string;

begin

strDialName := ’163’;//拨号连接的名称设为163

memo1.lines.add( ’******************用拨号连接’+ strDialName

+’实现拨号上网****************’);

winexec( PChar(’rundll32.exe rnaui.dll

RnaDial ’ + strDialName)

SW_SHOWNORMAL);

end;


以上程序在PWIN98+Delphi5.0下调试通过。
 
win2000底下怎么办
 
这是我定义的TDialer类(用于拨号网络拨号)
type
TDialer = class(TObject)
private
hRasConn : THRASCONN;
DeviceType : array of string;//记录调制解调器的类型
DeviceName : array of string;//记录调制解调器的名称
DeviceNumber : Integer;//记录调制解调器的数量
PhoneBookName : array of string;//记录已存在的拨号网络名称
PhoneBookNumber : Integer; //记录已存在的拨号网络数量
//密码保护,将信息转换成指定数字
function Encrypt(S : String) : String;
//function Decrypt(S : String) : String;
function CrunchName(S : String) : String;
//读取拨号网络
function LoadPhoneBook : Boolean;


1. //拨号
function Dial(EntryName, UserName, Password : String):Boolean;
传入参数:EntryName:已存在的拨号网络名称
UserName:用户名
Password:密码
传出参数:result = true 拨号成功
resutl = False 拨号失败
2.//自动拨号
function AutoDial : Boolean;
传出参数result = true 拨号成功
resutl = False 拨号失败
3.//修改拨号网络属性
function DoProperties(AHandle:THandle;EntriesName : string) : Boolean;
传入参数:AHandle:THandle:应用程序句柄
EntriesName : string:拨号网络名称
传出参数result = true 成功
resutl = False 失败
4.//新建拨号网络
function NewConnection(AHandle:THandle) : Boolean;
传入参数:AHandle:THandle:应用程序句柄
传出参数result = true 成功
resutl = False 失败
5.//断开连接
procedure Disconnected;
6.//保存拨号信息
procedure SaveINIFile(sEntryName,sUserName,sPassword : String);
传入参数:sEntryName,拨号网络名称
sUserName,用户名
sPassword密码
7.//获得调制解调器信息
function GetModemInfo : Boolean;

8.//获得上网IP地址
function GetIPAddress : string;
传出参数:传出ip地址的字符串
9.//获得拨号网络名称
function GetPhoneName : string;
传出参数:传出字符串字符是以','隔开例如string (163,169,236,)
以','隔开每个拨号网络名称

10.//获得拨号网络数量
function GetPhoneNumber : Integer;
传出参数:拨号网络的个数

11.//获得调制解调器名称
function GetModemName : string;
传出字符串字符是以','隔开例如string (163,169,236,)
以','隔开每个调制解调器名称

12, //获得调制解调器数量
function GetModemNumner : Integer;
传出参数:调制解调器的个数
unit Dialer2;

interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, IniFiles, Ras, ExtCtrls,ShellApi;

type
TDialer = class(TObject)
private
hRasConn : THRASCONN;
DeviceType : array of string;//记录调制解调器的类型
DeviceName : array of string;//记录调制解调器的名称
DeviceNumber : Integer;//记录调制解调器的数量
PhoneBookName : array of string;//记录已存在的拨号网络名称
PhoneBookNumber : Integer; //记录已存在的拨号网络数量
//密码保护,将信息转换成指定数字
function Encrypt(S : String) : String;
//function Decrypt(S : String) : String;
function CrunchName(S : String) : String;
//读取拨号网络
function LoadPhoneBook : Boolean;
public
//拨号
function Dial(EntryName, UserName, Password : String):Boolean;
//自动拨号
function AutoDial : Boolean;
//修改拨号网络属性
function DoProperties(AHandle:THandle;EntriesName : string) : Boolean;
//新建拨号网络
function NewConnection(AHandle:THandle) : Boolean;
//断开连接
procedure Disconnected;
//保存拨号信息
procedure SaveINIFile(sEntryName,sUserName,sPassword : String);
//获得调制解调器信息
function GetModemInfo : Boolean;
//获得上网IP地址
function GetIPAddress : string;
//获得拨号网络名称
function GetPhoneName : string;
//获得拨号网络数量
function GetPhoneNumber : Integer;
//获得调制解调器名称
function GetModemName : string;
//获得调制解调器数量
function GetModemNumner : Integer;
//property PhoneBookName : array of string;
//property PhoneBookNumber : Integer;
function GetUserName(DialerName : string) : string;
function GetPassword(DialerName : string) : string;
end;
implementation

{* * * * * * * * * * * * * *拨号核心程序 * * * * * * * * * * * * * * * * * * * * * * * * *}
//
function TDialer.Dial(EntryName, UserName, Password : String):Boolean;
var
rdParams : TRASDIALPARAMS;
dwRet : DWORD;
Buf : array [0..255] of Char;
begin
Result := false;
// setup RAS Dial Parameters
FillChar(rdParams, SizeOf(rdParams), 0);
rdParams.dwSize := SizeOf(TRASDIALPARAMS);
strCopy(rdParams.szUserName, PChar(UserName));
strCopy(rdParams.szPassword, PChar(Password));
strCopy(rdParams.szEntryName, PChar(EntryName));
rdParams.szPhoneNumber[0] := #0;
rdParams.szCallbackNumber[0] := '*';
rdParams.szDomain := '*';

//g_hWnd := Handle;
hRasConn := 0;;
dwRet := RasDialA(nil, nil, @rdParams, 0, nil, @hRasConn);
if dwRet <> 0 then
begin
RasGetErrorStringA(dwRet, @Buf[0], SizeOf(Buf));
exit;
//Disconnected;
end;
result:=true;
end;

//断开连接
procedure TDialer.Disconnected;
begin
if hRasConn <> 0 then
begin
RasHangUpA(hRasConn);
hRasConn := 0;
end;
end;

//程序启动自动拨号
function TDialer.AutoDial : Boolean;
var
IniFile : TIniFile;
aEntryName : String;
aUserName : String;
aPassword : String;
EntryName : string;
UserName : string;
FIniFileName : String;
rdParams : TRASDIALPARAMS;
dwRet : DWORD;
Buf : array [0..255] of Char;
begin
Result := False;
FIniFileName := Copy(Application.ExeName, 1,
Length(Application.ExeName) - 3) + 'ini';
IniFile := TIniFile.Create(FIniFileName);
try
aEntryName := IniFile.ReadString('Last', 'EntryName', '');
aUserName := IniFile.ReadString('Last', 'UserName', '');
EntryName := CrunchName(Trim(aEntryName));
UserName := CrunchName(Trim(aUserName));
aPassword := IniFile.ReadString('RAS_ENTRY_' + EntryName,
'USER_' + UserName, '*');
finally
IniFile.Free;
end;
//Result := Dial(aEntryName,aUserName,aPassword);
FillChar(rdParams, SizeOf(rdParams), 0);
rdParams.dwSize := SizeOf(TRASDIALPARAMS);
strCopy(rdParams.szUserName, PChar(aUserName));
strCopy(rdParams.szPassword, PChar(aPassword));
strCopy(rdParams.szEntryName, PChar(aEntryName));
rdParams.szPhoneNumber[0] := #0;
rdParams.szCallbackNumber[0] := '*';
rdParams.szDomain := '*';
//g_hWnd := Handle;
hRasConn := 0;;
dwRet := RasDialA(nil, nil, @rdParams, 0, nil, @hRasConn);
if dwRet <> 0 then
begin
RasGetErrorStringA(dwRet, @Buf[0], SizeOf(Buf));
exit;
//Disconnected;
end;
Result := True;
end;

//读取拨号网络电话本
function TDialer.LoadPhoneBook : Boolean;
var
Entries : array [0..15] of TRASENTRYNAME;
cb : DWORD;
cEntries : DWORD;
dwRet : DWORD;
Buf : array [0..127] of char;
I : Integer;
begin
Result := False;
setlength(PhoneBookName,20);
FillChar(Entries, SizeOf(Entries), 0);
Entries[0].dwSize := SizeOf(TRASENTRYNAME);
cb := SizeOf(Entries);
cEntries := 0;
dwRet := RasEnumEntriesA(NIL, NIL, @Entries[0], @cb, @cEntries);
if dwRet <> 0 then
begin
RasGetErrorStringA(dwRet, @Buf[0], SizeOf(Buf));
exit; //LogMessage(Buf);
end
else
begin
Result := True;
PhoneBookNumber := cEntries;
for I := 0 to cEntries - 1 do
PhoneBookName := Entries.szEntryName;
end;
end;

function TDialer.GetPhoneName : string;
var
I : Integer;
begin
LoadPhoneBook;
Result:='';
for I := 0 to PhoneBookNumber -1 do
Result := Result+PhoneBookName + ',';
end;

//建立新的拨号网络连接
function TDialer.NewConnection(AHandle:THandle) : Boolean;
var
dwRet : DWORD;
Buf : Array [0..127] of char;
begin
Result := False;
//dwRet := RasCreatePhonebookEntryA(NewForm.Handle,nil);
dwRet := RasCreatePhonebookEntryA(AHandle,nil);
LoadPhoneBook;
if dwRet <> 0 then
begin
RasGetErrorStringA(dwRet, @Buf[0], SizeOf(Buf));
exit;
//LogMessage(Buf);
end;
Result := True;
end;
//编辑修改拨号网络属性
//function DoProperties(NewForm : TForm; EntriesName : String) : Boolean;
function TDialer.DoProperties(AHandle:THandle;EntriesName : string) : Boolean;
var
dwRet : DWORD;
Buf : Array [0..127] of char;
begin
Result := False;
//dwRet := RasEditPhonebookEntryA(NewForm , nil, PChar(EntriesName));
dwRet := RasEditPhonebookEntryA(AHandle, nil, PChar(EntriesName));
if dwRet <> 0 then
begin
RasGetErrorStringA(dwRet, @Buf[0], SizeOf(Buf));
//LogMessage(Buf);
end
else
Result := True;
end;
//获得调制解调器信息
function TDialer.GetModemInfo : Boolean;
var
dwRet : DWORD;
RasConn : array[0..15] of TRASCONN;
cb : DWORD;
cConnection : DWORD;
Buf : array [0..127] of char;
I : Integer;
begin
Result := True;
SetLength(DeviceName,20);
SetLength(DeviceType,20);
FillChar(RasConn, SizeOf(RasConn), 0);
RasConn[0].dwSize := SizeOf(TRASCONN);
cb :=Sizeof(RasConn);
cConnection := 0;
dwRet := RasEnumConnectionsA(@RasConn,@cb,@cConnection);
if dwRet<>0 then
begin
RasGetErrorStringA(dwRet, @Buf[0], SizeOf(Buf));
Result := False;
//LogMessage(Buf);
end;
DeviceNumber := cConnection;
for I:=0 to cConnection-1 do
begin
DeviceType:= RasConn.szDeviceType;
DeviceName:= RasConn.szDeviceName;
end;
end;
//获得上网连接的IP地址
function TDialer.GetIPAddress : string;
begin
result := RasGetIPAddress;
end;
//保存拨号上网信息
procedure TDialer.SaveINIFile(sEntryName,sUserName,sPassword : String);
var
IniFile : TIniFile;
FIniFileName : String;
EntryName : String;
UserName : String;
begin
FIniFileName := Copy(Application.ExeName, 1,
Length(Application.ExeName) - 3) + 'ini';
IniFile := TIniFile.Create(FIniFileName);
IniFile.WriteString('Last', 'EntryName', sEntryName);
IniFile.WriteString('Last', 'UserName', sUserName);
IniFile.WriteString('Last', 'Password', Encrypt(sPassword));
//if SavePWCheckBox.Checked then begin
// IniFile.WriteString('最后一次上网的信息', ' Password', EnCrypt(PasswordEdit.Text));
// IniFile.WriteString('最后一次上网的信息', 'SavePW', '1');
EntryName := CrunchName(Trim(sEntryName));
UserName := CrunchName(Trim(sUserName));
if (UserName <> '') and (EntryName <> '') then
IniFile.WriteString('RAS_ENTRY_' + EntryName,
'USER_' + UserName,
EnCrypt(sPassword))
//end
else begin
IniFile.WriteString('Last', 'Password', '');
IniFile.WriteString('Last', 'SavePW', '0');
end;
IniFile.Free;
end;
//
function TDialer.Encrypt(S : String) : String;
type
PWORD = ^WORD;
var
Len : Integer;
I : Integer;
V : DWORD;
P : PChar;
Buffer : String[255];
begin
Buffer := S;
Len := Length(Buffer) + 1;
if (Len mod 2) <> 0 then
Inc(Len);
if Len < 10 then
Len := 10;
I := Length(Buffer);
if I = 0 then
Buffer := IntToStr(GetTickCount)
else
while Length(Buffer) < 10 do
Buffer := Buffer + Buffer;
SetLength(Buffer, I);
Result := '';
P := PChar(@Buffer[0]);
for I := 1 to Len div 2 do begin
V := 34567 + PWORD(P)^;
P := P + 2;
Result := Result + Format('%5.5d', [V]);
end;
end;

{function TDialer.Decrypt(S : String) : String;
type
PWORD = ^WORD;
var
Buffer : String;
PW : String[255];
P : PWORD;
I : Integer;
V : Integer;
begin
PW := ' ';
P := PWORD(@PW[0]);
I := 1;
while I <= Length(S) do begin
Buffer := Copy(S, I, 5);
I := I + 5;
V := StrToInt(Buffer) - 34567;
P^ := V;
Inc(P);
end;
Result := PW;
end;}
function TDialer.CrunchName(S : String) : String;
var
I : Integer;
begin
Result := '';
for I := 1 to Length(S) do begin
case S of
' ' : Result := Result + '_';
'=' : Result := Result + '/-';
'@' : Result := Result + '/A';
'_' : Result := Result + '/_';
'/' : Result := Result + '//';
else
Result := Result + S;
end;
end;
end;

function TDialer.GetPhoneNumber: Integer;
begin
LoadPhoneBook;
Result:=PhoneBookNumber;
end;

function TDialer.GetModemName: string;
var
I : Integer;
begin
GetModemInfo;
Result := '';
for I := 0 to DeviceNumber -1 do
Result := Result + DeviceName + ',';
end;

function TDialer.GetModemNumner: Integer;
begin
GetModemInfo;
Result := DeviceNumber;
end;

function TDialer.GetUserName(DialerName : string): string;
var
iReturn : Integer;
RASParams : TRasDialParams;
lpfp : LongBool;
begin
//FillChar(RASParams,Sizeof(TRasDialParams),0);
RASParams.dwSize := Sizeof(TRasDialParams);
StrPCopy(RASParams.szEntryName,DialerName);
lpfp := False;
iReturn := RasGetEntryDialParamsA(nil,@RASParams,@lpfp);
result :=RASParams.szUserName;
end;

function TDialer.GetPassword(DialerName: string): string;
var
iReturn : Integer;
RASParams : TRasDialParams;
lpfp : LongBool;
begin
//FillChar(RASParams,Sizeof(TRasDialParams),0);
RASParams.dwSize := Sizeof(TRasDialParams);
StrPCopy(RASParams.szEntryName,DialerName);
lpfp := False;
iReturn := RasGetEntryDialParamsA(nil,@RASParams,@lpfp);
result :=RASParams.szPassword;
end;

end.
 
gangfeng 的这个类好像很好的,我先仔细看看:)
 
后退
顶部