30 Days of Windows Mobile – Day 02: Bluetooth Manager

Screenshot of Bluetooth Manager applicationThe second sample application produced by Chris Craft is a small utility to toggle the power of a Bluetooth radio. Leaving the power on to the bluetooth radio for extended periods of time can be a drain on the battery life of your device.

Accessing Bluetooth

This application only works on devices that utilise the Microsoft Bluetooth stack. Unlike other aspects of the operating system there is no standardised API for bluetooth development, leading OEMs to be free to pick the bluetooth stack they think best serves the requirements of their device.

The Microsoft Bluetooth APIs are designed for use with C and C++. To use them you need to include the header file “bthutil.h” and link to a library called “bthutil.lib”. You can determine these requirements by looking at the bottom of the MSDN documentation page for functions such as BthSetMode.

To change the state of the Bluetooth radio we can use the BthSetMode function as shown below:

// Turn the bluetooth radio off
BthSetMode(BTH_POWER_OFF);

BthSetMode accepts a single parameter which is the desired radio state. It can be one of the following three values:

Value Description
BTH_POWER_OFF The bluetooth radio is off
BTH_CONNECTABLE The bluetooth radio is on and other devices can connect to it
BTH_DISCOVERABLE The bluetooth radio is on and other devices can discover (find) it as well as connect to it

We can also query the current state of the bluetooth radio by calling a function called BthGetMode.

DWORD dwMode = BTH_POWER_OFF;
BthGetMode(&dwMode);
 
if (dwMode == BTH_CONNECTABLE)
{
  // Do something here if the radio
  // is currently connectable
}

Using the State and Notification Broker

Rather than periodically polling the BthGetMode function to determine when the radio changes state we can ask the operating system to proactively tell us when the bluetooth mode changes.

The State and Notification Broker (SNAPI) is built on top of an infrastructure that allows you to monitor the value of any registry key and obtain notifications whenever it changes. There are two header files involved.

  • regext.h – Provides functions that allow us to watch for registry value changes
  • snapi.h – Provides definitions of various registry values that store system state information

Our sample application makes use of a function defined in regext.h called RegistryNotifyWindow. This function monitors a registry value and posts a window message to a specified window whenever the value changes. We set this up using a code snippet that looks similar to the following:

HREGNOTIFY hregNotify;
 
// We are interested in any change to the registry value.
NOTIFICATIONCONDITION condition = {
  REG_CT_ANYCHANGE,
  SN_BLUETOOTHSTATEPOWERON_BITMASK, 0
};
 
// We want to listen to the BLUETOOTHSTATEPOWERON
// registry value and have a WM_BLUETOOTH_STATE_CHANGE
// window message posted to 'hdlg' whenever it changes.
RegistryNotifyWindow(SN_BLUETOOTHSTATEPOWERON_ROOT,
  SN_BLUETOOTHSTATEPOWERON_PATH,
  SN_BLUETOOTHSTATEPOWERON_VALUE,
  hDlg,
  WM_BLUETOOTH_STATE_CHANGED,
  0,
  &condition,
  &hregNotify);

By modifying the contents of the NOTIFICATIONCONDITION structure we can also produce more complex scenarios such as only being notified when the specified SNAPI property increases above a certain value.

Using a button control

This application uses two buttons. When the user presses a button the dialog is sent a WM_COMMAND window message to allow it to respond to the event. One of the parameters of the WM_COMMAND window message allows us to determine which button has been pressed. For example:

case WM_COMMAND:
   // Determine which button was pressed
   switch (LOWORD(wParam))
   {
     case IDC_BUTTON_POWERON:
       // turn the bluetooth radio on
       break;
 
     case IDC_BUTTON_POWEROFF:
       // turn the bluetooth radio off
       break;
   }
   break;

Using an edit control

To replace the entire contents of an edit (textbox) control you can use the SetWindowText function just like you would for a static control.

HWND hWndCtrl = GetDlgItem(hDlg, IDC_EDIT_LOG);
SetWindowText(hWndCtrl, L"This is the new content");

To append text to the end of the existing contents of an edit control is a two part process. First we can move the selection (cursor) to the end of the textbox via the EM_SETSEL window message and then we can replace that selection with the text we desire via the EM_REPLACESEL window message, as shown below:

// Move the cursor to the end of the edit control
SendMessage(hWndCtrl, EM_SETSEL, -1, -1);
 
// Replace that selection with the text we want
// to append to the end of the edit control
SendMessage(hWndCtrl, EM_REPLACESEL, FALSE,
  (LPARAM)L"Text to add");

Displaying an image

The static control is commonly used like a Label control would be within a .NET Compact Framework application however it can also be used like a Picturebox control.

To change the image displayed by the static control we can use the STM_SETIMAGE window message as demonstrated by the following code sample.

// Get the status bitmap control
HWND hWndCtrl = GetDlgItem(hDlg, IDC_STATUS_BITMAP);
 
// Load the desired image from a bitmap resource
HBITMAP hBitmap = LoadBitmap(GetModuleHandle(NULL),
  MAKEINTRESOURCE(IDB_POWER_OFF));
 
// Then send the STM_SETIMAGE window message
// to the static control
SendMessage(hWndCtrl, STM_SETIMAGE, IMAGE_BITMAP,
  (LPARAM)hBitmap);

The other thing we need to do for this code sample is to make the image click-able. By default a static control does not respond to stylus taps. Within the dialog resource editor you can set the Notify property for a static control to True. When this is done a WM_COMMAND message will be generated whenever the static control is clicked, just like a button would.

Sample Application

[Download bluetoothmanager.zip - 99KB]

The Bluetooth State and Notification broker properties are new to Windows Mobile 6.0 so ideally we should set the minimum OS version property in the CAB file to disallow installation on previous versions of the operating system. This is left as a learning experience for the reader (one hint is that the OS version you want to specify isn’t 6.0…).

Another reader exercise may be to download the Broadcom Bluetooth SDK and modify the sample application to work on devices that use this alternative Bluetooth stack.

One Response to “30 Days of Windows Mobile – Day 02: Bluetooth Manager”

  1. Prasad says:

    You guys are amazing ….. i love it and really appreciate your work. Keep it up !!!!!!!!!!

Leave a Reply