Программирование для карманных компьютеров
Шрифт:
Компоненты Common Controls, меню и редактор ресурсов
Меню
При создании простого приложения среда сама создает строку главного меню, из которого вызывается диалоговое окно About. Эта линейка служит основой для создания главного меню приложения, которое может быть сколь угодно сложным. По большому счету, вся работа по созданию меню заключается в работе с редактором ресурсов и написании обработчиков сообщений, которые принимаются от соответствующих пунктов меню.
Упражнение 4.5
1. Создать простое приложение и сохранить его с именем Menu.
2. В окне Workspace перейти на вкладку ResourceView, открыть корневую папку Menu resources и в ней раскрыть папку Menubar. Внутри папки располагается элемент IDM_MENU. Двойной щелчок на этом элементе откроет редактор меню (рис. 4.7).
Рис. 4.7. Редактор меню.
3. Если в редакторе меню выделить уже созданный пункт (Tools), то его можно будет редактировать. Если требуется создать новый пункт меню, необходимо совершить двойной щелчок на пустом прямоугольнике справа от существующего пункта меню. На экран будет выведено окно редактирования нового пункта меню (рис. 4.8).
4. Теперь следует дважды щелкнуть на прямоугольнике справа от команды Tools и установить для этого пункта меню флажок General ? Separator. Это приведет к созданию вертикального разделителя на строке меню.
5. Следующий прямоугольник справа позволяет создать еще один пункт меню. Для него свойство Caption должно получить значение File. Также следует взвести флажки Pop-up, Autosize и No wrap.
6. Подняться на один прямоугольник вверх. Для нового пункта меню свойство Caption должно получить значение File1.
7. Подняться на один прямоугольник вверх. Для нового пункта меню свойство Caption должно получить значение File2, а свойство Break – значение Bar.
8. Подняться на один прямоугольник вверх и взвести флажок Separator.
9. Подняться на один прямоугольник вверх. Для нового пункта меню свойство Caption должно получить значение File3. Также необходимо взвести флажок Checked.
10. В результате этих действий должна получиться структура меню, показанная на рис. 4.9.
11. Сместиться на один прямоугольник вправо на основной строке меню. Для него свойство Caption должно получить значение Edit. Также следует взвести флажки Pop-up, Autosize и No wrap.
12. Подняться на один прямоугольник вверх. Для нового пункта меню свойство Caption должно получить значение Ed1. Также следует взвести флажок Pop-up.
13. Подняться на один прямоугольник вверх. Для нового пункта меню свойство Caption должно получить значение Ed2.
14. Подняться на один прямоугольник вверх и взвести флажок Separator.
15. Подняться на один прямоугольник вверх. Для нового пункта меню свойство Caption должно получить значение Ed3.
16. Выделить пункт Ed1, переместиться на пустой прямоугольник справа, и для нового пункта меню установить значение свойства Caption равным E1.
17. Подняться на один прямоугольник вверх. Для нового пункта меню свойство Caption должно получить значение E2, а свойство Break – значение Column. Также нужно взвести флажок Checked.
18. Подняться на один прямоугольник вверх. Для нового пункта меню свойство Caption должно получить значение E3. Также нужно взвести флажок Checked.
19. На рис. 4.10 показана структура созданного меню.
20. Сдвинуться на один прямоугольник вправо на основной строке меню и взвести флажок Separator.
21. Сдвинуться на один прямоугольник вправо на основной строке меню и взвести флажки CheckButton, Group, Autosize, No wrap, Pressed и Bitmap. Свойство Bitmap Index должно получить нулевое значение.
22. Сдвинуться на один прямоугольник вправо на основной строке меню и взвести флажки CheckButton, Group, Autosize, No wrap и Bitmap. Свойство Bitmap Index должно получить значение 1.
23. Сдвинуться на один прямоугольник вправо на основной строке меню и взвести флажок Separator.
24. Подняться на один прямоугольник вверх. Для нового пункта меню свойство Caption должно получить значение UnGroup. Также нужно взвести флажки CheckButton, Autosize, No wrap и Pressed.
25. Результат должен получиться такой, как показано на рис. 4.11.
26. Кое-что может смутить разработчика. Картинки для кнопок еще не выбраны, а вместо них уже появились изображения кактусов. К тому же свойство Break ничего не изменило. Что ж, все это вполне поправимо. Свойство Break срабатывает только во время выполнения приложения, а с картинками мы сейчас разберемся.
27. Щелкнуть правой кнопкой мыши внутри дерева ресурсов на панели Resource View и выполнить команду контекстного меню Insert. В выведенном на экран окне нужно выбрать тип ресурса Bitmap и нажать кнопку New. В дереве ресурсов появится новая папка Bitmap, а в ней ресурс с идентификатором IDB_ BITMAP1. Если дважды щелкнуть по идентификатору ресурса, то в редакторе справа будет открыто для редактирования пустое изображение. Прежде всего нужно изменить размер изображения. Для этого достаточно просто перетащить мышью правый нижний угол изображения. После начала перетаскивания углового маркера на строке состояния среды будут отображаться цифры горизонтального и вертикального значений размера. Необходимо добиться размера 32x16, поскольку в одном изображении будут храниться картинки для двух кнопок, каждая размером 16x16. После получения картинки требуемого размера нужно на ней создать графическое изображение, показанное на рис. 4.12.
28. Сохранить проект. Перейти на вкладку File View и открыть для редактирования файл menu.cpp. В этом файле нужно найти реализацию функции CreateRpCommandBar, после чего ее нужно изменить так, как показано в листинге 4.22. Листинг 4.22
mbi.nBmpId = 0;
mbi.cBmpImages = 0;
на:
mbi.nBmpId = IDB_BITMAP1;
mbi.cBmpImages = 2;Этот фрагмент кода подключает изображение к меню и указывает, что в данном ресурсе хранятся изображения для двух кнопок. 29. Теперь нужно создать обработчики событий щелчка на том или ином пункте меню. Это будет сделано для одного пункта меню, который обозначен как File2. Ему автоматически присваивается идентификатор ID_FILE_FILE2. Это можно проверить, перейдя на вкладку Resource View и дважды щелкнув на соответствующей кнопке меню в редакторе ресурсов. В начале процедуры WndProc нужно объявить две переменных.
HMENU hMenu = NULL; MENUITEMINFO lpmii;
Это идентификатор меню (hMenu) и переменная, содержащая в своей структуре
//если команда была сгенерирована щелчком на кнопке меню File2…
case ID_FILE_FILE2:
//…то извлечь указатель на конкретный пункт меню при помощи посылки
//сообщения SHCMBM_GETSUBMENU окну главного меню (g_hwndCB) с
//идентификатором пункта меню, на элемент которого мы хотим получить
//ссылку (ID_FILE)
hMenu = (HMENU)SendMessage(g_hwndCB, SHCMBM_GETSUBMENU, 0, ID_FILE);
//получив hMenu, мы извлекаем всю информацию об интересующем нас
//элементе меню по его идентификатору и помещаем ее в переменную lpmii:
GetMenuItemInfo(hMenu, ID_FILE_FILE2, false, &lpmii);
//проверяем поле fState структуры lpmii (то есть состояние
//соответствующего элемента меню:
if (lpmii.fState == 0)
//если состояние Unchecked, то устанавливаем флажок
CheckMenuItem(hMenu, ID_FILE_FILE2, MF_BYCOMMAND|MF_CHECKED);
else
//если состояние Checked, то сбрасываем флажок
CheckMenuItem(hMenu, ID_FILE_FILE2, MF_BYCOMMAND|MF_UNCHECKED);
break;30. Завершить упражнение можно созданием контекстного меню для данной формы. Для этого нужно объявить переменную меню там же, где объявлена переменная меню g_hwndCB.
HMENUg_hmPopup;
31. Создать меню в обработчике сообщения WM_CREATE сразу после всех операций по созданию меню и добавить к этому меню несколько пунктов, как показано в листинге 4.24. Листинг 4.24
g_hmPopup = CreatePopupMenu;
AppendMenu(g_hmPopup,MF_STRING, 1000,TEXT(«pop 1»));
AppendMenu(g_hmPopup,MF_STRING, 1001, TEXT(«pop 2»));
AppendMenu(g_hmPopup,MF_STRING, 1002,TEXT(«pop 3»));
AppendMenu(g_hmPopup,MF_STRING|MF_MENUBARBREAK, 1003, TEXT(«pop 4»));
AppendMenu(g_hmPopup,MF_STRING|MF_CHECKED, 1004,TEXT(«pop 5»));
AppendMenu(g_hmPopup,MF_STRING, 1005, TEXT(«pop 6»));32. Теперь нужно создать обработчик для вызова меню при щелчке правой кнопкой мыши, как показано в листинге 4.25. Листинг 4.25
case WM_LBUTTONDOWN:
{
WORD xPos = LOWORD(lParam); // horizontal position of the cursor
WORD yPos = HIWORD(lParam); // vertical position of the cursor
if (g_hmPopup){
TrackPopupMenuEx(g_hmPopup,0, xPos, yPos, hWnd, NULL);
}
}
break;33. Запустить проект. Легко убедиться, что всплывающее меню работает так, как надо.
Стоит подробнее рассмотреть диалоговое окно создания и редактирования пункта меню. В этом окне три вкладки, на каждой из которых находятся элементы управления. Органы управления вкладки General перечислены в следующем списке.
? ID – идентификатор команды меню, по которому приложение будет обращаться к этой команде для обработки событий или манипуляций с данной кнопкой.
? Caption – название команды меню.
? Caption ID – идентификатор строкового ресурса, в котором хранится название команды меню.
? Pop-Up – установка этого флажка говорит о том, что данный пункт меню имеет подменю, которые будут выведены во всплывающем окне. В редакторе меню при выделении пункта меню с включенным свойством Pop-up над этим пунктом появляется прямоугольник, позволяющий редактировать всплывающее меню.
? Separator – установка этого флажка превращает данный пункт меню в разделитель.
? Shared New – выводит в строку меню кнопку New, предназначенную для создания нового пустого документа.
? Prompt – текст, предназначенный для автоматического показа в строке состояния, когда выбрана данная команда меню.
? Свойство Break имеет три состояния. Значение None указывает, что свойство не активно. Значение Column говорит о том, что данный пункт меню начинает следующий вертикальный столбец, а значение Bar указывает, что данный пункт меню начинает следующий вертикальный столбец, отделенный от предыдущего вертикальной линией.
В следующем списке рассматриваются органы управления, расположенные на вкладке Styles.
? Check Button – при установке данного флажка кнопка меню становится западающей. После первого щелчка мышью она переходит в нажатое состояние, после второго – возвращается в исходное состояние.
? Group – установка данного флажка позволяет создавать группу кнопок. Это имеет смысл, когда кнопки все имеют стиль Check Button. Тогда нажатие одной кнопки вызывает автоматическое отжатие другой кнопки в группе.
? Auto Size – автоматически меняет размер кнопки при изменении надписи.
? No wrap – установка флажка не позволяет переносить текст на другую строку.
? Pressed – нажатая кнопка при создании меню. Имеет смысл для кнопки со стилем Check Button.
? Grayed – кнопка будет окрашена в серый цвет и станет неактивна.
? Indeterminate – кнопка неопределенного стиля, активная, но серая.
? Hidden – скрытая кнопка.
? Highlighted – надпись кнопки подкрашена в контрастный цвет.
И наконец, в последнем списке рассматривается предназначение органов управления, расположенных на вкладке More Styles.
? Bitmap – кнопка вместо надписи несет на себе изображение.
? Bitmap index – уникальный индекс, идентифицирующий номер изображения в наборе изображений, подключенных к меню.
Однако меню не исчерпывает все потребности при создании набора команд. Гораздо большую гибкость дает элемент управления CommandBar.
CommandBar
Рассмотрение возможностей этого органа управления лучше начать с конкретного примера, который приведен в следующем разделе.
Упражнение 4.6
1. Создать простое приложение и сохранить его с именем CommandBar.
2. В окне Workspace перейти на вкладку ResourceView, открыть корневую папку Menu resources и в этой папке перейти в подкаталог Menubar. Существующее меню нужно отредактировать так, чтобы оно содержало команды Tools, File и Edit. Не надо добавлять дополнительные элементы в меню, создавать подменю и совершать прочие действия, которые уже рассматривались в предыдущем упражнении. Данное меню будет нужно только для демонстрации использования ресурса меню при помещении его в CommandBar.
3. Как и в прошлом упражнении, добавить к ресурсам изображение для кнопок.
4. Щелкнуть внутри дерева ресурсов правой клавишей мыши на папке Dialogs и в контекстном меню выполнить команду Insert Dialog. В папку будет добавлен еще один диалог с идентификатором IDD_DIALOG1. Теперь нужно перейти в правую часть окна, в редактор диалога. На панели Controls следует отыскать компонент Combo Box и поместить его на окно диалога.
5. Перейти в редактор кода, и в файле CommandBar.cpp добавить код, приведенный в листинге 4.26.
Листинг 4.26//объявить хэндлеры для меню, компонентов CommandBar и Combo Box
HWNDg_hwndCombo, g_hwndMenu;
HMENUg_hmCB;
//объявление структуры для кнопок:
static TBBUTTON b_but1, b_but2, b_but3;