PlatformVB

RasDial

The RasDial function dials an entry or the parameters as specified in a RASDIALPARAMS structure.  The RasDial function can be called asynchronously or synchronously. It does NOT display any user interface while dialling - it's up to you to prompt the user as you see fit. 

The RasDail function looks like this:

Public Declare Function RasDial _
      Lib "rasapi32.dll" Alias "RasDialA" _
      (lpRasDialExtensions As Any, _
       ByVal lpszPhonebook As String, _
       lpRasDialParams As Any, _
       ByVal dwNotifierType As Long, _
       ByVal hwndNotifier As Long, _
       lphRasConn As Long) _
As Long

If the function is successful it returns 0, else use the VBRasErrorHandler function to get an error description.

Parameters:

lpRasDialExtensions
is a RASDIALEXTENSIONS structure.  This can only be used on NT4 or windows 2000. (see the platform SDK for further details)  For windows 95 and 98, use ByVal 0& . On Nt4 and windows 2000 you can also use ByVal 0& if you do not wish to specify a RASDIALEXTENSION structure.
lpszPhonebook
a string that specifies the phonebook to use for windows NT and 2000.  To use the deafult phonebook, and on windows 95/98, use vbNullString for this parameter.
lpRasDialParams
A RASDIALPARAMS structure.  For compatibility across windows platforms, the examples here pass an array of bytes for this parameter.  See the examples below for more details and also make sure you have read the RasDialParams page.
dwNotifierType
A long that, together with the hwndNotifier parameter, specifies whether the call is asynchronous or  synchronous. See below for further details.
hwndNotifier 
specifies a windows hwnd to recieve connecting messages, OR the address of a callback function to recieve connecting messages OR 0& not to recieve connecting messages.
lphRasConn 
This returns the handle to the connection.  If the returned value is non zero, you must eventually HangUp the connection, even if the connection failed.  Also useful when getting connection status etc.

Synchronous or Asynchronous dialling.

The RasDial function can operate asynchronously or synchronously.  If synchronous, then the function returns after the connection is established or fails.  In other words your line of code will not finish executing till the function returns, so your application is non responsive during this time and the user cannot cancel the dialling.  If asynchronous, the function returns immediately and you can use a callback function or subclass your window to recieve connecting messages.  This allows your code to continue and makes it possible for you to allow the user to cancel the operation if you so desire.

To specify asynchronous or synchronous dialling, you specify the values of the dwNotifierType and hwndNotifier accordingly.  To use a callback function, you need to add a RasDialFunc, RasDialFunc1, or RasDialFunc2 type procedure to your application. You can then use the AddressOf function in VB to specify your callback function's address for the hwndNotifier parameter.

The following logic table depicts the options for the two parameters:

dwNotifierType hwndNotifier  description
doesn't matter, (use 0&) 0& no callback messages are recieved, regardless of the dwNotifierType parameter.  Call is synchronous.
&HFFFFFFFF a windows hWnd
eg:
Form1.hWnd
You need to subclass the form to get the messages.  Call is asynchronous
0 Address of a RasDialFunc procedure Your RasDialFunc procedure gets the connecting messages.  Call is asynchronous.  
NOT recommended for VB6
1 Address of a RasDialFunc1 procedure Your RasDialFunc1 procedure gets the connecting messages.  Call is asynchronous 
NOT recommended for VB6
2 Address of a RasDialFunc2 procedure For windows NT and 2000 only.

Your RasDialFunc2 procedure gets the connecting messages.  Call is asynchronous 
NOT recommended for VB6

 

Unfortunately due to limitations of VB's threading model, you will possibly encounter crashes when using asynchronous dialing unless you use a form and subclass it to recieve the messages.  See below for example of using a form's hwnd and subclassing.

 

NOTE: All the asynchronous callback methods will stop recieving messages once the connection is established, hangup, or fails. That is, if a connection is established, the callback will NOT recieve any subsequent messages such as disconnected. 

A RasDialFunc procedure looks like this:

Sub RasDialFunc(ByVal unMsg As Long,  _
	ByVal rasConnectionState As Long, 
         ByVal dwError As Long)
   
    ' do stuff here, such as check for errors
    ' or check the rasConnectionState

End Sub

 

Examples:

Simple Syncronous Dial

The following sample does a simple synchronous dial.  The function returns the handle to the connection.  Remember you have to eventually Hangup the connection if the connection's handle value is non-zero .  This function also use the VBRasGetEntryDialParams function (from the RasDialParams page).

You can call it like so:

Dim hConn as Long
hConn = VBSyncronousDial(vbNullString, "My Connection")

  

Function VBSyncronousDial(strPhonebook As String, _
                              strEntryName As String) As Long
   Dim rtn As Long
   Dim b() As Byte
   Dim lngHConn As Long
   
   rtn = VBRasGetEntryDialParams(b, strPhonebook, strEntryName)
   
   'todo: check if rtn = 0 else handle error
   
   ' note how code pauses on next line
   ' until connection established or fails

   rtn = RasDial(ByVal 0&, strPhonebook, b(0), 0&, 0&, lngHConn)
   
   'todo: check if rtn = 0 else handle error
   
   VBSyncronousDial= lngHConn
End Function

 

Modifying the dialling parameters

The following sample performs a  synchronous dial, however, this time we will modify the dialling parameters.  Note: this sample calls on code from the RasDialParams page

   Dim rtn As Long
   Dim b() As Byte
   Dim myDialParams As VBRasDialParams
   Dim lngHConn As Long
   Dim strPhonebook as String

   With myDialParams
      .EntryName = "My Connection"
      .UserName = "Someone"
      .Password = "SECRET"
      .PhoneNumber = "111 123456789"
   End With
   
   rtn = VBRasDialParamsToBytes(myDialParams, b)
   'todo: check if rtn = True else handle error
   
   ' note how code pauses on next line
   ' until connection established or fails

   rtn = RasDial(ByVal 0&, strPhonebook, b(0), 0&, 0&, lngHConn)
   'todo: check if rtn = 0 else handle error

 

 

Simple Asyncronous Dial

The following sample does a simple asynchronous dial.  The function returns the handle to the connection.  Remember you have to eventually Hangup the connection if the connection's handle value is non-zero .  This function also use the VBRasGetEntryDialParams function (from the RasDialParams page).

You can call it like so:

Dim hConn as Long
hConn = VBAsyncronousDial(vbNullString, "My Connection")

  Note this code requires you to subclass a form:

 

In your form, have this code:

Private Sub Form_Load()
   Call Hook(Me.hwnd)
End Sub

Public Sub Form_Unload(Cancel As Integer)
   UnHook
End Sub

Function VBAsyncronousDial(strPhonebook As String, _
                              strEntryName As String) As Long
   Dim rtn As Long
   Dim b() As Byte
   Dim lngHConn As Long
   
   rtn = VBRasGetEntryDialParams(b, strPhonebook, strEntryName)
   
   'todo: check if rtn = 0 else handle error
   
   rtn = RasDial(ByVal 0&, strPhonebook, b(0), _
                     &HFFFFFFFF, Me.hwnd, lngHConn)
   
   'todo: check if rtn = 0 else handle error
   
   VBAsyncronousDial = lngHConn
End Function

 

and you need this code in a standard module to do the subclassing and recieve the window messages.

 

Option Explicit

Private Declare Function RegisterWindowMessage Lib "user32" Alias _
   "RegisterWindowMessageA" (ByVal lpString As String) As Long

Private Const RASDIALEVENT = "RasDialEvent"
Private Const WM_RASDIALEVENT = &HCCCD&
Private m_RasMessage As Long

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
   ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _
   ByVal lParam As Any) As Long

Private Declare Function CallWindowProc Lib "user32" Alias _
   "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, _
   ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Declare Function SetWindowLong Lib "user32" Alias _
   "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, _
   ByVal wNewWord As Long) As Long

Private Declare Function GetWindowLong Lib "user32" Alias _
   "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long

Private Const GWL_WNDPROC = (-4)

Private m_hWnd As Long
Private m_lpPrev As Long


Public Sub Hook(ByVal hwnd As Long)
   If m_hWnd Then Call UnHook()
   m_hWnd = hwnd
   m_lpPrev = SetWindowLong(m_hWnd, GWL_WNDPROC, AddressOf WindowProc)
   
   'register RasMEvent Message
   If m_RasMessage = 0 Then
      m_RasMessage = RegisterWindowMessage(RASDIALEVENT)
      If m_RasMessage = 0 Then m_RasMessage = WM_RASDIALEVENT
   End If
   
End Sub

Public Sub UnHook()
   If m_hWnd Then
      Call SetWindowLong(m_hWnd, GWL_WNDPROC, m_lpPrev)
      m_hWnd = 0
   End If
End Sub

Private Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, _
   ByVal wParam As Long, ByVal lParam As Long) As Long
   If uMsg = m_RasMessage Then
      Call RasDialFunc(uMsg, wParam, lParam)
   End If
   WindowProc = CallWindowProc(m_lpPrev, hwnd, uMsg, wParam, lParam)
End Function


Sub RasDialFunc(ByVal unMsg As Long, _
       ByVal rasConnectionState As Long, ByVal dwError As Long)
   
   ' do stuff here, such as check for errors
   ' or check the rasConnectionState
   'Debug.Print hRasConn, Hex$(rasConnectionState), dwError
   If rasConnectionState = RASCS_Connected Then
      '  Debug.Print "connected"
   ElseIf rasConnectionState = RASCS_disconnected Then
      '  Debug.Print "disconnected"
   End If
   
   If dwError <> 0 Then
      Debug.Print(VBRASErrorHandler(dwError))
      '  Debug.Print "disconnected"
   End If
   '  Warning !!  if an error occurs or you get disconnected
   ' you should still call RasHangUp 
End Sub

  

The  rasConnectionState  parameter of the RasDialFunc is a long that tell us the connection state. For further information see the RasConnState enumeration, and also see the platform SDK for information about the RasDialFunc1 procedure

 

Remember that if the any of the dial methods above returns a non zero connection handle, you must hangup that connection even if the connection fails. In asynchronous dialling you can hangup the connection before the connection is established.

 

 

See Also: Contents, IntroductionRasDialParams, RasEnumEntries, RasHangUp, RasConnState