прямоугольник rcWork используется оконной процедурой WndProc при вызове функции InvalidateRect, чтобы ограничить обновляемый регион только видимой частью клиентской области.
Диалоговая процедура ModelessDlgProc осуществляет обработку сообщений от полос прокрутки IDC_RED, IDC_GREEN и IDC_BLUE. Элементы управления типа Vertical Scroll Bar посылают родительскому окну такие же сообщения, как и вертикальная полоса прокрутки главного окна приложения. Пример обработки этих сообще ний мы уже рассматривали в приложении TextViewer (см. листинг 2.2).
В результате обработки сообщений от полос прокрутки изменяются значе ния глобального массива rgb, в котором хранятся текущие величины для RGB компонентов цвета. Если изменилось хотя бы одно из значений, то диалоговая процедура при помощи функции SendMessage посылает пользовательское сооб щение UM_CHANGE, адресуя его оконной процедуре родительского окна. Константа UM_CHANGE является значением перечисляемого типа UserMsg, который опреде лен оператором enum.
Оконная процедура WndProc содержит код обработки сообщения UM_CHANGE. В этом блоке вызывается функция SetClassLong для изменения цвета фона главно го окна приложения. Чтобы окно перерисовалось, нужно также вызвать функцию InvalidateRect. Обратите внимание на то, что если в качестве второго аргумента функции InvalidateRect передать NULL, то при перерисовке возникнет неприятное мерцание фона диалогового окна.
Уничтожение диалогового окна происходит в блоке обработки сообщения
WM_DESTROY.
Последнее замечание: если для диалогового окна IDD_MODELESS на вкладке Styles окна Dialog Properties задать стиль Popup, то в теле функции AdjustDlgPlace для уста новки позиции окна следует вызывать первую версию перегруженной функции
ShiftWindow:
ShiftWindow(hDlg, 0, 0, 0, dH);
Окно работающего приложения ModelessDlg показано на рис. 7.34.
Рис. 7.34. Приложение ModelessDlg
К сожалению, черно белый рисунок не может передать всей красоты нежней шего светло салатового цвета в клиентской области окна, который установлен в настоящий момент элементами управления диалогового окна Öâåò ôîíà.
372 |
Глава 7. Диалоговые окна |
|
|
Окно сообщений
Окно сообщений, которое вызывается функцией MessageBox, является простей шим типом диалогового окна. В предыдущих проектах эта функция уже неод нократно применялась, но при этом были использованы далеко не все ее воз можности.
Функция MessageBox позволяет создавать, отображать и выполнять различные действия с окном сообщения. Окно сообщения содержит текст, определяемый приложением, и заголовок, а также любое сочетание предопределенных пикто грамм и кнопок.
Функция MessageBox чаще всего используется для сообщений об ошибках и предупреждающих сообщений. Иногда ее применяют для отладочной печати данных в качестве замены оператора printf в консольных приложениях. Также окна сообщения могут использоваться в качестве функций заглушек при разработке программы. Например, окна сообщений могут вызываться для пунктов меню, ко торые еще не реализованы.
Функция имеет следующий прототип:
int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
Параметр hWnd принимает дескриптор родительского окна. Если этот параметр равен NULL, то окно сообщения не имеет окна владельца.
Параметр lpText является указателем на C строку, содержащую текст, который должен быть отображен в окне. Вы можете использовать в составе строки управ ляющие символы \n, если хотите сделать текст многострочным.
Параметр lpCaption является указателем на C строку, которая отображается в заголовке диалогового окна. Если этот параметр равен NULL, то применяется за данный по умолчанию заголовок Error.
Параметр uType определяет содержимое и правила поведения диалогового окна. Его значением может быть комбинация флагов из групп флагов, которые приве дены в табл. 7.13–7.15.
Для указания состава отображаемых кнопок используйте одно из значений, приведенных в табл. 7.13.
Таблица 7.13. Флаги, определяющие состав кнопок
Ôëàã |
Описание |
|
|
MB_CANCELTRYCONTINUE |
Окно сообщений содержит кнопки Cancel, Try Again, Continue |
MB_HELP |
Добавляет кнопку Help в окно сообщений. Когда пользователь |
|
нажимает эту кнопку, система посылает сообщение WM_HELP |
|
окну-владельцу |
MB_OK |
Окно сообщений содержит единственную кнопку OK. Это |
|
значение применяется по умолчанию |
MB_OKCANCEL |
Окно сообщений содержит кнопки OK и Cancel |
MB_RETRYCANCEL |
Окно сообщений содержит кнопки Retry и Cancel |
MB_YESNO |
Окно сообщений содержит кнопки Yes и No |
MB_YESNOCANCEL |
Окно сообщений содержит кнопки OK, No и Cancel |
|
|
Чтобы указать отображаемую пиктограмму, нужно выбрать одно из значений, приведенных в табл. 7.14.
Окно сообщений |
373 |
|
|
|
Таблица 7.14. Флаги, определяющие отображаемую пиктограмму |
|
|
|
Ôëàã |
Описание |
|
|
|
|
MB_ICONEXCLAMATION, |
Пиктограмма с изображением восклицательного знака |
|
MB_ICONWARNING |
|
|
MB_ICONINFORMATION, |
Пиктограмма с изображением буквы «i» |
|
MB_ICONASTERISK |
|
|
MB_ICONQUESTION |
Пиктограмма с изображением вопросительного знака |
|
MB_ICONSTOP, |
Пиктограмма с изображением знака «Стоп» |
|
MB_ICONERROR, MB_ICONHAND |
|
|
|
|
Чтобы указать «вид модальности», используйте одно из значений, приведен ных в табл. 7.15.
Таблица 7.15. Флаги, определяющие вид модальности окна сообщений
Ôëàã |
Описание |
|
|
MB_APPLMODAL |
Пользователь должен щелкнуть на одной из кнопок в окне сообщения, |
|
прежде чем сможет продолжить работу с окном, указанным в пара- |
|
метре hWnd. Пока окно сообщений не закрыто, окно hWnd и все его |
|
дочерние окна недоступны. Однако окна стиля «popup», открытые ранее |
|
в данном приложении, доступны для работы с ними. Пользователь также |
|
может переключиться в окна других приложений и работать с ними |
MB_SYSTEMMODAL |
Поведение окна сообщений такое же, как и с флагом MB_APPLMODAL, за |
|
исключением того, что окно сообщений имеет стиль WS_EX_TOPMOST, то |
|
есть располагается всегда поверх других окон. Рекомендуется использо- |
|
вать этот флаг для сообщений о серьезных ошибках или проблемах, |
|
требующих немедленной реакции пользователя |
MB_TASKMODAL |
Поведение окна сообщений такое же, как и с флагом MB_APPLMODAL, за |
|
исключением того, что, если параметр hWnd равен NULL, недоступными |
|
будут все окна данного приложения. Этот флаг используется обычно |
|
в тех ситуациях, когда дескриптор окна-владельца неизвестен (например, |
|
при разработке библиотек) |
|
|
Есть и другие, реже применяемые флаги, которые перечислены в справочных материалах MSDN.
Если функция завершается успешно, она возвращает одно из следующих зна чений:
Возвращаемое значение |
Описание |
|
|
IDABORT |
Была выбрана кнопка Abort |
IDCANCEL |
Была выбрана кнопка Abort или нажата клавиша Esc |
IDCONTINUE |
Была выбрана кнопка Continue |
IDIGNORE |
Была выбрана кнопка Ignore |
IDNO |
Была выбрана кнопка No |
IDOK |
Была выбрана кнопка OK |
IDRETRY |
Была выбрана кнопка Retry |
IDTRYAGAIN |
Была выбрана кнопка Try Again |
IDYES |
Была выбрана кнопка Yes |
|
|
Если произошла какая то ошибка, то функция возвращает нулевое значение. Технику применения функции MessageBox довольно легко понять, поэтому спе
циальные примеры в этой главе не приводятся.
374 |
Глава 7. Диалоговые окна |
|
|
Диалоговые окна общего пользования
Одна из важнейших целей, поставленных перед разработчиками системы Windows, заключалась в том, чтобы способствовать разработке приложений со стандартизи рованным интерфейсом пользователя. Для многих общепринятых пунктов меню это было сделано довольно быстро. Почти все разработчики программного обеспе чения стали использовать последовательность команд File Open (Файл Открыть) для вызова диалогового окна, при помощи которого пользователь мог открыть файл. Однако сами окна диалога для открытия файла часто были не очень похожи друг на друга.
Начиная с версии Windows 3.1, решение этой проблемы было реализовано
ввиде библиотеки диалоговых окон общего пользования (Common Dialog Box Library). Библиотека содержит несколько функций, которые вызывают стандартные окна диалога для открытия и сохранения файлов, поиска и замены, выбора цвета, выбо ра шрифта и другие стандартные окна.
Для каждой функции, создающей и вызывающей стандартное диалоговое окно,
взаголовочном файле commdlg.h определен соответствующий тип структуры. Что бы работать со стандартным диалогом, вы должны определить подходящую струк турную переменную и инициализировать ее. После этого вызывается функция стандартного диалога, которой передается адрес этой структурной переменной. Когда пользователь закрывает окно диалога, вызванная функция возвращает уп равление программе. В этот момент вы можете получить требуемую информацию из указанной структурной переменной.
Вдемонстрационном приложении CommonDialogs, которое мы сейчас разрабо таем, иллюстрируется, как можно использовать стандартные диалоговые окна Open (Открыть), Save As (Сохранить как), Color (Цвет) и Font (Шрифт).
Создайте новый проект с именем CommonDialogs.
Добавьте к приложению ресурс меню с идентификатором IDR_MENU1. Главное меню должно содержать пункты с атрибутами, указанными в табл. 7.16.
Таблица 7.16. Пункты главного меню
Имя пункта |
Тип пункта |
Идентификатор |
|
|
|
&File |
Подменю |
— |
&Background color |
Команда |
IDM_BKGR_COLOR |
&Text color |
Команда |
IDM_TEXT_COLOR |
&Choose font |
Команда |
IDM_CHOOSE_FONT |
|
|
|
Подменю File должно содержать пункты с атрибутами, приведенными в табл. 7.17.
Таблица 7.17. Пункты подменю File
Имя пункта |
Тип пункта |
Идентификатор |
|
|
|
&Open… |
Команда |
IDM_OPEN |
Save &As… |
Команда |
IDM_SAVE_AS |
— |
SEPARATOR |
— |
E&xit |
Команда |
IDM_EXIT |
|
|
|
Добавьте в состав проекта файл CommonDialogs.cpp с текстом, приведенным в листинге 7.7.
Диалоговые окна общего пользования |
375 |
|
|
|
Листинг 7.7. Проект CommonDialogs
//////////////////////////////////////////////////////////////////////
// CommonDialogs.cpp #include <windows.h> #include <stdio.h> #include "KWnd.h" #include "resource.h"
#define ESC_OF "Отказ от выбора или ошибка выполнения функции "
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //==================================================================== int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("CommonDialogs", hInstance, nCmdShow, WndProc, MAKEINTRESOURCE(IDR_MENU1), 100, 100, 400, 300);
while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg);
}
return msg.wParam;
}
//==================================================================== LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC; PAINTSTRUCT ps; RECT rcClient; BOOL success;
static COLORREF textColor;
//Переменные для стандартных диалогов "Open", "Save As" static OPENFILENAME ofn;
static char szFile[MAX_PATH];
//Переменные для стандартного диалога "Color"
static CHOOSECOLOR cc; // common dialog box structure static COLORREF acrCustClr[16]; // array of custom colors
// Переменные для стандартного диалога "Font" static CHOOSEFONT chf;
static HFONT hFont; static LOGFONT lf;
switch (uMsg)
{
case WM_CREATE:
// Инициализация структуры ofn ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hWnd;
ofn.lpstrFile = szFile; ofn.nMaxFile = sizeof(szFile);
// Инициализация структуры cc
продолжение
376 |
Глава 7. Диалоговые окна |
|
Листинг 7.7 (продолжение) |
cc.lStructSize |
= sizeof(CHOOSECOLOR); |
cc.hwndOwner = hWnd;
cc.lpCustColors = (LPDWORD) acrCustClr; cc.Flags = CC_FULLOPEN | CC_RGBINIT;
// Инициализация структуры chf chf.lStructSize = sizeof(CHOOSEFONT); chf.hwndOwner = hWnd;
chf.lpLogFont = &lf;
chf.Flags = CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT; chf.nFontType = SIMULATED_FONTTYPE;
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDM_OPEN: strcpy(szFile, "");
success = GetOpenFileName(&ofn); if (success)
MessageBox(hWnd, ofn.lpstrFile, "Открывается файл:", MB_OK); else
MessageBox(hWnd, ESC_OF"GetOpenFileName", "Отказ от выбора или ошибка", MB_ICONWARNING);
break;
case IDM_SAVE_AS: strcpy(szFile, "");
success = GetSaveFileName(&ofn); if (success)
MessageBox(hWnd, ofn.lpstrFile,
"Файл сохраняется с именем:", MB_OK); else
MessageBox(hWnd, ESC_OF"GetSaveFileName", "Отказ от выбора или ошибка", MB_ICONWARNING);
break;
case IDM_BKGR_COLOR:
if (ChooseColor(&cc))
SetClassLong(hWnd, GCL_HBRBACKGROUND, (LONG)CreateSolidBrush(cc.rgbResult));
break;
case IDM_TEXT_COLOR:
if (ChooseColor(&cc)) textColor = cc.rgbResult; break;
case IDM_CHOOSE_FONT:
if(ChooseFont(&chf)) hFont = CreateFontIndirect(chf.lpLogFont); break;
case IDM_EXIT:
SendMessage(hWnd, WM_DESTROY, 0, 0); break;
default:
break;
}
Диалоговые окна общего пользования |
377 |
|
|
|
InvalidateRect(hWnd, NULL, TRUE); break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps); SetBkMode(hDC, TRANSPARENT); SetTextColor(hDC, textColor); if (hFont)
DeleteObject(SelectObject(hDC, hFont));
GetClientRect(hWnd, &rcClient);
DrawText(hDC, "Common Dialogs", -1, &rcClient, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hWnd, &ps); break;
case WM_DESTROY: PostQuitMessage(0); break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
//////////////////////////////////////////////////////////////////////
В приложении используются предопределенные структуры трех типов. Струк тура OPENFILENAME применяется для создания стандартных диалогов Open и Save As. Структура CHOOSECOLOR позволяет вызывать диалоговое окно Color, а струк тура CHOOSEFONT предназначена для работы со стандартным диалоговым окном Font. Соответствующие структурные переменные ofn, cc и chf объявлены со спецификатором static. Это решает две проблемы: инициализацию нулевым значением тех полей структур, для которых можно использовать значения по умолчанию, и сохранение значений полей между двумя вызовами функции
WndProc.
Инициализация переменных ofn, cc и chf осуществляется в блоке обработки сообщения WM_CREATE.
Рис. 7.35. Приложение CommonDialogs
378 |
Глава 7. Диалоговые окна |
|
|
Стандартные диалоговые окна создаются и вызываются следующими функ циями:
Стандартное диалоговое окно |
Функция |
|
|
Open |
GetOpenFileName |
Save As |
GetSaveFileName |
Color |
ChooseColor |
Font |
ChooseFont |
|
|
Приложение выводит в центре окна текстовую строку Common Dialogs (рис. 7.35). Пользователь может выбрать любой цвет фона и любой цвет текста, а также любой шрифт из установленных в системе шрифтов, с любым возможным размером и на чертанием шрифта.
На рисунке выбран шрифт Monotype Corsiva с размером 36 логических единиц. Протестируйте приложение, выполняя различные команды, в том числе и для подменю File. Обратите внимание на то, что удобный, а главное, стандартизиро ванный интерфейс пользователя в нашей программе был реализован минималь
ными средствами.
379
8Элементы управления общего пользования
По мере развития операционной системы Windows ее пользовательский интер фейс непрерывно улучшался. Так, начиная с Windows 95, в системе было опреде лено несколько новых элементов, названных общими элементами управления. Чтобы сделать эти элементы доступными для разработчиков программного обес печения, Microsoft разработала библиотеку элементов управления общего пользо вания (common control library). Новые элементы управления дополняют базовые элементы управления, рассмотренные в предыдущей главе, и придают програм мам более совершенный вид. Библиотека элементов управления общего пользо вания реализована в виде динамически загружаемой библиотеки comctl32.dll.
Элементы управления общего пользования можно разделить на четыре кате гории, в которые входят элементы управления главного окна, составные диалого вые элементы управления, элементы управления Windows Explorer и иные до полнительные элементы управления. В табл. 8.1–8.4 приведены краткие описания этих элементов.
Таблица 8.1. Элементы управления главного окна
Элемент управления |
Описание |
|
|
Toolbar (Панель инструментов) |
Состоит из кнопок быстрого доступа |
Tooltip (Окно подсказки) |
Показывает текст во всплывающем окне |
Status bar (Строка состояния) |
Информационная строка, обычно размещаемая в нижней |
|
части окна приложения |
|
|
Таблица 8.2. Составные диалоговые элементы управления
Элемент управления |
Описание |
|
|
Tab control (Закладки) |
Имитация закладок в записной книжке. При выборе одной |
|
из закладок на экране отображается связанное с ней |
|
диалоговое окно |
Property sheet |
Диалоговое окно с набором страниц, аналогичных зак- |
(Набор страниц свойств) |
ладкам, содержащее кроме этого общие для всех страниц |
|
кнопки |
Property page (Страница свойств) |
Диалоговое окно, используемое как страница в элементе |
|
управления Property sheet |
|
|
380 |
Глава 8. Элементы управления общего пользования |
|
Таблица 8.3. Элементы управления Windows Explorer |
|
|
Элемент управления |
Описание |
|
|
Tree view (Дерево просмотра) |
Отображает иерархически структурированный список (левая |
|
панель окна программы Windows Explorer) |
List view (Список просмотра) |
Отображает список элементов, идентифицируемых пикто- |
|
граммами и текстовыми данными (правая панель окна |
|
программы Windows Explorer) |
|
Таблица 8.4. Другие элементы управления |
|
|
Элемент управления |
Описание |
|
|
Animation |
Воспроизводит анимационную последовательность для |
(Анимационное изображение) |
индикации длительной операции |
Header |
Отображает горизонтальные заголовки для столбцов и ис- |
(Заголовок списка просмотра) |
пользуется совместно с элементом List view |
Image list (Список изображений) |
Элемент управления для хранения набора растровых изо- |
|
бражений, не являющийся отдельным окном |
Progress bar |
Элемент управления, который отображает динамику дли- |
(Индикатор процесса) |
тельной операции в виде процентного соотношения выпол- |
|
ненной части задачи |
Rich edit |
Редактор, поддерживающий множество шрифтов и базовые |
(Усовершенствованный редактор) |
возможности OLE-контейнера |
Slider (Регулятор) |
Ползунок, перемещаемый в пределах шкалы (разновидность |
|
полосы прокрутки) |
Spin (Счетчик или стрелки) |
Полоса прокрутки, состоящая из двух кнопок со стрелками, |
|
для увеличения или уменьшения на единицу целого числа, |
|
находящегося в «приятельском» окне редактирования |
|
|
Основы применения
Большинство элементов управления общего пользования реализовано в виде окна соответствующего предопределенного класса. С этой точки зрения элементы уп равления общего пользования похожи на базовые элементы управления. И те и другие элементы могут быть созданы вызовом функции CreateWindow, кото рой передаются конкретные флаги стиля класса. И те и другие элементы управ ляются специфичными для данного класса сообщениями. Оба типа элементов управления посылают уведомляющие сообщения родительскому окну, информи руя его обо всех происходящих событиях.
Разница между базовыми элементами управления и элементами управления общего пользования состоит в типе посылаемых уведомительных сообщений. Базовые элементы управления посылают сообщения WM_COMMAND, а элементы уп равления общего пользования почти всегда посылают сообщения WM_NOTIFY.
Инициализация библиотеки
Чтобы использовать в приложении какой либо элемент управления общего пользования, сначала нужно вызвать функцию InitCommonControlsEx, которая