實現撥號上網
本例知識要點:
1. 遠程訪問服務(RAS)簡介
遠程訪問服務(Remote Access Service 簡稱RAS)是Windows 操作系統提供的系統服務之一,通過電話線可以使單獨的計算機接入網絡,或通過兩個RAS對撥使兩個局域網互連。此項服務的功能可以使遠程的計算機端點以較低的費用同網絡連接。
由於Windows操作系統的大量使用,遠程訪問服務功能也被廣泛應用,在許多具體的應用程序中,均已通過遠程訪問功能來實現對遠程的資源共享等功能。連通遠程訪問服務,只要從遠程客戶機撥通撥號網絡就可以了,執行掛斷就結束連接,鼠標操作Windows 98中的撥號網絡就可以直接連通和掛斷。但有些時候我們希望在應用程序中RAS撥號和掛斷對用戶不可見,那麼就需要相應的程序控制來實現RAS撥通和掛斷。
2. RasDial撥號函數
Windows 98提供了API函數RasDial,調用系統中建好的撥號網絡連接,完成RAS撥號,同時提供了API函數RasHangUp斷開連接。RasDial的原型如下:
DWORD RasDial(LPRASDIALEXTENSIONS lpRasDialExtensions,LPCTSTR lpszPhonebook,LPRASDIALPARAMS lpRasDialParams, DWORD dwNotifierType, LPVOID lpvNotifier, LPHRASCONN lphRasConn)
函數的第三個參數爲指向RASDIALPARAMS型結構體的指針,它提供了配置RAS撥號的參數:第五個參數爲撥號完成後執行的回調函數;第六個參數是LPHRASCONN型指針,撥號連接建立好之後將返回此連接的句柄;其他三個參數爲NULL即可。函數調用如果成功將返回零,否則返回錯誤代碼,此錯誤代碼的含義可以在頭文件Raserror.h中找到。
lpRasDialExtensions和lpszPhonebook:僅在Windows NT下有效,在Windows 95下,這兩個參數被忽略。
lpRasDialParams:這個參數很重要,它指向一個RASDIALPARAMS結構,RASDIALPARAMS型結構體包括7個數據成員:dwSize、szEntryName、szPhoneNumber、szCallNumber、szUserName、szPassWord和szDomain,分別解釋如下:
1) szSize:應設定爲sizeof(RASDIALPARAMS)。
2) szEntryName和szPhoneNumber:這兩個參數有聯繫,szEntryName可以指定要建立的連接,比方說“我的連接”等等,“我的連接”是用戶在Windows 98“撥號網絡”裏建立的連接。這時,Modem將撥打用戶在“我的連接”中設定的ISP號碼,此時szPhoneNumber成員設爲空字符串“”即可:如果用戶要在程序中自行指定要撥打的ISP號碼的話,szEntryNumber可以設定爲空字符串“”,此時應設置szPhoneNumber爲你的ISP號碼(163,169等)。
3) szCallBackNumber,szDomain:設爲空串“”即可。
4) szUserName,szPassWord:登陸用戶名和密碼。如169公用guest。
5) dwNotifierType:指定是窗口還是由回調函數來處理確認消息。通過確認消息用戶可以得到RasDial過程的當前狀態。如“正在打開端口”,“正在驗證用戶名和密碼”等。也可設爲NULL。
6) dwNoifier:指定處理確認消息的窗口或回調函數,也可設爲NULL。
7) lphRasConn:指向一個類型爲HRASCONN的變量。在調用RasDial前必須指定爲NULL,RasDial若成功返回,則將RAS連接的句柄存放於它所指向的變量中。用戶可以通過此句柄來斷開連接。
3. 撥號狀態
以指定窗口來處理確認消息爲例,說明如何得到撥號過程的當前狀態。
在處理確認消息的對話框類(或視圖類等)的實現代碼中加入:
Const UINT WM_RASEVENT = ::RegisterWindowMessageA(RASDIALEVENT)
在Message Map中手工加入消息映射:CDialInfo是用戶定義的對話框類名稱。
BEGIN_MESSAGE_MAP(CDialInfo, CDialog)
//AFX_MSG_MAP
……
ON_REGISTER_MESSAGE(WM_RASEVENT,OnRasDialEvent)//添加消息
//AFX_MSG_MAP
END_MESSAGE_MAP()
加入成員函數處理消息:
LRESULT CDialInfo::OnRasDialEvent(WPARAM wp,LPARAM lp)
{
RASCONNSTATE rasstate=(RASCONNSTATE)wp;
//用ListBox控件(ID爲IDC_BOHAOINFO)來顯示撥號狀態)
CListBox *info=(CListBox *)GetDlgItem(IDC_BOHAOINFO)
Switch(rasstate)
{
Case RASCS_OpenPort:
Info->AddString(_T(“打開端口。。。。。。”));
Break;
Case RASCS_Opened:
Info->AddString(_T(“端口已打開。”));
Break;
Case RASCS_ConnectDevice:
Info->AddString(_T(“連接設備。。。。。。”));
Break;
Case RASCS_DeviceConnected:
Info->AddString(_T(“設備已連接。”));
Break;
Case RASCS_Authenticate:
Info->AddString(_T(“驗證用戶及密碼”));
Break;
Case RASCS_Connected:
Info->AddString(_T(“已連接”));
Break;
Case RASCS_Disconnected:
Info->AddString(_T(“連接已斷開”));
Break;
Default:
Return (LRESULT)0;
}
}
4. 斷開連接
由於定義了類型爲HRASCONN的成員變量m_hRasConn來保存RAS連接的句柄。而且在調用RasDial時用指向m_hRasConn的指針作爲lpRasConn參數。因此在撥號連接斷開後應將m_hRasConn置爲NULL。
If(m_hRasConn!=NULL)
{
RasHangUp(m_hRasConn);
m_hRasConn = NULL;
::Sleep(2000);
}
上述代碼中的Sleep函數是必要的,它等待一定時間來斷開連接。如果不等待一段時間,計算機有可能無法正常關閉端口。導致下一次無法撥號,只有重新啓動Windows才能解決。
本例製作過程
1) 啓動Microsoft Visual C++6.0,單擊File下拉菜單下的“新建”命令,在“工程”標籤下選擇MFC AppWizard(exe)。
2) 在“工程名”文本框中輸入工程名Dialproc,在“位置”文本框中輸入工程地址,單擊OK按鈕進入新建應用程序嚮導。
3) 在嚮導第一步選擇Dialog Based(對話框),如圖11-1所示。第二到第四步接受默認設置。
圖11-1
4) 單擊“完成”按鈕,單擊項目工程區的類視圖ResourceView,展開Dialog中的IDD_DIALPRO_DIALOG對話框,清除對話框中的所有控件,並用控件工具欄中的工具增加如圖11-2所示的對話框。
圖11-2
IDD_DIALPRO_DIALOG對話框中的控件分別是:
文本框 標識:IDC_STATIC 標題:撥號連接
組合框 標識:IDC_DIALUP_COMBO
文本框 標識:IDC_STATIC 標題:用戶
編輯框 標識:IDC_USER_EDIT
文本框 標識:IDC_STATIC 標題:密碼
編輯框 標識:IDC_PASSWORD_EDIT
按鈕 標識:IDC_CONNECT_BUTTON 標題:連接
按鈕 標識:IDCANCEL 標題:退出
1.給新添加的控件增加成員變量
1)給控件IDC_DIALUP_COMBO增加成員變量,按住Ctrl鍵並雙擊該控件,彈出Add Member Variable對話框,在Member Variable Name中輸入m_DialCombo,Category列表框選擇Control,如圖11-3所示,單擊OK按鈕確認。
圖11-3
2)給控件IDC_USER_EDIT增加成員變量,按住Ctrl鍵雙擊該控件,彈出Add Member Variable對話框,在Member Variable Name中輸入m_UserID,Category列表框選擇Control,如圖11-4所示,單擊OK按鈕確認。
圖11-4
3)給控件IDC_PASSWORD_EDIT增加成員變量,按住Ctrl鍵雙擊該控件,彈出Add Member Variable對話框,在Member Variable Name中輸入m_Password,Category列表框選擇Control,如圖11-5所示,單擊OK按鈕確認。
圖11-5
2.給類添加成員函數
1)給類CDialprocDlg添加成員函數SetupDialupCombo()。
在dialprocDlg.h增加成員函數SetupDialupCombo()的說明:
#include <ras.h>
…
Public:
void SetupDialupCombo(void);
…
在dialprocDlg.cpp中編輯成員函數SetupDialupCombo()。
Void CDialprocDlg::SetupDialupCombo()
{
DWORD n;
DWORD dwSize=0;
m_DialCombo.ResetContent();
DWORD ret=RasEnumEntries(NULL,NULL,NULL,&dwSize, &n);
n=dwSize/sizeof(RASENTRYNAME);
RASENTRYNAME *entry=new RASENTRYNAME[n];
if(entry)
{
entry[0].dwSize=sizeof(RASENTRYNAME);
DWORD ret=RasEnumEntries(NULL,NULL,entry,&dwSize, &n);
for(DWORD i=0; i {
m_DialCombo.AddString(entry[i].szEntryName);
}
delete[] entry;
}
}
2) 打開ClassWizard,Class Name選擇CDialprocDlg,Object IDs 選擇IDC_CONNECT_BUTTON,Messages 選擇BN_CLICKED,單擊Add Function按鈕,在類CDialprocDlg增加成員函數OnConnectbutton();
void CDialprocDlg::OnConnectButton()
{
//TODO:Add your control notification handler code here
CWaitCursor wait;
RASDIALPARAMS params;
memset(¶ms,’/0’,sizeof(params));
param.dwSize=sizeof(params);
m_DialCombo.GetWindowText(params.szEntryName,sizeof(params.szEntryName)-1);
strcpy(params.szPhoneNumber,””);
m_UserID.GetWindowText(params.szUserName,sizeof(params.szUserName)-1);
m_Password.GetWindowText(params.szPassword,sizeof(params.szPassword)-1);
HRASCONN handle;
if(RasDial(NULL,NULL,¶ms,NULL,NULL,&handle)==0){
MessageBox(“已經連接成功,按確定將切斷電話”);
}
else
{
MessageBox(“您撥的計算機沒有應答,請稍候再撥”);
}
wait.Restore();
RasHangUp(handle);
}
3) 打開ClassWizard,Class Name選擇CDialprocDlg,Object IDs 選擇IDC_DIALUP_COMBO,Messages 選擇CBN_SELCHANGE,單擊Add Function按鈕,在類CDialprocDlg增加成員函數OnSelchangeDialupCombo();
void CDialprocDlg::OnSelchangeDialupCombo ()
{
//TODO:Add your control notification handler code here
RASDIALPARAMS params;
int sel;
memset(¶ms,’/0’,sizeof(params));
params.dwSize=sizeof(RASDIALPARAMS);
sel=m_DialCombo.GetCurSel();
if(sel>=0){
m_DialCombo.GetLBText(sel,params.szEntryName);
TRACE(“%s/n”,params.szEntryName);
BOOL p;
RasGetEntryDialParams(NULL,¶ms,&p);
m_UserID.SetWindowText(params.szUserName);
m_Password.SetWindowText(params.szPassword);
}
4) 打開ClassWizard,Class Name選擇CDialprocDlg,Object IDs 選擇CDialprocDlg,Messages 選擇CBN_SELCHANGE,單擊Add Function按鈕,在類CDialprocDlg自動增加成員函數OnInitDialog();
BOOL CDialprocDlg:;OnInitDialog()
{
CDialog::OnInitDialog();
//Add”About….”menu item to system menu.
//IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX);
ASSERT((IDM_ABOUTBOX<0xF000); <br >
CMenu *pSysMenu = GetSystemMenu(FALSE);
if(pSysMenu!=NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX, strAboutMenu);
}
}
//Set the icon for this dialog. The framework does this automatically
//when the application’s main window is not a dialog
SetIcon(m_hIcon, TRUE); //set big icon
SetIcon(m_hIcon, FALSE); //set small icon
// TODO:Add extra initialization here
SetupDialupCombo();
return TRUE; //return FALSE unless you set the focus to the control
}
3. 增加rasapi32.lib, 單擊Project菜單,選擇Setting,彈出Project Settings對話框,在Settings 對話框中選擇Link選項,在Object/Library modules中鍵入rasapi32.lib,如圖11-6 所示。
圖11-6
單擊Build下拉菜單的Excute dialproc.exe命令編譯執行文件,就可以在組合框中選擇機器上已有的連接進行撥號上網了。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1681526
本文轉自
http://blog.csdn.net/dehuadeng/archive/2007/07/06/1681526.aspx