Волков Владимир
Шрифт:
HWNDg_hwndComB, g_hwndLnEd, g_hwndPass, g_hwndList, g_hwndMlnEd; HWNDg_hwndBtn1, g_hwndBtn2, g_hwndBtn3;
Это идентификаторы всех элементов, которые будут созданы на форме.
4. В начале функции WndProc, там, где объявляются локальные переменные, допишите объявление еще нескольких переменных, как показано в листинге 4.19.
Листинг 4.19int i;
wchar_t *mstr[]={L" Elly", L" Totoshka", L" Strashila", L" Bastinda", L" Gingema", L" Elly",
L" Totoshka", L" Strashila", L" Bastinda", L" Gingema", L" Elly", L" Totoshka",
L" Strashila", L" Bastinda", L" Gingema"};
wchar_t tmp[128];5. В этой же функции, в начале блока, помеченного комментарием Parse the menu selections, нужно разместить код, приведенный в листинге 4.20. Листинг 4.20
switch (wmId)
{
//Начало нашего кода:
case 200:
if(wmEvent == CBN_SELCHANGE)
{
SendMessage (g_hwndComB, CB_SETCURSEL, SendMessage (g_hwndComB,
CB_GETCURSEL, 0, 0), 0);
SendMessage (g_hwndComB, WM_COPY, 0, 0);
SendMessage (g_hwndMlnEd, WM_PASTE, 0, 0);
SendMessage (g_hwndMlnEd, EM_REPLACESEL, 0, (LPARAM)(LPCSTR)L"\r\n");
}
break;
case 201:
if (wmEvent == LBN_DBLCLK)
{
SendMessage (g_hwndList, LB_GETTEXT, SendMessage (g_hwndList,
LB_GETCURSEL, 0, 0), (LPARAM)(LPCTSTR)tmp);
SendMessage (g_hwndComB, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)tmp);
}
break;
case 205:
SendMessage (g_hwndPass, WM_GETTEXT, 20, (LPARAM)tmp);
SendMessage (g_hwndComB, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)tmp);
break;
case 206:
SendMessage (g_hwndLnEd, WM_GETTEXT, 20, (LPARAM)tmp);
SendMessage (g_hwndList, LB_ADDSTRING, 0, (LPARAM)(LPCSTR)tmp);
break;
case 207:
SendMessage (g_hwndMlnEd, WM_SETTEXT, 0, (LPARAM)(LPCSTR)"");
break;6. В ветвь case WM_CREATE непоредственно перед оператором прерывания break нужно добавить код, приведенный в листинге 4.21. Листинг 4.21
//Создаем ComboBox. Параметр WS_NOTIFY позволяет этому элементу
//передавать щелчки мышью в основное окно приложения
g_hwndComB = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT(«COMBOBOX»),
TEXT(""), WS_NOTIFY|CBS_AUTOHSCROLL|WS_VSCROLL |WS_BORDER |WS_VISIBLE |WS_CHILD, 10,
10, 95, 100, hWnd, (HMENU)200, g_hInst, NULL);
//Создаем ListBox.
g_hwndList = CreateWindowEx(WS_EX_DLGMODALFRAME, TEXT("LISTBOX "), TEXT(""),
LBS_NOTIFY|WS_VSCROLL |WS_BORDER| WS_VISIBLE |WS_CHILD, 135, 10, 95, 100, hWnd,
(HMENU)201, g_hInst, NULL);
//И тут же заполняем его элементами из ранее объявленного массива
//Все взаимодействия с компонентами происходят через Windows Messages
for (i = 0; i<15; i++)
{
SendMessage (g_hwndList, LB_ADDSTRING, i+1, (LPARAM)mstr[i]);
};
//Строка ввода пароля, определяется наличием параметра ES_PASSWORD
//Вводимые символы будут отображаться звездочками
g_hwndPass = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, TEXT(«EDIT»), TEXT(""), ES_PASSWORD
|WS_VISIBLE |WS_CHILD, 10, 115, 95, 25, hWnd, (HMENU)202, g_hInst, NULL);
//Простой однострочный редактор текста
g_hwndLnEd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, TEXT(«EDIT»), TEXT(""), WS_VISIBLE
|WS_CHILD, 135, 115, 95, 25, hWnd, (HMENU)203, g_hInst, NULL);
//Многострочный редактор текста с вертикальной прокруткой //(ES_MULTILINE|
ES_AUTOVSCROLL|WS_VSCROLL)
g_hwndMlnEd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, TEXT(«EDIT»), TEXT(""),
ES_NOHIDESEL| ES_MULTILINE|ES_AUTOVSCROLL|WS_VSCROLL |WS_VISIBLE |WS_CHILD, 10, 150,
220, 110, hWnd, (HMENU)204, g_hInst, NULL);
//И наконец, три самые обыкновенные кнопки
g_hwndBtn1 = CreateWindowEx(WS_EX_WINDOWEDGE, TEXT(«BUTTON»), TEXT("1"), BS_PUSHBUTTON
|WS_VISIBLE |WS_CHILD, 110, 10, 20, 40, hWnd, (HMENU)205, g_hInst, NULL);
g_hwndBtn2 = CreateWindowEx(WS_EX_WINDOWEDGE, TEXT(«BUTTON»), TEXT("2"), BS_PUSHBUTTON
|WS_VISIBLE |WS_CHILD, 110, 55, 20, 40, hWnd, (HMENU)206, g_hInst, NULL);
g_hwndBtn3 = CreateWindowEx(WS_EX_WINDOWEDGE, TEXT(«BUTTON»), TEXT("3"), BS_PUSHBUTTON
|WS_VISIBLE |WS_CHILD, 110, 100, 20, 40, hWnd, (HMENU)207, g_hInst, NULL);7. Запустить приложение. Его внешний вид показан на рис. 4.6.
8. В этом окне двойной щелчок на элементе списка ListBox копирует этот элемент в изначально пустой список ComboBox. Выбор элемента в списке ComboBox добавляет его в многострочный редактор, располагающийся в нижней части страницы. Строка, введенная в левый однострочный редактор текста будет отображаться в виде звездочек, но при щелчке на кнопке 1 будет добавлена к списку ComboBox в нормальном виде. Строка, введенная в правый однострочный редактор кода, будет добавлена в список ListBox после нажатия кнопки 2. Редакторы также позволяют выделять фрагменты текста, копировать, вырезать и вставлять этот текст из буфера обмена при помощи сочетаний клавиш Ctrl+X, Ctrl+C и Ctrl+V.
9. Теперь необходимо рассмотреть код, который был введен в обработчик события WM_COMMAND. Выбором case определяется, какой из элементов управления сгенерировал данное событие. Эта информация извлекается из младшего слова сообщения wParam, которое хранится в переменной wmId. При использовании кнопок событие WM_COMMAND означает, что пользователь нажал кнопку. С органами управления ListBox или ComboBox все не так просто. Сообщение WM_ COMMAND может поступить от разных событий. Для точного определения команды нужно воспользоваться старшим словом wParam, которое размещается в переменной wmEvent.
10. В ветке case 200 заложено достаточно много интересных действий. Прежде всего посылается сообщение CB_SETCURSEL, третьим аргументом для которого служит возвращаемый результат предварительного посланного сообщения CB_GETCURSEL. Если этого не сделать, то в ComboBox будет выбрано не то содержимое редактора, которое пользователь выбрал из списка, а предыдущее. Для проверки можно просто закомментировать эту строку. Также следует отметить, что для всех редакторов текста, в том числе для компонента Edit, входящего в состав ComboBox, работают сообщения WMCOPY, WM_PASTE и WM_CUT, осуществляющие стандартные операции редактирования. Последняя строка при помощи сообщения EM_REPLACESEL добавляет в конец только что вставленной строки «жесткий» перевод строки. На самом деле сообщение это призвано заменять выделенный фрагмент в тексте на новый, но поскольку у нас ничего не выделено, то новый фрагмент просто вставляется в позицию курсора. Обратите внимание на сочетание символов для перевода строки \г\п. Оно должно быть только таким, порядок расположения символов важен.
11. В ветви case 201 можно убедиться, что был произведен именно двойной щелчок на компоненте ListBox (wmEvent = LBN_DBLCLK). После этого в строковую переменную tmp записывается текущее строковое значение элемента, выбранного в ListBox, а сама переменная отправляется в ComboBox.
12. В ветвях case 205 и case 206 по щелчку на кнопке извлекается текущее значение текста из однострочных редакторов, которое потом добавляется в список элементов ListBox или ComboBox.
13. В целом это упражнение является достаточно полной иллюстрацией приемов работы с компонентами Edit, ListBox и ComboBox. Конечно же, в этом упражнении не были исчерпаны все возможности этих компонентов, но достаточно ясно были обозначены пути дальнейшего развития приложения.
SCROLLBAR и STATICДва этих компонента не представляют особых трудностей в использовании. Компонент SCROLLBAR можно использовать для организации полос прокрутки основного окна приложения или для создания индикатора с указателем прогресса.
При использовании компонента SCROLLBAR необходимо учитывать, что этот компонент генерирует и принимает сообщения, указанные в следующем списке.
? Сообщения WMJHSCROLL и WMJHSCROLL посылаются родительскому окну при изменении положения движка компонента.
? Сообщения SBMGETSCROLLINFO и SBMSETSCROLLINFO посылаются компоненту для установки его параметров и положения движка.
Кроме этого существуют функции API SetScrollInfo и GetScrollInfo, выполняющие те же самые действия, но без явной посылки сообщения.
Компонент STATIC позволяет вывести на определенное место формы статический текст или изображение, хранящееся в файле ресурсов. Этот компонент настолько прост, что в отдельном рассмотрении не нуждается.Компоненты 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 показана структура созданного меню.