Thema: Wlan connect

Einzelnen Beitrag anzeigen

Benutzerbild von TERWI
TERWI

Registriert seit: 29. Mär 2008
Ort: D-49626
381 Beiträge
 
Delphi 11 Alexandria
 
#19

AW: Wlan connect

  Alt 29. Jan 2017, 15:03
Nun zum WLANNotify-ing:
Da haben sich vor gut 10 Jahren schon div. Leute in diesem Projekt den Kopf zerbrochen und mit Event's rumgedaddelt. Hat's irgendwann dann doch geklappt ?

Nach eingehendem Studium div. MSDN-Seiten zu dem Thema las ich sinngemäß:
".... WlanRegisterNotification funzt so lange, wie der übergebene Handle gültig ist ...."

Aha, also: Handle öffnen, WlanRegisterNotification aufrufen und dann entsprechend andere Funktionen hinterher ... und am Ende der selbstgemachten Routine gleich wieder den Handle (ordnungsgemäß !) freigeben.
Da wundert's nicht, wenn nie ein (zeitlich später folgendes) Ereignis NIEMALS und der Notify-Routine auftaucht. Warten auf Godot ....

Lösung: Einfach beim Programmstart global nur einen THandle (! - hier FcHandle) holen und im gesamten Programm verwenden. Funzt tadellos hier.
Code:
function TMain.GetWlanHandle(var Handle : THandle) : boolean;
var
  res    : HRESULT;
  Version : DWORD;
begin
  result := false;
  Handle := 0;
  res := WlanOpenHandle(2, nil, @Version, @Handle); // "2" for version also XP - autom. negotiation
  if res <> ERROR_SUCCESS then
  begin
    Memo.Lines.Add('GetWlanHandle - FAILED: ' + IntToStr(res) + ' - ' + GetErrString(res));
    exit;       // ... no handle ? no function ...
  end;
  Memo.Lines.Add('GetWlanHandle - negotiate Version: ' + IntToStr(Version));
  result:= true;
end;
Übergeben und gesetzt wird eine globale var FhClient.

Die Registrierug ist auch recht unspektakulär:
Code:
// -----------------------------------------------------------------------------
function TMain.Wlan_RegisterNotification(Mode : boolean) : HRESULT;
var
  Notify  : DWORD;
  pProc   : pointer;
begin
  if NOT FIsClient then exit; // for safety !
  if Mode then
  begin
    Notify := NDU_WLAN_NOTIFICATION_SOURCE_ALL; //_ACM
    pProc := @WLanNotifyProc;
  end
  else
  begin
    Notify := NDU_WLAN_NOTIFICATION_SOURCE_NONE;
    pProc := NIL;
  end;
  // check negotiatedVersion if needed
  result := WlanRegisterNotification(FhClient, // hClientHandle [in]
                                     NDU_WLAN_NOTIFICATION_SOURCE_ACM, // dwNotifSource [in]
                                     //NDU_WLAN_NOTIFICATION_SOURCE_ALL,
                                     true, // bIgnoreDuplicate [in], ignored in XP
                                     pProc, // funcCallback [in, optional]
                                     nil, // pCallbackContext [in, optional], always NIL
                                     nil, // pReserved [in], always NIL
                                     @FScanCompleteEvent //pdwPrevNotifSource [out, optional]
                                    );
  if result <> ERROR_SUCCESS then
  begin
    Memo.Lines.Add('RegisterNotification - FAILED: ' + IntToStr(result));
  end
  else
    Memo.Lines.Add('RegisterNotification - OK !');
end;
Initialisiert wird das so:
Code:
procedure TMain.FormCreate(Sender: TObject);
var
  res       : HRESULT;
  prevSource : pointer;  // Register
begin
  // SetUp Common
  Memo.Clear;
  FIF_List    := TList.Create; // remind Interfaces
  FIF_selected := -1;           // nothing selected
  FNW_List    := TList.Create; // remind Networks
  FNW_selected := -1;           // nothing selected
  FIsClient   := GetWlanHandle(FhClient);;
  if FIsClient then
    Wlan_RegisterNotification(true);
  ....
end;

procedure TMain.FormDestroy(Sender: TObject);
begin
  if FIsClient then
    Wlan_RegisterNotification(false);
  .....
end;
Und die Notify-Routine geht etwa so:
Code:
procedure WLanNotifyProc(pNotifyData : Pndu_WLAN_NOTIFICATION_DATA;
                          pContext : pointer); stdcall;
var
  s : string;
begin
  if pNotifyData^.NotificationSource = NDU_WLAN_NOTIFICATION_SOURCE_ACM then
  begin
    case Tndu_WLAN_NOTIFICATION_ACM(pNotifyData.NotificationCode) of
      ....
      wlan_notification_acm_scan_complete : s := 'scan complete';
      wlan_notification_acm_scan_fail : s := 'scan fail';
      wlan_notification_acm_connection_start : s := 'connection start';
      wlan_notification_acm_connection_complete : s := 'connection complete';
      wlan_notification_acm_connection_attempt_fail : s := 'connection attempt';
      ....
      wlan_notification_acm_disconnecting : s := 'disconnecting';
      wlan_notification_acm_disconnected : s := 'disconnected';
      ....
    end;
    Main.Memo.Lines.Add('NOTIFY: ' + IntToStr(pNotifyData^.NotificationCode) + ' - ' + s);
  end;
  if Assigned(pNotifyData) then WlanFreeMemory(pNotifyData);
end;
Angehängte Dateien
Dateityp: rar WIFI_ADMIN.004.rar (198,2 KB, 66x aufgerufen)

Geändert von TERWI (29. Jan 2017 um 15:29 Uhr)
  Mit Zitat antworten Zitat