Программирование для карманных компьютеров
Шрифт:
6. Теперь нужно перейти в процедуру WinProc и в ее начале объявить переменные, как показано в листинге 4.27. Листинг 4.27
int i;
RECT *lprc;
wchar_t *mstr[]={L"1", L"2", L"3", L"4"};7. Удалить из обработчика сообщения WM_CREATE ранее сгенерированный код и ввести туда код, приведенный в листинге 4.28. Листинг 4.28
//Создаем CommandBar и помещаем его хэндлер в g_hwndCB
g_hwndCB = CommandBar_Create(g_hInst,hWnd, 500);
//Добавляем к списку изображений CommandBar (CB) наши рисунки
CommandBar_AddBitmap(g_hwndCB, g_hInst,IDB_BITMAP1, 2, 16, 16);
//Устанавливаем положение внизу окна
//Закомментируйте эту строку, и CB будет сверху
SendMessage (g_hwndCB, TB_SETSTYLE, 0, (LPARAM)(DWORD)CCS_BOTTOM);
//Добавляем в CB меню
CommandBar_InsertMenubar(g_hwndCB, g_hInst, IDM_MENU, 0);
//Добавляем в CB Combo Box
g_hwndCombo = CommandBar_InsertComboBox (g_hwndCB, g_hInst, 30,
WS_CHILD|WS_VISIBLE,IDC_COMBO1, 1);
//Задаем содержимое Combo Box
for (i=0;i<4;i++)
SendMessage (g_hwndCombo, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)mstr[i]);
//Устанавливаем текущую позицию, выбранную в Combo Box
SendMessage (g_hwndCombo, CB_SETCURSEL, (WPARAM)0, 0);
//Используя структуры свойств кнопок, устанавливаем их параметры
//и добавляем
b_but1.iBitmap = 0;
b_but1.idCommand = 201;
b_but1.fsState = TBSTATE_ENABLED;
//Эта кнопка будет содержать в себе выпадающий список
b_but1.fsStyle =TBSTYLE_BUTTON | TBSTYLE_DROPDOWN;
b_but1.dwData = 0;
b_but1.iString = -1;
CommandBar_InsertButton (g_hwndCB, 2, &b_but1);
//Создаем выпадающий список для кнопки
g_hmCB = CreatePopupMenu;
AppendMenu(g_hmCB,MF_STRING, 1000,TEXT(«AI1»));
AppendMenu(g_hmCB,MF_STRING, 1001, TEXT(« AI2»));
//Следующие две кнопки будут зависеть друг от друга
b_but2.iBitmap = 1;
b_but2.idCommand = 202;
b_but2.fsState = TBSTATE_ENABLED;
b_but2.fsStyle = TBSTYLE_BUTTON|TBSTYLE_CHECKGROUP;
b_but2.dwData = 0;
b_but2.iString = -1;
CommandBar_InsertButton (g_hwndCB, 3, &b_but2);
b_but3.iBitmap = 0;
b_but3.idCommand = 203;
b_but3.fsState = TBSTATE_ENABLED;
b_but3.fsStyle = TBSTYLE_BUTTON|TBSTYLE_CHECKGROUP;
b_but3.dwData = 0;
b_but3.iString = -1;
CommandBar_InsertButton (g_hwndCB, 4, &b_but3);
break;8. Запустить проект. Все должно работать, кроме выпадающего списка. Когда пользователь нажимает кнопку со стрелкой, щелчок на самой кнопке очень легко обработать в ветви WM_COMMAND, выловив идентификатор кнопки. Но вот как обработать щелчок на стрелке, чтобы появился выпадающий список? Теоретически, щелчок на этой стрелке должен генерировать константу TBN_DROPDOWN внутри поля lParam сообщения WM_NOTIFY, но, как выясняется, такой константы в этом поле нет. На самом деле в поле lParam помещается указатель на структуру LPTBNOTIFY, в которой есть поле hdr, в структуру которого входит поле code, в которое и помещается соответствующая константа. Значит, всего-то нужно выловить наличие константы в этом поле. Соответствующий код, располагающийся в процедуре WinProc, приведен в листинге 4.29. Листинг 4.29
case WM_NOTIFY:
//Ловим событие щелчка на стрелке к кнопке
if (((LPTBNOTIFY) lParam)->hdr.code == TBN_DROPDOWN)
{
//Находим углы кнопки, помещаем их в структуру lprc
SendMessage (g_hwndCB, TB_GETRECT, ((LPTBNOTIFY) lParam)->iItem, (LPARAM)(LPRECT)lprc);
//Находим место, где заканчивается окно, и начинается CB
i=CommandBar_Height(g_hwndCB);
//По найденным координатам выводим всплывающее меню так, чтобы оно
//в этой точке оказалось своим нижним правым углом (это задается
//константами TPM_RIGHTALIGN|TPM_BOTTOMALIGN
TrackPopupMenuEx(g_hmCB,TPM_RIGHTALIGN|TPM_BOTTOMALIGN, lprc->right, i, hWnd, NULL);
}
break;9. Программу можно запустить и посмотреть на результат ее работы.
Диалоговые окна
В предыдущем упражнении диалоговое окно уже добавлялось к проекту. Но это было сделано только для того, чтобы использовать помещенный на него компонент Combo Box для встраивания в Command Bar. Тем не менее, если в проекте необходимо использовать окна, выводимые на экран командами меню, то следует придерживаться определенной последовательности действий.
10. Добавить диалоговое окно к ресурсам проекта, как это было сделано в предыдущем упражнении.
11. Разместить на окне элементы управления с панели Controls окна редактирования диалога, как показано на рис. 4.13.
12. Двойным щелчком на каждом из элементов управления вызвать на экран окно настройки его параметров и установить требуемые значения для положения, стиля и поведения компонента.
13. Связать диалоговое окно с командой меню и обеспечить его создание так, как это сделано в шаблонном проекте. Следует обратить внимание на то, как обеспечивается создание диалогового окна (вызов функции DialogBox из обработчика сообщения команды меню IDM_HELP_ABOUT), организуется анализ очереди сообщений (функция LRESULT CALLBACK About) и как окно ликвидируется после использования (обработчик сообщения команды щелчка на кнопке OK диалогового окна, который находится в функции анализа очереди сообщений и вызывает функцию EndDialog). Все эти операции придется проделать с каждым создаваемым диалоговым окном.
14. Обеспечить обработку необходимых сообщений, посылаемых элементами управления, расположенными на диалоговом окне. Естественно, формат книги не позволяет подробно разобрать работу с каждым элементом управления, но это уже сделано в примерах, которые поставляются вместе с SDK. По умолчанию они располагаются в папке C: \Windows СЕ Tools\wce300\Pocket PC 2002\samples\win32.
Примеры, которые поставляются вместе с SDK, приведены в следующем списке.
? CalendarAndDTP – использование элементов управления Calendar и Date Time Picker.
? Cmdbar – использование элемента CommandBar и динамическое изменение кнопок на нем.
? ComCtls – посылка сообщений элементам управления, синхронизированная с «тиками» таймера.
? DirTree работа с компонентом Tree Control.
? Dynamenu – пример вывода и сокрытия пунктов меню во время работы приложения.
? HandleSIP – программное управление режимами и поведением виртуальной клавиатуры.
? Keytest2 – пример того, как перехватываются и обрабатываются сообщения от клавиатуры и стилуса.
? ListView и ListView2 – разные способы применения компонента ListView со значками и организация большого списка с горизонтальной прокруткой.
? ReBar – работа с компонентами ReBar и ToolBar.
? Toolbar – демонстрация работы с компонентом ToolBar.
? TrackStylus – отслеживание и обработка событий стилуса.
Отладка
Несмотря на то что, по логике вещей, любая программа должна быть сначала создана, а потом отлажена, на самом деле отладка проекта обычно происходит параллельно его созданию. Разработчик пишет часть кода, компилирует проект, устраняет ошибки, которые выявляет компилятор и сборщик, затем запускает проект на выполнение и пытается выполнить только что написанный код. Если все работает как положено, то ничего отлаживать не придется. Но бывает так, что при попытке выполнить написанный и скомпилированный код либо генерируется ошибка времени выполнения, либо код работает без ошибок, но делает совсем не то, что
Процесс отладки сводится в основном к тому, чтобы в нужных местах программы расставить точки останова и, когда программа остановится, начать пошаговое выполнение. На каждом шаге необходимо отслеживать значения переменных, правильность выделения памяти, использования ресурсов, открытия файлов, взаимодействия программы с устройствами, а также соответствие логики передачи управления.
Компиляция и сборка для отладкиЧтобы можно было выполнять все необходимые для отладки операции и иметь доступ ко всем используемым в программе именам, программу надо скомпилировать в отладочном варианте. Для компиляции программы под отладку необходимо соответствующим образом настроить среду. Проще всего для этого установить необходимые параметры на панели инструментов WCE configuration, как показано на рис. 4.14.
В первом выпадающем списке этой панели задается имя активного проекта в заданном рабочем пространстве. Во втором выпадающем списке указывается устройство, для которой создается проект. В третьем списке можно выбрать одну из конфигураций, согласно которой будет происходить компиляция и сборка текущего проекта. Обычно в списке есть несколько предустановленных конфигураций, но разработчик может создать свою конфигурацию при помощи команды меню Build ?Configurations… ?Add… и настроить ее согласно своим требованиям при помощи команды меню Project ? Settings…. Четвертый список позволяет задать устройство, на котором будет запускаться скомпилированная программа.
ПРИМЕЧАНИЕ. Для запуска программы на устройстве Pocket PC конфигурацию необходимо выбирать из списка конфигураций для WCE ARM, а для запуска на эмуляторе – из списка WCE x86. Такова суровая правда жизни – эмулятор для Pocket PC не эмулирует машинные команды и не в полной мере эмулирует архетиктуру микропроцессора ARM, на котором собрано устройство Pocket PC. Это можно считать серьезным недостатком, поскольку невозможно установить на эмулятор бинарные файлы для Pocket PC.
Естественно, если вы хотите отлаживать свою программу, вам необходимо выбрать одну из отладочных конфигураций. К ним относятся Win32 (WCEx86) Debug и Win32 (WCE ARM) Debug. Точки останова (breakpoints) и пошаговое выполнение программы
Для того чтобы в нужном месте выполнить программу пошагово, необходимо на этой строке кода установить точку останова. Точка останова ставится либо при помощи команды Insert\Remove Breakpoint из контекстного меню, либо при нажатии соответствующей кнопки панели инструментов WCE Configuration. Кроме этого, установку точки останова можно выполнить, нажав клавишу F9 на клавиатуре. В левом поле окна редактора кода напротив строки, в которой задана точка останова, появится маркер – кружок коричнево-красного цвета. Когда программа останавливается в заранее заданной точке, внутри этого кружка появляется желтая стрелка, как показано на рис. 4.15.
После останова программы в заданной точке можно начать пошаговое выполнение. Для этого можно воспользоваться командами меню Debug. Но гораздо удобнее пользоваться горячими клавишами, которые приведены в следующем списке.
? F11 – отладка с заходом в тело функций. Если очередной командой при пошаговом выполнении оказывается вызов функции, то следующий шаг будет сделан уже внутри тела этой функции.
? F10 – отладка без захода в тело функций. Если очередной командой оказывается вызов функции, то эта строка проходится так же точно, как и все остальные. Функция выполняется за один шаг.
? Shift+F11 – выход из тела функции. Если, войдя в функцию в процессе пошагового выполнения программы, разработчик увидел все, что ему было нужно, и необходимость дальше продолжать пошаговое выполнение внутри функции отпала, то это сочетание клавиш выполнит оставшиеся шаги за один раз и передаст управление следующему за функцией оператору.
? Ctrl+F10 – нажатие этого сочетания клавиш приведет к выполнению кода в обычном режиме и остановке в строке, в которой в редакторе кода находится в данный момент текстовый курсор.
Перемещение желтой стрелки по левому полю редактора кода указывает, на какую строку в исходном коде передается управление ходом выполнения программы.
Отображение и модификация значений переменныхСмысл пошагового выполнения программы не только в том, чтобы проследить, правильно ли передается управление ходом выполнения кода, но и в том, чтобы проверить, какие значения принимают те или иные переменные. Для этого среда eVC предоставляет в распоряжение программиста окна Watches и Variables.
В окне Variables отображаются локальные переменные той функции, в которой сейчас происходит выполнение программы (рис. 4.16).
Содержимое окна может меняться в процессе выполнения программы. Это окно позволяет как просматривать, так и редактировать значения переменных. Окно имеет три вкладки. На вкладке Auto отображаются переменные, имеющие смысл в текущей и предыдущей строке кода. На вкладке Locals отображаются все локальные переменные, которые активны в данный момент. На вкладке This отображается информация обо всех переменных, именах и значениях, доступ к которым может быть осуществлен через указатель на переменную this.
? На вкладке Auto отображаются также значения, возвращаемые функциями. Эти значения появляются при передаче управления инструкции, следующей за вызовом функции.
? Окно Watches предназначено для контроля и изменения значений произвольных переменных (рис 4.17):
? Чтобы добавить в окно переменную, значение которой нужно отслеживать в ходе выполнения программы, достаточно ввести ее имя в колонку Name. Но можно и просто щелкнуть в коде на имени переменной правой клавишей мыши, а затем из контекстного меню выбрать команду QuickWatch и нажать кнопку Add Watch.
Настройки среды
? Все настройки среды осуществляются в окнах, вызываемых на экран командами Tools ? Customize… и Tools ? Options…. Команда Customize уже рассматривалась ранее, поэтому сейчас нужно сосредоточить свое внимание на команде Options. По этой команде на экран выводится следующее окно с множеством вкладок (рис. 4.18).