Смекни!
smekni.com

Программирование для Windows CE (стр. 2 из 3)

Те программисты, которые разрабатывают программы для РПК или других горизонтальных платформ, вполне обойдутся без Platform Builder, но его, несомненно, стоит порекомендовать серьезным авторам Windows CE-приложений. Этот сложный набор инструментов обеспечивает бесценную информацию об архитектуре Windows CE. Позднее мы поговорим о Platform Builder подробнее.

Базовый цикл разработки программ

А теперь приступим к разработке настоящей Windows CE-программы. Последовательность необходимых для этого шагов здесь такая же, как и при подготовке программы для Windows настольных систем. Для начала организуем новую рабочую область в окне Visual C++. Можно прибегнуть к услугам одного из множества "мастеров", призванных помочь в составлении Windows CE-программ, либо заняться этим самостоятельно, выбрав тип приложения Win32 application и установив флажки для тех процессоров, на которые, как предполагается, будет рассчитана программа.

По завершении разработки проекта следует просто набрать текст программы и подготовить ресурсы, в том числе меню, пиктограммы и шаблоны диалоговых окон, почти так же, как в ходе аналогичных процедур в среде Windows 98 или Windows NT, исключение составляют вышеупомянутые отличия в API. Как было отмечено ранее, отличия эти не слишком значительны; тем не менее некоторые особенности модели программирования для Windows CE все же заслуживают внимания. Первая, и, на поверхностный взгляд, наиболее удивительная из них, - отсутствие в Windows CE меню для окон верхнего уровня. Это не означает, что Windows CE-программы не могут иметь меню, просто управление ими организуется через панель команд.

Элемент управления "панель команд" и ее более сложные "сестры" - "командные полосы" - обеспечивают доступ к меню и инструментальным панелям, кроме того, предусматривают место для размещения кнопок вызова справочной системы программ Windows CE и их закрытия. Благодаря своей конструкции эти элементы управления предельно просты в программировании. На деле незамысловатая панель команд, которая обеспечивает доступ к меню и кнопкам закрытия программы, может быть представлена всего тремя строчками в тексте программы. В элементе управления "командная полоса" получила дальнейшее развитие концепция панели команд, компоненты которой, т. е. меню, кнопки и другие элементы, группируются в отдельные полосы, размещаемые на экране пользователем. Основой данного элемента служит элемент управления rebar (повторно используемая панель), разработанный для Internet Explorer 3.

Еще одно отличие Windows CE-программ состоит в том, что в масштабах отдельной программы пиктограммы назначаются классам, а не экземплярам окна. Следовательно, два окна одного и того же оконного класса будут иметь одну и ту же пиктограмму. Это не играет особой роли, поскольку пиктограмма окна отображается только на соответствующей кнопке панели задач.

Большинство остальных отличий, не считая уже перечисленных, касается соглашений по программированию, а не ограничений для программ или различий в реализации. Например, окна верхнего уровня в Windows CE могут содержать строки заголовка, в то время как по имеющимся соглашениям это недопустимо. Подобный запрет вызван необходимостью экономии места на крохотных экранах устройств Windows CE. В версиях Windows для настольных систем строка заголовка применяется для перемещения окна по экрану. Такой функции в Windows CE-системах чаще всего нет, так как по умолчанию окна верхнего уровня в Windows CE занимают весь экран.

Здесь уместно упомянуть одну из новинок Windows CE. Начиная с версии Windows CE 2.1 диспетчер окон обзавелся средствами для работы со стандартными окнами переменного размера. Операционная система всегда обеспечивала возможность формирования окон любого фиксированного размера, однако теперь диспетчер окон позволяет окаймлять перекрывающиеся окна рамками, в результате пользователь может менять их размеры. Тем не менее даже на новых профессиональных РПК такое увидишь не часто, поскольку по умолчанию окна верхнего уровня занимают всю площадь экрана, несмотря на его относительно немалые размеры.

//============================================================

// TinyCE - Небольшая программа для Windows CE

//

#include <windows.h>

#include <commctrl.h> // подключение линейки команд

LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM,LPARAM);

TCHAR szAppName[] = TEXT ("TinyCE");

HINSTANCE hInst;

//-----------------------------------

// Точка входа в программу

//

int WINAPI WinMain (HINSTANCE hInstance,

HINSTANCE hPrevInstance, LPWSTR lpCmdLine,

int nCmdShow) {

WNDCLASS wc;

HWND hWnd;

MSG msg;

hInst = hInstance;

// Регистрируется класс App Main Window

memset (&wc, 0, sizeof (wc));

wc.lpfnWndProc = MainWndProc; // Внешний вызов

wc.hInstance = hInstance; // Дескриптор владельца

wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);

wc.lpszClassName = szAppName; // Имя класса окна

if (RegisterClass(&wc) == 0) return -1;

// Построение главного окна

hWnd = CreateWindow (szAppName, // Класс окна

szAppName, // Заголовок окна

WS_VISIBLE, // Флаги стилей

CW_USEDEFAULT, // Позиция по X

CW_USEDEFAULT, // Позиция по Y

CW_USEDEFAULT, // Исходная ширина

CW_USEDEFAULT, // Исходная высота

NULL, // Предок

NULL, // Меню, должен иметь

// значение NULL

hInstance, // Экземпляр программы

NULL); // Указатель для

// создания параметров

// В качестве return-значения передается код ошибки,

// если окно не построено

if (!IsWindow (hWnd)) return -2;

// Стандартные вызовы отображения и обновления

ShowWindow (hWnd, nCmdShow);

UpdateWindow (hWnd);

// Цикл обработки сообщений в программе

while (GetMessage (&msg, NULL, 0, 0)) {

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return 0;

}

//-----------------------------------

// Основная оконная процедура

//

LRESULT CALLBACK MainWndProc(HWND hWnd, UINT wMsg,

WPARAM wParam, LPARAM lParam) {

HWND hwndCB;

PAINTSTRUCT ps;

RECT rect;

HDC hdc;

switch (wMsg) {

case WM_CREATE:

// Создание минимальной панели команд, содержащей только

// кнопку Exit.

hwndCB = CommandBar_Create (hInst, hWnd, 0x10);

CommandBar_AddAdornments (hwndCB, 0, 0);

break;

case WM_PAINT:

// Настройка размера прямоугольника клиентского окна

// с учетом высоты панели команд.

GetClientRect (hWnd, &rect);

rect.top += CommandBar_Height (GetDlgItem (hWnd, 0x10));

hdc = BeginPaint (hWnd, &ps);

DrawText (hdc, TEXT ("Hello Windows CE!"), -1, &rect,

DT_CENTER | DT_VCENTER | DT_SINGLELINE);

EndPaint (hWnd, &ps);

break;

case WM_DESTROY:

break;

}

return DefWindowProc(hWnd, wMsg, wParam, lParam);

}

Достаточно взглянуть на этот текст, чтобы увидеть, как похожи приложения Windows CE на обычные Windows-программы.

А теперь, не упуская из виду все перечисленные соображения, рассмотрим элементарную программу для Windows CE. На рис. 1 показан исходный текст простой программы TinyCE, которая лишь выводит на экран строку текста в главном окне. При беглом взгляде программисты, сроднившиеся с функциями Win32, вряд ли обнаружат едва уловимые различия между этой программой и ее "кузинам" для Windows 98 или NT. Она так же регистрирует класс окна, конструирует окно, выполняет цикл обработки сообщений и работает с окнами, как и любая другая Windows-программа. В отличиях, наблюдающихся в данном примере, повинны уже упоминавшиеся расхождения в интерфейсах API. Например, для размещения кнопки закрытия программы используется панель команд. После набора текста программы для ее компиляции и запуска применяются точно такие же методы, как и для приложений на настольных ПК. Процедура компиляции предусматривает дополнительную операцию автоматической загрузки полученного EXE- или DLL-модуля в подключенное к настольному ПК Windows CE-устройство. Для запуска программы на выполнение в среде Windows CE выбирается тот же пункт меню Program | Run (Программа | Запуск либо [Ctrl] + [F5]), что и при запуске программы, подготовленной для Windows NT.

И конечно, с помощью интегрированного отладчика можно выполнять программу в пошаговом режиме. Основное различие между отладкой программ для Windows CE и Windows NT вызвано влиянием скорости последовательного соединения между ПК разработчика и удаленной Windows CE-системой. Из-за низкой скорости такого соединения пошаговая отладка превращается в раздражающе медленный процесс. Что касается меня, я обычно применяю отладчик только для поиска самых трудноуловимых ошибок.

Вместо дистанционного отладчика можно применять другой вариант. Все SDK для платформ РПК, КПК и автомобильных ПК (Auto PC) оснащены программными эмуляторами, которые пытаются имитировать удаленное Windows CE-устройство в среде Windows NT. Такой эмулятор запускает скомпилированную специальным образом версию подготовленной программы. Он эмулирует интерфейс API Windows CE, в том числе такие его расширения, как API СУБД. Но и здесь не обходится без проблем: модель среды Windows CE, обеспечиваемая эмулятором, далека от идеала. Иногда после целого дня работы вдруг понимаешь, что проблема, над решением которой бьешся, - проблема эмулятора, а не ошибка в программе.

Но выход из создавшейся ситуации все же есть: программы для Windows CE следует составлять таким образом, чтобы они компилировались как для Windows CE, так и для Windows NT. В результате общие для обеих систем фрагменты приложения можно отлаживать локально в среде Windows NT, а затем, выбрав иную целевую среду, провести компиляцию для Windows CE. Нужно только помнить, что многократные компиляции на любой из платформ чреваты сложностями. После бесконечных повторов компиляции для Windows NT придется потратить массу времени, чтобы путем внесения изменений добиться надлежащего функционирования программы в среде Windows CE.

Разработать программу, которая будет компилироваться и для Windows NT, и для Windows CE, не так уж и трудно. Чтобы выделить фрагменты программы, характерные для конкретной операционной системы, следует применять выражения define компилятора, и тогда они будут выбираться при компиляции для заданной ОС. В приведенном ниже фрагменте программы функции формирования панели команд размещены в предложениях условной компиляции (#), поэтому будут охвачены процедурой компиляции только для Windows CE.

#ifdef _WIN32_WCE // Если выполняется

// компиляция для CE