Reputation: 1562
I'm building an application that allows me to pair with a bluetooth device. Right now I'm trying to find an event in C# that allows me to detect when a device is being added or ready to be added (see img: Windows 10 popup)
Anyone know which one I'm looking for?
Upvotes: 4
Views: 3517
Reputation:
You can use a device watcher.
Initialize with:
var deviceWatcher = DeviceInformation.CreateWatcher(BluetoothDevice.GetDeviceSelector());
deviceWatcher.Added += DeviceWatcher_AddedAsync;
deviceWatcher.Removed += DeviceWatcher_RemovedAsync;
Then you get events on:
private void DeviceWatcher_AddedAsync(DeviceWatcher sender, DeviceInformation args)
{
...
}
private void DeviceWatcher_RemovedAsync(DeviceWatcher sender, DeviceInformationUpdate args)
{
...
}
Upvotes: 0
Reputation: 191
I'm a bit late, but here are a few snippets about what I'm doing in plain Raw API (in C++), using the WM_DEVICECHANGE messages.
(Those are 'Interface GUIDs' in case you need them with the SetupAPIxx/CM_xx routines)
I'm using the following code to 'register' them:
HDEVNOTIFY UDeviceInfoHandler::RegisterDeviceNotification( HWND hwnd,
GUID InterfaceClassGuid,
DWORD flags)
{
DEV_BROADCAST_DEVICEINTERFACE DevFilter;
::ZeroMemory(&DevFilter, sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
DevFilter.dbcc_size = sizeof( DEV_BROADCAST_DEVICEINTERFACE );
DevFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
DevFilter.dbcc_classguid = InterfaceClassGuid;
return ::RegisterDeviceNotification(hwnd, //events recipient
&DevFilter, //type of device
flags); //type of recipient handle
}
bool UDeviceInfoHandler::UnregisterDeviceNotification(HDEVNOTIFY hdevnotify)
{
return TRUE==::UnregisterDeviceNotification(hdevnotify);
}
At this point, you'll be able
by handling the
messages in your WM_DEVICECHANGE handler.
If you need to access the DBT_CUSTOMEVENT messages pertaining to the Radio/Devices, you'll first need to 'Register' some 'events' for WM_DEVICECHANGE too, but for the 'HANDLE' of the Radio. You can register the GUIDs of the following events
Use something like
void UBthDeviceInfoHandler::RegisterBthNotifications(HWND hwnd,const UGuidItems& guids)
{
BLUETOOTH_FIND_RADIO_PARAMS radio_params;
radio_params.dwSize = sizeof(BLUETOOTH_FIND_RADIO_PARAMS);
HANDLE hRadio;
HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio(&radio_params, &hRadio);
if (hFind != INVALID_HANDLE_VALUE)
{
do
{
//for every events Guid you need
HDEVNOTIFY hdevnotify=
RegisterHandleNotification( hwnd,
hRadio,
Guid,
DEVICE_NOTIFY_WINDOW_HANDLE);
if (hdevnotify!=NULL){
//insert code here
}
else{
//error handling
}
//end for
} while (BluetoothFindNextRadio(hFind, &hRadio));
BluetoothFindRadioClose(hFind);
}
}
At this point, you'll be able to receive those events by handling the DBT_CUSTOMEVENT|DBT_DEVTYP_HANDLE porting of the WM_DEVICECHANGE handler, with something like
[...]
#if (WINVER >= 0x040A)
case DBT_CUSTOMEVENT:
//@see https://msdn.microsoft.com/en-us/library/aa363217(v=vs.85).aspx
if (lParam!=0){
PDEV_BROADCAST_HDR phdr = reinterpret_cast<PDEV_BROADCAST_HDR> (lParam);
switch (phdr->dbch_devicetype){
case DBT_DEVTYP_HANDLE:
{
//@see https://learn.microsoft.com/en-us/windows/desktop/bluetooth/bluetooth-and-wm-devicechange-messages
//typedef struct _DEV_BROADCAST_HANDLE {
// DWORD dbch_size;
// DWORD dbch_devicetype;
// DWORD dbch_reserved;
// HANDLE dbch_handle; // file handle used in call to RegisterDeviceNotification
// HDEVNOTIFY dbch_hdevnotify; // returned from RegisterDeviceNotification
// //
// // The following 3 fields are only valid if wParam is DBT_CUSTOMEVENT.
// //
// GUID dbch_eventguid;
// LONG dbch_nameoffset; // offset (bytes) of variable-length string buffer (-1 if none)
// BYTE dbch_data[1]; // variable-sized buffer, potentially containing binary and/or text data
//} DEV_BROADCAST_HANDLE, *PDEV_BROADCAST_HANDLE;
PDEV_BROADCAST_HANDLE phndl=reinterpret_cast<PDEV_BROADCAST_HANDLE>(phdr);
CustomHandleEvent(*phndl);
}
break;
default:
break;
}
}//endif lParam!=0
break;
#endif // WINVER >= 0x040A
the |dbch_eventguid| field being one of those GUID_BLUETOOTH_RADIO_IN_RANGE etc. events.
Well, this is only an overview of what I've discovered so far. Any enhancements/suggestions/additions are more than welcome though. I'm currently struggling with a few undocumented CUSTOM_EVENTS, whose GUIDs are
//When the Bluetooth radio handle is opened, call the RegisterDeviceNotification function and
//register for notifications on the handle using DBT_DEVTYP_HANDLE as the devicetype.
//When registered, the following GUIDs are sent,
//and the DEV_BROADCAST_HANDLE::dbch_data member is the associated buffer.
//this unknow event happens while looking for nearby devices in Settings.
DEFINE_GUID(GUID_UNKNOWN_EVENT_GUID1,0x1BBD4010, 0x498C, 0x4E85, 0x85, 0x1B, 0xEA, 0xA0, 0x57, 0x15, 0xC3, 0x7A);
//
DEFINE_GUID(GUID_UNKNOWN_EVENT_GUID2,0xD4EB6503, 0xC001, 0x441A, 0xAE, 0x42, 0xEE, 0x0D, 0xC9, 0x6C, 0x18, 0x85);
//happening when opening Settings|Bluetooth panel
DEFINE_GUID(GUID_UNKNOWN_EVENT_GUID3,0x7A7637FF, 0x531C, 0x4205, 0x97, 0x80, 0x3F, 0x33, 0x5F, 0x65, 0xAD, 0xDD);
//nameoffset=-1 datalen=8
//Settings|Devices -> Bluetooth activation/deactivation
DEFINE_GUID(GUID_UNKNOWN_EVENT_GUID4,0xB74983CD, 0xC2D9, 0x4E38, 0xB8, 0x0E, 0x54, 0x72, 0xFC, 0x10, 0x8B, 0x4B);
//nameoffset=-1 datalen=8
Hope this helps!
Upvotes: 5