So, we continue to translate a cycle of articles 30 days. NET [Windows Mobile]. I remind you that two articles are translated at once for greater interest - from Chris Kraft's blog (Windows Forms - C #) and Christopher Fairbairn (WinAPI - C). The second day is next -
control of bluetooth . Previous article from the cycle -
http://habrahabr.ru/blogs/mobiledev/61248/ .
Chris Kraft. C #
The original is
here .
As you know, constantly turned on Bluetooth considerably reduces the lifetime of the phone. In the standard Windows Mobile, there is no convenient way to turn bluetooth on and off, and on the way to work you want to easily turn it on and off so that you can talk through the headset! An important feature - for this switch, I really do not want to have to look at the screen.
')
I decided to develop a really convenient application that switches the bluetooth state on startup, then waits for one minute and is automatically unloaded from memory. Thus, it is enough to assign a call to the application to one of the hardware buttons and get the desired result.
So, according to the
countdown to midnight , I have 2 hours 21 minutes and 6 seconds to develop this application.
Bluetooth manager

I always loved my applications to be at least a little pleasing to the eye. That is why in the upper part of the application you can see the bluetooth logo. It is colored when bluetooth is active, and gray when bluetooth is turned off.
I added a text field with a few lines of logging. Also, in addition to the main task to switch the bluetooth state at the start of the application, I added two buttons to explicitly switch the state after the start.
The only difficulty in the development - the need to use P / Invoke to work with Bluetooth. Here are the necessary announcements:
[DllImport( "BthUtil.dll" )]
private static extern int BthGetMode( out RadioMode dwMode);
[DllImport( "BthUtil.dll" )]
private static extern int BthSetMode(RadioMode dwMode);
* This source code was highlighted with Source Code Highlighter .
In addition, I also used the
State and Notification Broker (SNAPI) . The bottom line is that if the state of bluetooth changes outside of our application, we will not know about this without SNAPI. You can subscribe to almost any notice. We will only subscribe to bluetooth:
SystemState bluetoothStatePowerOn = new SystemState(SystemProperty.BluetoothStatePowerOn);
bluetoothStatePowerOn.Changed += new ChangeEventHandler(bluetoothStatePowerOn_Changed);
void bluetoothStatePowerOn_Changed( object sender, ChangeEventArgs args)
{
UpdateScreen();
}
* This source code was highlighted with Source Code Highlighter .
And finally, we need to deal with the automatic termination of the application. Everything is very simple - there is a timer that waits a minute, after which a loop is executed, at each iteration of which Thread.Sleep (1000) is called. This creates an excellent effect and allows the user to understand that the application has not ended abnormally. (
Note: to be honest, I didn’t understand at all how these 10 seconds can help the user and what :) UPD: they understood, within 10 seconds a message is displayed that the application will turn off after X seconds. )
Source Code C #:
bluetoothManager.zip .
Christopher Fairbairn. WinAPI - C
The original is
here .
Bluetooth access
To begin with, the application only works on devices that use the Microsoft Bluetooth Stack. Unlike other aspects of the platform, there are no fixed standards for bluetooth. Each equipment manufacturer can choose everything that he considers best for his purposes.
To use the Microsoft Bluetooth API, you need to connect the header file “bthutil.h” and the library “bthutil.lib” - see the
documentation .
To change the Bluetooth status, use the
BthSetMode function:
// Bluetooth <br/>
BthSetMode(BTH_POWER_OFF);
* This source code was highlighted with Source Code Highlighter .
This function accepts the following constants as a parameter:
Constant | Description |
BTH_POWER_OFF | Turn off Bluetooth |
BTH_CONNECTABLE | Bluetooth is turned on and other devices can connect to the device. |
BTH_DISCOVERABLE | Bluetooth is turned on and other devices can detect and connect to the device. |
We can also get the current Bluetooth status using
BthGetMode :
DWORD dwMode = BTH_POWER_OFF;
BthGetMode(&dwMode);
if (dwMode == BTH_CONNECTABLE)
{
// -, bluetooth
}
* This source code was highlighted with Source Code Highlighter .
Using a state broker and notifications
Instead of polling the system using
BthGetMode by
timer , it is more logical to use the subscription mechanism for notifications provided by the system.
State and Notification Broker (SNAPI) is built using the registry key monitoring mechanism. We will need the following header files: “regext.h”, which provides monitoring of the registry, and “snapi.h”, containing the necessary keys with system information.
Let's use the
RegistryNotifyWindow function from “regext.h”. It monitors the registry key and sends a message to the specified window in case a change in value has occurred.
HREGNOTIFY hregNotify;
// . <br/>
NOTIFICATIONCONDITION condition = {
REG_CT_ANYCHANGE,
SN_BLUETOOTHSTATEPOWERON_BITMASK, 0
};
// BLUETOOTHSTATEPOWERON <br/>
// WM_BLUETOOTH_STATE_CHANGE <br/>
// 'hdlg'. <br/>
RegistryNotifyWindow(SN_BLUETOOTHSTATEPOWERON_ROOT,
SN_BLUETOOTHSTATEPOWERON_PATH,
SN_BLUETOOTHSTATEPOWERON_VALUE,
hDlg,
WM_BLUETOOTH_STATE_CHANGED,
0,
&condition,
&hregNotify);
* This source code was highlighted with Source Code Highlighter .
By changing the parameters of the NOTIFICATIONCONDITION structure, we can subscribe to more complex events, including receiving a notification in the case, for example, if a certain threshold is exceeded.
Using buttons on the screen
The application uses two buttons. When a user clicks any of them, a
WM_COMMAND message is sent to the
dialog :
case WM_COMMAND:
// , <br/>
switch (LOWORD(wParam))
{
case IDC_BUTTON_POWERON:
// <br/>
break ;
case IDC_BUTTON_POWEROFF:
// <br/>
break ;
}
break ;
* This source code was highlighted with Source Code Highlighter .
Text field
To change the value of a text field (TextBox), you can use the
SetWindowText function, just like for a static control:
HWND hWndCtrl = GetDlgItem(hDlg, IDC_EDIT_LOG);
SetWindowText(hWndCtrl, L "This is the new content" );
* This source code was highlighted with Source Code Highlighter .
Adding text to the end consists of two stages. First we need to move the selection (cursor) to the end of the text with the
EM_SETSEL message, and then replace the contents of the selection (
Approx. Ln .: essentially a block of zero length ) with the necessary text with the message
EM_REPLACESEL :
// <br/>
SendMessage(hWndCtrl, EM_SETSEL, -1, -1);
// <br/>
// to append to the end of the edit control <br/>
SendMessage(hWndCtrl, EM_REPLACESEL, FALSE,
(LPARAM)L "Text to add" );
* This source code was highlighted with Source Code Highlighter .
Display image
In the Compact Framework, you can do with
PictureBox controls. We will continue to use the static control by sending the
STM_SETIMAGE message to
it :
// <br/>
HWND hWndCtrl = GetDlgItem(hDlg, IDC_STATUS_BITMAP);
// <br/>
HBITMAP hBitmap = LoadBitmap(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDB_POWER_OFF));
// STM_SETIMAGE
// <br/>
SendMessage(hWndCtrl, STM_SETIMAGE, IMAGE_BITMAP,
(LPARAM)hBitmap);
* This source code was highlighted with Source Code Highlighter .
Finally we will make it so that the image can be clicked. By default, static controls do not handle clicks. To achieve this, in the resource editor it is necessary for the static control to set the value of the Notify property to true. In this case,
WM_COMMAND will be sent when you click on the image.
Test application
Download:
bluetoothmanager.zip - 99KbDue to the fact that working with bluetooth through the
state and notification broker (SNAPI) became possible only in Windows Mobile 6.0, ideally it would be nice to set a limit on the minimum OS version in the installation cab file to avoid installation on older versions.
Also, as a homework, try to download the
Broadcom Bluetooth SDK and modify the application to work on this Bluetooth protocol stack. (
Prim.per .: And better at once on both stacks! :) )