C++ Builder Snippets  

Einwahl über eine existierende DFÜ-Verbindung, Trennen der Verbindung:

//---------------------------------------------------------------------------
// Verbindung mit dem überg. Namen herstellen:
//---------------------------------------------------------------------------
// Beispielaufruf:
//
// if(!RasDial("Meine Verbindung"))
//   ShowMessage("Error !");
//---------------------------------------------------------------------------

#pragma warn -dup
#define WINVER 0x400
#include <ras.h>

bool RasDial(AnsiString slEntry)
{
  RASDIALPARAMS pRasDialParams;
  BOOL blPw = true;
  HRASCONN hndConnection = NULL;
  DWORD dwError = 0;
  // RASDIALPARAMS-Struktur füllen:
  ::ZeroMemory(&pRasDialParams, sizeof(pRasDialParams));
  pRasDialParams.dwSize = sizeof(RASDIALPARAMS);
  strcpy(pRasDialParams.szEntryName, slEntry.c_str());
  if(RasGetEntryDialParams(NULL, &pRasDialParams, &blPw))
    return false;
  if(!blPw) // falls Kennwort nicht gespeichert, fragen:
  {
    AnsiString slPw = InputBox("Daten nicht vollständig",
      "Kennwort für die Verbindung \"" + slEntry + "\" eingeben:","");
    if(slPw !=EmptyStr) strcpy(pRasDialParams.szPassword, slPw.c_str());
    else return false;
  }
  // Einwählen_
  dwError = ::RasDial(NULL, NULL, &pRasDialParams, 0,
    NULL, &hndConnection);
  if(dwError) return false;
  else return true;
}

//---------------------------------------------------------------------------
// Alle Verbindungen trennen
//---------------------------------------------------------------------------
bool HangUpAllConnections(void)
{
  bool blFound = false;
  DWORD dwSizeBuf = 0;
  DWORD dwConnections = 0;
  RASCONN stRasConn;
  stRasConn.dwSize = sizeof(stRasConn);

  RasEnumConnections(&stRasConn, &dwSizeBuf, &dwConnections);
  if(dwConnections <= 0) return false;

  RASCONN *lpRasConn = new RASCONN[dwConnections];
  lpRasConn->dwSize = sizeof(*lpRasConn);
  RasEnumConnections(lpRasConn, &dwSizeBuf, &dwConnections);
  for(DWORD i = 0; i < dwConnections; i++)
    RasHangUp(lpRasConn[i].hrasconn);
  delete []lpRasConn;
  return blFound;
}

Nachtrag vom Woodym im RAD-Forum vom 16.03.2002 zum Anzeigen der Statusmeldungen während der Herstellung der Verbindung:

"ich hasse windows-botschaften, da der code jegliche portabilität auf andere systeme erschweren. in dem ausführlichen quelltext der dfü-verbindung wird aber eine sehr schöne funktion darüber realisiert... man sieht wie der status der dfü-verbindung ist. das ganze geht aber auch ohne windows-botschaften...."

Nachvolgend wird beschrieben, wie diese Funktionalität implementiert werden kann. Zu beachten ist allerdings, dass der Rückgabewert der RasDial() bei dieser Lösung nun keine Aussage darüber beinhaltet, ob die Verbindung hergestellt werden konnte. Dies muss der Programmierer mit Hilfe von RasGetConnectStatus() selbst überprüfen. Desweiteren verursachte die Callback unter Windows 2000 bei ausgeschaltetem Modem reproduzierbare Programmabstürze. Aus diesem Grund wird in TRasObject auf etwas umständlichere Weise mit Messages gearbeitet.
//---------------------------------------------------------------------------
// in der Header-Datei (ausserhalb der Form-Klassendeklaration !)
// Deklaration der Funktion für die Anzeige der Einwahl-Statusmeldungen
void WINAPI RasDialFunc(UINT unMsg, int rasconnstate, DWORD dwError);

//---------------------------------------------------------------------------
// Verbindung mit dem überg. Namen herstellen:
//---------------------------------------------------------------------------
// Beispielaufruf:
//
// RasDial("Meine Verbindung", RasDialFunc);
//---------------------------------------------------------------------------
#pragma warn -dup
#define WINVER 0x400
#include <ras.h>

bool RasDial(AnsiString slEntry, void* StatusFunc)
{
  RASDIALPARAMS pRasDialParams;
  BOOL blPw = true;
  HRASCONN hndConnection = NULL;
  DWORD dwError = 0;
  // RASDIALPARAMS-Struktur füllen:
  ::ZeroMemory(&pRasDialParams, sizeof(pRasDialParams));
  pRasDialParams.dwSize = sizeof(RASDIALPARAMS);
  strcpy(pRasDialParams.szEntryName, slEntry.c_str());
  if(RasGetEntryDialParams(NULL, &pRasDialParams, &blPw))
    return false;
  if(!blPw) // falls Kennwort nicht gespeichert, fragen:
  {
    AnsiString slPw = InputBox("Daten nicht vollständig",
      "Kennwort für die Verbindung \"" + slEntry + "\" eingeben:","");
    if(slPw !=EmptyStr) strcpy(pRasDialParams.szPassword, slPw.c_str());
    else return false;
  }
  // Einwählen_
  dwError = ::RasDial(NULL, NULL, &pRasDialParams, 0,
    StatusFunc, &hndConnection);
  if(dwError) return false;
  else return true;
}

//---------------------------------------------------------------------------
// Callback-Funktion (wird bei Statusänderungen automatisch aufgreufen)
//---------------------------------------------------------------------------
void WINAPI RasDialFunc(UINT unMsg, int rasconnstate, DWORD dwError)
{
  AnsiString slStatus;
  switch(rasconnstate)
  {
    case RASCS_Connected:
      slStatus = "Successfully connected to remote server !";
      break;
    case RASCS_Disconnected:
      slStatus = "Disconnected";
      break;
    case RASCS_OpenPort:
      slStatus = "Opening the port...";
      break;
    case RASCS_PortOpened:
      slStatus = "Port has been opened successfully";
      break;
    case RASCS_ConnectDevice:
      slStatus = "Connecting to the device...";
      break;
    case RASCS_DeviceConnected:
      slStatus = "The device has connected successfully.";
      break;
    case RASCS_AllDevicesConnected:
      slStatus = "All devices in the device chain have successfully connected.";
      break;
    case RASCS_Authenticate:
      slStatus = "Verifying the user name and password...";
      break;
    case RASCS_AuthNotify:
      slStatus = "An authentication event has occurred.";
      break;
    case RASCS_AuthRetry:
      slStatus = "Requested another validation attempt with a new user.";
      break;
    case RASCS_AuthCallback:
      slStatus = "Server has requested a callback number.";
      break;
    case RASCS_AuthChangePassword:
      slStatus = "The client has requested to change the password";
      break;
    case RASCS_AuthProject:
      slStatus = "Registering your computer on the network...";
      break;
    case RASCS_AuthLinkSpeed:
      slStatus = "The link-speed calculation phase is starting...";
      break;
    case RASCS_AuthAck:
      slStatus = "An authentication request is being acknowledged.";
      break;
    case RASCS_ReAuthenticate:
      slStatus = "Reauthentication (after callback) is starting. ";
      break;
    case RASCS_Authenticated:
      slStatus = "The client has successfully completed authentication.";
      break;
    case RASCS_PrepareForCallback:
      slStatus = "The line is about to disconnect for callback.";
      break;
    case RASCS_WaitForModemReset:
      slStatus = "Delaying to give the modem time to reset for callback.";
      break;
    case RASCS_WaitForCallback:
      slStatus = "Waiting for an incoming call from server.";
      break;
    case RASCS_Projected:
      slStatus = "Projection result information is available.";
      break;
    case RASCS_StartAuthentication:
      slStatus = "User authentication is being initiated or retried.";
      break;
    case RASCS_CallbackComplete:
      slStatus = "Client has been called back and is about to resume authentication.";
      break;
    case RASCS_LogonNetwork:
      slStatus = "Logging on to the network...";
      break;
    case RASCS_SubEntryConnected:
      slStatus = "Subentry has been connected";
      break;
    case RASCS_SubEntryDisconnected:
      slStatus = "Subentry has been disconnected";
      break;
    case RASCS_Interactive:
      slStatus = "Terminal state supported by RASPHONE.EXE.";
      break;
    case RASCS_RetryAuthentication:
      slStatus = "Retry authentication state supported by RASPHONE.EXE.";
      break;
    case RASCS_CallbackSetByCaller:
      slStatus = "Callback state supported by RASPHONE.EXE.";
      break;
    case RASCS_PasswordExpired:
      slStatus = "Change password state supported by RASPHONE.EXE.";
      break;
  }
  if(slStatus!="")
    Form1->StatusBar1->SimpleText="Dial: "+slStatus;
}
Anm.: Woodym's Quellcode wurde von mir geringfügig verändert, für die Ausgabe der Statusmeldungen wird eine Statusleiste (TStatusBar) namens StatusBar1 verwendet.

© '99-2002 by S. Kreutzmann