Delphi 如何检测WiFi(重新)连接的时间?

Delphi 如何检测WiFi(重新)连接的时间?,delphi,winapi,Delphi,Winapi,对不起,我没有任何代码要显示。这可能会使这个问题成为一个候选问题,但他们在这里没有语言特定的领域,我正在寻找一个德尔福解决方案,所以我将在这里提问。我希望这是可以接受的 基本上,我想在WiFi连接时自动启动VPN。我怎样才能发现呢?在这件事上,谷歌似乎不是我的朋友。所需的WinApi调用没有在Delphi中实现-您必须自己定义并调用它们。在这种情况下,相关功能包括: 您可以将其定义为: const wlanapi = 'wlanapi.dll'; WLAN_NOTIFICATI

对不起,我没有任何代码要显示。这可能会使这个问题成为一个候选问题,但他们在这里没有语言特定的领域,我正在寻找一个德尔福解决方案,所以我将在这里提问。我希望这是可以接受的


基本上,我想在WiFi连接时自动启动VPN。我怎样才能发现呢?在这件事上,谷歌似乎不是我的朋友。

所需的WinApi调用没有在Delphi中实现-您必须自己定义并调用它们。在这种情况下,相关功能包括:



您可以将其定义为:

const
  wlanapi = 'wlanapi.dll';
  WLAN_NOTIFICATION_SOURCE_ACM = $00000008;

type
  GUID = TGUID;
  HANDLE = THandle;

  PWLanNotificationData = ^TWLanNotificationData;
  TWLanNotificationData = record
    NotificationSource: DWORD;
    NotificationCode: DWORD;
    InterfaceGuid: GUID;
    dwDataSize: DWORD;
    pData: PVOID;
  end;

  TWLanNotificationCallback = procedure(data: PWLanNotificationData; context: PVOID); stdcall;

function WlanOpenHandle(dwClientVersion: DWORD; pReserved: PVOID;
  out pdwNegotiatedVersion: DWORD; out phClientHandle: HANDLE): DWORD; stdcall;
  external wlanapi name 'WlanOpenHandle';

function WlanRegisterNotification(hClientHandle: HANDLE; dwNotifSource: DWORD;
  bIgnoreDuplicate: BOOL; funcCallback: TWLanNotificationCallback; pCallbackContext: PVOID;
  pReserved: PVOID; out pdwPrevNotifSource: DWORD): DWORD; stdcall;
  external wlanapi name 'WlanRegisterNotification';
并称之为:

// Define a callback procedure to handle the notifications
// You can supply a context pointer to any user information the callback
// may require (pointer to object, etc)
procedure OnWlanNotify(data : PWLanNotificationData; context : PVOID); stdcall;
begin
  // ShowMessage(IntToStr(data^.NotificationCode));  etc...
end;

// Register for notification
procedure TForm1.FormCreate(Sender: TObject);
var
  negotiatedVer : DWORD;
  prevSource : DWORD
begin
  if WlanOpenHandle(2, nil, negotiatedVer, FHandle) <> ERROR_SUCCESS then begin
    // handle error...
  end;
  // check negotiatedVersion if needed
  if WlanRegisterNotification(FHandle,
                       WLAN_NOTIFICATION_SOURCE_ACM,
                       LongBool(true),
                       @OnWlanNotify,
                       nil,
                       nil,
                       prevSource) <> ERROR_SUCCESS then begin
  end;
第二个更详细的回调示例:

procedure OnWlanNotify(data : PWLanNotificationData; context : PVOID); stdcall;
begin
  case data^.NotificationCode of
    WLAN_NOTIFICATION_ACM_AUTOCONF_ENABLED : 
      TForm1(context^).Memo1.Lines.Add('Autoconfiguration is enabled.');
    WLAN_NOTIFICATION_ACM_AUTOCONF_DISABLED : 
      TForm1(context^).Memo1.Lines.Add('Autoconfiguration is disabled.');
    WLAN_NOTIFICATION_ACM_BACKGROUND_SCAN_ENABLED : 
      TForm1(context^).Memo1.Lines.Add('Background scans are enabled.');
    WLAN_NOTIFICATION_ACM_BACKGROUND_SCAN_DISABLED : 
      TForm1(context^).Memo1.Lines.Add('Background scans are disabled.');
    WLAN_NOTIFICATION_ACM_BSS_TYPE_CHANGE : 
      TForm1(context^).Memo1.Lines.Add('The BSS type for an interface has changed.');
    WLAN_NOTIFICATION_ACM_POWER_SETTING_CHANGE : 
      TForm1(context^).Memo1.Lines.Add('The power setting for an interface has changed.');
    WLAN_NOTIFICATION_ACM_SCAN_COMPLETE : 
      TForm1(context^).Memo1.Lines.Add('A scan for networks has completed.');
    WLAN_NOTIFICATION_ACM_SCAN_FAIL : 
      TForm1(context^).Memo1.Lines.Add('A scan for connectable networks failed.');
    WLAN_NOTIFICATION_ACM_CONNECTION_START : 
      TForm1(context^).Memo1.Lines.Add('A connection has started to a network in range.');
    WLAN_NOTIFICATION_ACM_CONNECTION_COMPLETE : 
      TForm1(context^).Memo1.Lines.Add('A connection has completed.');
    WLAN_NOTIFICATION_ACM_CONNECTION_ATTEMPT_FAIL : 
      TForm1(context^).Memo1.Lines.Add('A connection attempt has failed.');
    WLAN_NOTIFICATION_ACM_FILTER_LIST_CHANGE : 
      TForm1(context^).Memo1.Lines.Add('A change in the filter list has occurred, either through group policy or a call to the WlanSetFilterList function.');
    WLAN_NOTIFICATION_ACM_INTERFACE_ARRIVAL : 
      TForm1(context^).Memo1.Lines.Add('A wireless LAN interface is been added to or enabled on the local computer.');
    WLAN_NOTIFICATION_ACM_INTERFACE_REMOVAL : 
      TForm1(context^).Memo1.Lines.Add('A wireless LAN interface has been removed or disabled on the local computer.');
    WLAN_NOTIFICATION_ACM_PROFILE_CHANGE : 
      TForm1(context^).Memo1.Lines.Add('A change in a profile or the profile list has occurred, either through group policy or by calls to Native Wifi functions.');
    WLAN_NOTIFICATION_ACM_PROFILE_NAME_CHANGE : 
      TForm1(context^).Memo1.Lines.Add('A profile name has changed, either through group policy or by calls to Native Wifi functions.');
    WLAN_NOTIFICATION_ACM_PROFILES_EXHAUSTED : 
      TForm1(context^).Memo1.Lines.Add('All profiles were exhausted in an attempt to autoconnect.');
    WLAN_NOTIFICATION_ACM_NETWORK_NOT_AVAILABLE : 
      TForm1(context^).Memo1.Lines.Add('The wireless service cannot find any connectable network after a scan.');
    WLAN_NOTIFICATION_ACM_NETWORK_AVAILABLE : 
      TForm1(context^).Memo1.Lines.Add('The wireless service found a connectable network after a scan, the interface was in the disconnected state, and there is no compatible auto-connect profile that the wireless service can use to connect.');
    WLAN_NOTIFICATION_ACM_DISCONNECTING : 
      TForm1(context^).Memo1.Lines.Add('The wireless service is disconnecting from a connectable network.');
    WLAN_NOTIFICATION_ACM_DISCONNECTED : 
      TForm1(context^).Memo1.Lines.Add('The wireless service has disconnected from a connectable network.');
    WLAN_NOTIFICATION_ACM_ADHOC_NETWORK_STATE_CHANGE : 
      TForm1(context^).Memo1.Lines.Add('A state change has occurred for an adhoc network.');
  end;
end;
在上面的示例中,在用户上下文参数中传递了指向
Form1
的指针。这将在回调中传回,允许您从方法中访问该数据

  if WlanRegisterNotification(FHandle,
                           WLAN_NOTIFICATION_SOURCE_ACM,
                           LongBool(true),
                           @OnWlanNotify,
                           @Form1,  // Pass in form pointer
                           nil,
                           prevSource) <> ERROR_SUCCESS then begin
    // handle error
  end;
如果WlanRegisterNotification(FHandle,
WLAN\u通知\u源\u ACM,
朗布尔(真),
@通知,
@Form1,//传入表单指针
无
prevSource)错误\u成功,然后开始
//处理错误
结束;

这可能会有所帮助:看起来不错(+1),但很复杂-“创建DLL以接收连接通知后,必须向系统注册它”。我希望不必生成DLL,但如果这是唯一的方法,那么我将邀请您将此作为答案发布。@TLama-谢谢您的编辑。我知道我可能还没有把一切都做好。还在整理-快点写下来!没问题。我的更新来自Windows SDK标题(不是直译,但我希望更接近正确)。
  if WlanRegisterNotification(FHandle,
                           WLAN_NOTIFICATION_SOURCE_ACM,
                           LongBool(true),
                           @OnWlanNotify,
                           @Form1,  // Pass in form pointer
                           nil,
                           prevSource) <> ERROR_SUCCESS then begin
    // handle error
  end;