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:
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 |
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
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
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
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, Introduction, RasDialParams, RasEnumEntries, RasHangUp, RasConnState