Translation: 30 days Windows Mobile - Day Two (Winforms / C # vs WinAPI / C)

Original author: Chris Craft and Christopher Fairbairn
  • Transfer
So, we continue the translation of the article cycle 30 days. NET [Windows Mobile]. I remind you that for more interest, two articles are being translated at once - from the blog of Chris Kraft (Windows Forms - C #) and Christopher Fairbairn (WinAPI - C). Next in line is the second day - bluetooth control . Previous article from the cycle -
http://habrahabr.ru/blogs/mobiledev/61248/ .


Chris Kraft C #


The original is here .

As you know, constantly on Bluetooth significantly reduces the life time of the phone. There is no convenient way to turn bluetooth on and off in the standard delivery of Windows Mobile, and on the way to work, you really want to turn it on easily and simply to get the opportunity to talk through the headset! An important feature - for this switch I really do not want it to be necessary to look at the screen.

I decided to develop a really convenient application that at startup switches the state of bluetooth, after which it waits for one minute and is automatically unloaded from memory. Thus, it is enough to assign an application call to one of the hardware buttons and get the desired result.

So, in accordance withcountdown to midnight , I have 2 hours 21 minutes and 6 seconds left to develop this application.

Bluetooth manager



Always loved to have my applications at least a little pleasing to the eye. That is why at the top of the application you can watch the bluetooth logo. It is color when bluetooth is active, and gray when bluetooth is off.

I added a text box displaying multiple lines for logging. Also, in addition to the main task of switching the state of bluetooth when the application starts, I added two buttons to explicitly switch the state after the start.

The only development challenge is the need to use P / Invoke to work with Bluetooth. Here are the required 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 status and notification broker (SNAPI) . The bottom line is that if the bluetooth state changes outside of our application, we won’t know about it without SNAPI. You can subscribe to almost any notification. 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 completion 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 a great effect and allows the user to understand that the application did not crash. ( Note lane: to be honest, I completely did not understand how these 10 seconds can help the user and how :) UPD: figured out, within 10 seconds a message is displayed saying that the application will turn off after X seconds. )

C # source code: bluetoothManager.zip .

Christopher Fairbairn WinAPI - C


The original is here .

Bluetooth access


To begin with, the application only works on devices that use 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 optimal for his purposes.

To use the Microsoft Bluetooth API, you must include the header file “bthutil.h” and the library “bthutil.lib” - see the documentation .

To change the status of Bluetooth, use the BthSetMode function :
// Выключим Bluetooth<br/>
BthSetMode(BTH_POWER_OFF);

* This source code was highlighted with Source Code Highlighter.


This function takes 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 status of Bluetooth using BthGetMode :
DWORD dwMode = BTH_POWER_OFF;
BthGetMode(&dwMode);

if (dwMode == BTH_CONNECTABLE)
{
 // Сделаем что-нибудь, если bluetooth включен
}

* This source code was highlighted with Source Code Highlighter.


Using the status and notification broker


Instead of interrogating the system with a timer using BthGetMode , it is more logical to use the notification subscription mechanism that the system provides.

State and Notification Broker (SNAPI) is built using the registry key monitoring mechanism. We will need the following header files: “regext.h”, which provides registry monitoring, and “snapi.h”, which contains declarations of the necessary keys with system information.

We will 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 also subscribe to more complex events, including receiving a notification in case, for example, a certain threshold is exceeded.

Using the buttons on the screen


The application uses two buttons. When the 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 steps. First, we must move the selection (cursor) to the end of the text using the EM_SETSEL message , and then replace the contents of the selection ( Note per: essentially a zero-length block ) with the necessary text using the EM_REPLACESEL message :

// Перемещаем курсор в конец<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 control. We will continue to use the static control by sending him the STM_SETIMAGE message :

//Получаем контрол<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 possible to click on the image. By default, static controls do not handle clicks. To achieve this, in the resource editor, you need to set the value of the Notify property to true at the static control. In this case, WM_COMMAND will be sent when you click on the image.

Test application


Download: bluetoothmanager.zip - 99Kb

Due to the fact that working with bluetooth through the status and notification broker (SNAPI) became possible only in Windows Mobile 6.0, ideally it would be nice to set a limit on the minimum version of the OS in the installation cab-file to avoid Installation on older versions.

Also, as a homework, try downloading the Broadcom Bluetooth SDK and modify the application so that it works on this Bluetooth protocol stack. ( Note.per .: And it’s better to immediately on both stacks! :) )


Also popular now: