實現撥號上網

 實現撥號上網
  
  本例知識要點:
  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&gt;
  …
  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, &amp;n);
  n=dwSize/sizeof(RASENTRYNAME);
  RASENTRYNAME *entry=new RASENTRYNAME[n];
  if(entry)
  {
  entry[0].dwSize=sizeof(RASENTRYNAME);
  DWORD ret=RasEnumEntries(NULL,NULL,entry,&amp;dwSize, &amp;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,&amp;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&gt;=0){
  m_DialCombo.GetLBText(sel,params.szEntryName);
  TRACE(“%s/n”,params.szEntryName);
  BOOL p;
  RasGetEntryDialParams(NULL,¶ms,&amp;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&amp;0xFFF0)==IDM_ABOUTBOX);
  ASSERT((IDM_ABOUTBOX&lt;0xF000); &lt;br &gt;  
  CMenu *pSysMenu = GetSystemMenu(FALSE);
  
  if(pSysMenu!=NULL)
  {
  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  
  if(!strAboutMenu.IsEmpty())
  {
  pSysMenu-&gt;AppendMenu(MF_SEPARATOR);
  pSysMenu-&gt;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

發佈了10 篇原創文章 · 獲贊 2 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章