Necessary WinApi calls are not implemented in Delphi - you need to define and name them yourself. In this case, the relevant functions are:
WlanOpenHandle (MSDN)
WlanRegisterNotification (MSDN)
Structure WLAN_NOTIFICATION_SOURCE (MSDN)
You would define them as:
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';
And name them like:
// 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;
This logs you in for WLAN notifications. The callback function will be executed after receiving the notifications, and the nature of the notification can be found in the TWlanNotificationData structure TWlanNotificationData to this method.
You should also refuse to register for notifications when they are no longer needed. I just checked the rudimentary error checking. Details for various error codes can be found in the MSDN documentation at.
A (partial) ACM notification list:
const WLAN_NOTIFICATION_ACM_AUTOCONF_ENABLED = $00000001; //Autoconfiguration is enabled. WLAN_NOTIFICATION_ACM_AUTOCONF_DISABLED = $00000002; //Autoconfiguration is disabled. WLAN_NOTIFICATION_ACM_BACKGROUND_SCAN_ENABLED = $00000003; //Background scans are enabled. WLAN_NOTIFICATION_ACM_BACKGROUND_SCAN_DISABLED = $00000004; //Background scans are disabled. WLAN_NOTIFICATION_ACM_BSS_TYPE_CHANGE = $00000005; //The BSS type for an interface has changed. WLAN_NOTIFICATION_ACM_POWER_SETTING_CHANGE = $00000006; //The power setting for an interface has changed. WLAN_NOTIFICATION_ACM_SCAN_COMPLETE = $00000007; //A scan for networks has completed. WLAN_NOTIFICATION_ACM_SCAN_FAIL = $00000008; //A scan for connectable networks failed. WLAN_NOTIFICATION_ACM_CONNECTION_START = $00000009; //A connection has started to a network in range. WLAN_NOTIFICATION_ACM_CONNECTION_COMPLETE = $0000000a; //A connection has completed. WLAN_NOTIFICATION_ACM_CONNECTION_ATTEMPT_FAIL = $0000000b; //A connection attempt has failed. WLAN_NOTIFICATION_ACM_FILTER_LIST_CHANGE = $0000000c; //A change in the filter list has occurred, either through group policy or a call to the WlanSetFilterList function. WLAN_NOTIFICATION_ACM_INTERFACE_ARRIVAL = $0000000d; //A wireless LAN interface is been added to or enabled on the local computer. WLAN_NOTIFICATION_ACM_INTERFACE_REMOVAL = $0000000e; //A wireless LAN interface has been removed or disabled on the local computer. WLAN_NOTIFICATION_ACM_PROFILE_CHANGE = $0000000f; //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 = $00000010; //A profile name has changed, either through group policy or by calls to Native Wifi functions. WLAN_NOTIFICATION_ACM_PROFILES_EXHAUSTED = $00000011; //All profiles were exhausted in an attempt to autoconnect. WLAN_NOTIFICATION_ACM_NETWORK_NOT_AVAILABLE = $00000012; //The wireless service cannot find any connectable network after a scan. WLAN_NOTIFICATION_ACM_NETWORK_AVAILABLE = $00000013; //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 = $00000014; //The wireless service is disconnecting from a connectable network. WLAN_NOTIFICATION_ACM_DISCONNECTED = $00000015; //The wireless service has disconnected from a connectable network. WLAN_NOTIFICATION_ACM_ADHOC_NETWORK_STATE_CHANGE = $00000016; //A state change has occurred for an adhoc network.
The second callback example in more detail:
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;
In the above example, a pointer to Form1 was passed in the user context parameter. This is returned in the callback, which allows you to access this data from the method.
if WlanRegisterNotification(FHandle, WLAN_NOTIFICATION_SOURCE_ACM, LongBool(true), @OnWlanNotify, @Form1, // Pass in form pointer nil, prevSource) <> ERROR_SUCCESS then begin // handle error end;