лекции / Shchupak_Yu._Win32_API_Razrabotka_prilozheniy_dlya_Windows
.pdfЭлементы управления главного окна |
421 |
|
|
|
|
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
brightness = intensity[shapeData.id_bright - ID_DARK];
if (bShow) {
hBrush = CreateSolidBrush(RGB( shapeData.fRed? brightness : 0, shapeData.fGreen? brightness : 0, shapeData.fBlue? brightness : 0));
hOldBrush = (HBRUSH)SelectObject(hDC, hBrush);
//Определение позиции и размеров фигуры с учетом
//уменьшения клиентской области из-за размещения
//панели инструментов и строки состояния GetClientRect(hWnd, &rect); GetWindowRect(hwndToolBar, &rcTB); tbHeight = rcTB.bottom - rcTB.top; GetWindowRect(hwndStatusBar, &rcSB); sbHeight = rcSB.bottom - rcSB.top;
x0 = rect.right / 2;
y0 = tbHeight + (rect.bottom - tbHeight - sbHeight) / 2;
// Координаты прямоугольника и эллипса if (shapeSize == MIN) {
x1 = x0 - W/2; y1 = y0 - H/2; x2 = x0 + W/2; y2 = y0 + H/2;
}
else {
x1 = 0; y1 = tbHeight;
x2 = rect.right; y2 = rect.bottom - sbHeight;
}
// Координаты ромба
pt[0].x = (x1 + x2) / 2; pt[0].y = y1; pt[1].x = x2; pt[1].y = (y1 + y2) / 2; pt[2].x = (x1 + x2) / 2; pt[2].y = y2; pt[3].x = x1; pt[3].y = (y1 + y2) / 2;
switch (shapeData.id_shape) { |
|
case ID_RECTANGLE: |
|
Rectangle(hDC, x1, y1, x2, y2); |
break; |
case ID_RHOMB:
Polygon(hDC, pt, 4); break; case ID_ELLIPSE:
Ellipse(hDC, x1, y1, x2, y2); break;
}
DeleteObject(SelectObject(hDC, hOldBrush));
}
EndPaint(hWnd, &ps); break;
case WM_DESTROY: PostQuitMessage(0);
продолжение
Другие элементы управления |
423 |
|
|
|
|
Другие элементы управления
Из других элементов управления общего пользования мы рассмотрим только
Progress bar, Slider и Spin.
Индикатор процесса
Индикатор процесса, или элемент управления Progress bar реализован как дочер нее окно, которое может использоваться в приложении для отображения процес са выполнения некоторой длительной операции. Индикатор процесса выглядит как вытянутая и расположенная горизонтально или вертикально прямоугольная область. По мере выполнения операции область заполняется слева направо или снизу вверх небольшими прямоугольниками, что позволяет показать пользовате лю прогресс в выполнении текущей операции.
Индикатор процесса создается при помощи функции CreateWindow или Create WindowEx с указанием идентификатора PROGRESS_CLASS в качестве оконного клас са, например:
hwndProgressBar = CreateWindow(PROGRESS_CLASS, NULL, WS_CHILD | WS_VISIBLE, x, y, width, height, hwndParent, NULL, NULL, NULL);
По умолчанию индикатор процесса имеет горизонтальную ориентацию и за полняется отдельными маленькими прямоугольниками, окрашенными системным цветом COLOR_HIGHLIGHT1.
Если при вызове функции CreateWindowдополнительно указать стиль PBS_VERTICAL, то индикатор будет иметь вертикальную ориентацию. Термин «ориентация» здесь относится только к способу заполнения окна индикатора прямоугольниками: слева направо или снизу вверх. Форма же окна определяется только параметрами width
и height.
Если вы предпочитаете использовать сплошное заполнение окна индикатора процесса, без маленьких промежутков между прямоугольниками, то укажите до полнительно стиль PBS_SMOOTH.
Реализация процесса и его связи с индикацией полностью лежат на плечах разработчика приложения. Собственно индикатор является лишь средством ото бражения отношения двух величин.
Интервал (range) индикатора процесса ассоциируется с полным выполнени ем операции. Он задается как пара целых чисел wMin и wMax. Текущая позиция (current position) отображает смещение от начала интервала и соответствует сте пени завершения операции. Оконная процедура индикатора процесса использует интервал и текущую позицию, чтобы определить процент заполнения окна инди катора прямоугольниками.
Для управления индикатором процесса используются сообщения, приведен ные в табл. 8.12 (полный список сообщений см. в MSDN).
Задавая значения wMin и wMax при определении интервала, выбирайте их из диапазона от 0 до 65 535. Если вы не определите интервал индикатора с помощью сообщения PBM_SETRANGE, то система использует установки по умолчанию, когда wMin = 0, а wMax = 100.
1Цвет, используемый Windows для подсвечивания выделенных элементов в дочерних окнах элемен тов управления.
424 |
|
Глава 8. Элементы управления общего пользования |
|
|
|||
Таблица 8.12. Сообщения для управления элементом Progress bar |
|||
|
|
|
|
Код сообщения |
wParam |
lParam |
Описание |
|
|
|
|
PBM_SETRANGE |
0 |
MAKELPARAM |
Установка интервала для индикатора |
|
|
(wMin, wMax) |
|
PBM_SETPOS |
nNewPos |
0 |
Установка текущей позиции |
PBM_DELTAPOS |
nInc |
0 |
Изменение текущей позиции прибавлением |
|
|
|
смещения nInc |
PBM_SETSTEP |
nStepInc |
0 |
Установка шага приращения для индикатора |
PBM_STEPIT |
0 |
0 |
Изменение текущей позиции прибавлением |
|
|
|
øàãà nStepInc |
PBM_SETBARCOLOR |
0 |
(COLORREF) |
Установка цвета заполняемых прямоугольников |
|
|
clrBar |
|
PBM_SETBKCOLOR |
0 |
(COLORREF) |
Установка цвета фона |
|
|
clrBk |
|
|
|
|
|
Как видно из таблицы, текущее состояние индикатора можно изменять тремя аль тернативными способами. Для этого может использоваться сообщение PBM_SETPOS, PBM_DELTAPOS или PBM_STEPIT. В третьем способе текущая позиция изменяется при бавлением шага приращения nStepInc, который можно предварительно установить, отправив сообщение PBM_SETSTEP. Если вы не устанавливаете это значение, система использует значение по умолчанию nStepInc = 10.
Отметим, что если при обработке сообщения PBM_STEPIT индикатор достигнет значения wMax или превысит его, то его текущая позиция сбрасывается в значе ние wMin и индикатор процесса стартует сначала.
Два последних сообщения из табл. 8.12 позволяют изменить цветовые атрибу ты индикатора процесса.
Для демонстрации применения индикатора процесса разработаем приложе ние ProgressBar, в котором решается задача загрузки некоторого файла. Приложе ние должно иметь строку состояния с двумя полями. В первом поле выводится текстовое сообщение о проценте выполненной операции. Во втором поле будет располагаться окно индикатора процесса.
Предположим, что размер загружаемого файла равен size байтов и файл чита ется порциями по DATA_CHUNK байтов. Чтобы упростить связь процесса загрузки файла с отображением степени завершения операции в индикаторе, будем счи тать, что wMin = 0, wMax = size / DATA_CHUNK, nStepInc = 1, а текущая позиция будет изменяться отправкой сообщения PBM_STEPIT.
Выбирая значение DATA_CHUNK, вы должны понимать, что величина wMax не может превышать значение 65 535.
Создайте новый проект с именем ProgressBar. Добавьте к настройкам проекта на вкладке Link библиотеку comctl32.lib. Скопируйте из папки проекта ToolTip фай лы KWndEx.h и KWndEx.cpp, после чего добавьте их в состав проекта. Также добавьте к приложению ресурс меню IDR_MENU1 с одним пунктом. Пункт меню должен иметь имя LoadFile и идентификатор IDM_LOAD_FILE.
Добавьте к проекту файл ProgressBar.cpp с текстом, приведенным в листинге 8.6.
Листинг 8.6. Проект ProgressBar
//////////////////////////////////////////////////////////////////////
// ProgressBar.cpp #include <windows.h> #include <commctrl.h>
Другие элементы управления |
425 |
|
|
|
|
#include <stdio.h> #include <fstream> using namespace std;
#include "KWndEx.h" #include "resource.h"
#define ID_STATUSBAR 201 #define N_PARTS 2
#define DATA_CHUNK 64
#define FILE_NAME "ProgressBar.cpp"
HWND hwndStatusBar;
HWND hwndProgressBar;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //==================================================================== int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWndEx mainWnd("ProgressBar", hInstance, nCmdShow, WndProc, MAKEINTRESOURCE(IDR_MENU1), 100, 100, 400, 200);
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; char text[100]; RECT rect, r1;
int aWidths[N_PARTS]; |
|
ifstream file; |
|
static int size; |
// размер файла в байтах |
static int range; |
// диапазон для индикатора процесса |
static int nBytesRead; |
// число прочитанных байтов |
double percentage; |
|
char buf[DATA_CHUNK]; |
|
static int i; |
|
MSG message; |
|
switch (uMsg)
{
case WM_CREATE:
// Создание строки состояния
hwndStatusBar = CreateStatusWindow(WS_CHILD | WS_VISIBLE, "", hWnd, ID_STATUSBAR);
// Увеличиваем высоту строки состояния
продолжение
426 Глава 8. Элементы управления общего пользования
Листинг 8.6 (продолжение)
SendMessage(hwndStatusBar, SB_SETMINHEIGHT, 24, 0);
aWidths [0] = 50; aWidths [1] = -1;
SendMessage(hwndStatusBar, SB_SETPARTS, N_PARTS, (LPARAM)aWidths);
//Извлекаем координаты 1-ãî ïîëÿ SendMessage(hwndStatusBar, SB_GETRECT, 1, (LPARAM)&r1);
//Создание индикатора процесса
hwndProgressBar = CreateWindow(PROGRESS_CLASS, NULL, WS_CHILD | WS_VISIBLE,
r1.left + 3, r1.top + 3, r1.right - r1.left, r1.bottom - r1.top, hwndStatusBar, NULL, NULL, NULL);
break;
case WM_SIZE:
SendMessage (hwndStatusBar, WM_SIZE, wParam, lParam); break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDM_LOAD_FILE: // Открывем файл
file.open(FILE_NAME, ios::in | ios::binary); if (!file) {
MessageBox(hWnd, "Нет файла", NULL, MB_OK | MB_ICONSTOP); break;
}
// Определяем размер файла file.seekg(0, ios::end); size = file.tellg(); file.seekg(0, ios::beg);
// Настраиваем параметры индикатора процесса range = size / DATA_CHUNK; SendMessage(hwndProgressBar, PBM_SETRANGE, 0,
MAKELPARAM(0, range)); SendMessage(hwndProgressBar, PBM_SETSTEP, 1, 0); SendMessage(hwndProgressBar, PBM_SETPOS, 0, 0); InvalidateRect(hWnd, NULL, FALSE);
nBytesRead = 0; // Загрузка файла
while (!file.eof()) {
// Чтение порции данных file.read(buf, DATA_CHUNK); nBytesRead += DATA_CHUNK;
if (file.eof()) break;
//Здесь возможен вызов процедуры для обработки порции данных
//...
//Отображение процента выполненной операции
percentage = 100.0 * nBytesRead / size;
Другие элементы управления |
429 |
|
|
|
|
hwndSlider = CreateWindow(TRACKBAR_CLASS, NULL, WS_CHILD | WS_VISIBLE, x, y, width, height, hwndParent, NULL, NULL, NULL);
Кроме стилей WS_CHILD и WS_VISIBLE можно также задавать дополнительные стили, определяющие внешний вид элемента управления (табл. 8.13).
Таблица 8.13. Стили элемента управления Slider
Стиль |
Описание |
|
|
TBS_HORZ |
Линейка имеет горизонтальную ориентацию (стиль по умолчанию) |
TBS_VERT |
Линейка имеет вертикальную ориентацию |
TBS_AUTOTICKS |
Линейка имеет метки для всех значений в заданном диапазоне значений. Без |
|
этого стиля линейка может иметь метки только для начального и конечного |
|
положений ползунка |
TBS_NOTICKS |
Исключает отображение каких-либо меток, в том числе и для начального |
|
и конечного положений ползунка |
TBS_RIGHT |
Элемент отображает метки справа (снизу) от линейки; ползунок направлен |
|
в ту же сторону. Этот стиль используется по умолчанию |
TBS_LEFT |
Элемент отображает метки слева (сверху) от линейки; ползунок направлен |
|
в ту же сторону |
TBS_BOTH |
Элемент отображает метки с обеих сторон; ползунок имеет прямоугольную |
|
форму |
TBS_TOOLTIPS |
Поддерживается всплывающая подсказка, отображающая текущую позицию |
|
ползунка |
|
|
Альтернативный способ создания регулятора — с помощью редактора диа логовых окон на этапе визуального проектирования формы диалога. В этом случае вы выбираете щелчком мыши элемент Slider на панели инструментов Controls и повторным щелчком помещаете регулятор в нужное место формы диалога.
Размеры элемента управления при размещении на форме диалога, как обыч но, регулируются с помощью мыши или при помощи команд подменю Layout.
Затем нужно вызвать окно свойств Slider Properties и на вкладке General в поле ID ввести идентификатор элемента управления. На вкладке Styles, показанной на рис. 8.12, можно задать дополнительные свойства регулятора.
Рис. 8.12. Свойства элемента Slider на вкладке Styles
Открывающийся список Orientation позволяет выбрать ориентацию элемен та управления: Horizontal (по умолчанию) или Vertical. Другой список, Point, пред назначен для выбора стиля размещения меток: Both (по умолчанию), Top/Left или Bottom/Right. Флажок Tick marks задает наличие меток, флажок Auto ticks за дает стиль TBS_AUTOTICKS, флажок Border определяет наличие рамки у элемента управления.
430 |
Глава 8. Элементы управления общего пользования |
|
|
Создание регулятора с помощью редактора диалоговых окон является более простым способом. Именно эту технологию мы используем в рассматриваемом ниже примере разработки приложения Trackbar.
Параметры и состояние регулятора
С элементом управления Slider связан внутренний счетчик, определяющий его поведение. Счетчик имеет минимальное значение wMin и максимальное значение wMax. По умолчанию wMin = 0, а wMax = 100. Вы можете изменить диапазон регу лятора, послав ему сообщение TBM_SETRANGE.
Текущее состояние счетчика однозначно связано с текущей позицией ползун ка. Пользователь может перемещать ползунок по линейке регулятора как с помо щью мыши, так и с помощью клавиатуры. Второй вариант работы предполагает, что регулятор имеет фокус ввода.
Минимальный интервал, на который можно изменить состояние регулятора с помощью клавиш со стрелками, называется «строкой» (line). По умолчанию он равен единице. Размер «строки» можно изменить, послав регулятору сообщение
TBM_SETLINESIZE.
Более крупный интервал, на который можно изменить состояние регулятора с помощью клавиши PageUpили PageDown, называется «страницей» (page). По умол чанию размер «страницы» равен одной пятой части диапазона регулятора. Размер «страницы» можно изменить, послав регулятору сообщение TBM_SETPAGESIZE.
Если регулятор создан со стилем Auto ticks (TBS_AUTOTICKS), то линейка имеет метки во всем диапазоне значений с шагом wFreq, который по умолчанию равен единице. Вы можете изменить этот шаг, послав сообщение TBM_SETTICFREQ.
Действия пользователя и уведомляющие сообщения
Регулятор уведомляет свое родительское окно о действиях пользователя, посылая сообщение WM_HSCROLL или WM_VSCROLL — в зависимости от ориентации элемента уп равления (Horizontal или Vertical). В любом случае в младшем слове параметра wParam содержится код уведомления, а параметр lParam содержит дескриптор регулятора. Возможные коды уведомления приведены в табл. 8.14. Для кодов TB_THUMBPOSITION и TB_THUMBTRACK старшее слово параметра wParam содержит позицию ползунка.
Таблица 8.14. Коды уведомления от элемента управления Slider
Код уведомления |
Значение |
Описание |
|
|
|
TB_LINEUP |
0 |
Нажата клавиша «стрелка влево» (VK_LEFT) или клавиша |
|
|
«стрелка вверх» (VK_UP) — ползунок сдвигается на вели- |
|
|
чину «строки» |
TB_LINEDOWN |
1 |
Нажата клавиша «стрелка вправо» (VK_RIGHT) или кла- |
|
|
виша «стрелка вниз» (VK_DOWN) — ползунок сдвигается |
|
|
на величину «строки» |
TB_PAGEUP |
2 |
Нажата клавиша «Page Up» (VK_PRIOR) или щелчок |
|
|
мышью на линейке левее или выше ползунка — ползунок |
|
|
сдвигается на величину «страницы» (левее — для гори- |
|
|
зонтальной ориентации регулятора, выше — для верти- |
|
|
кальной ориентации) |
TB_ PAGEDOWN |
3 |
Нажата клавиша «Page Down» (VK_NEXT) или щелчок |
|
|
мышью на линейке правее или ниже ползунка — ползунок |
|
|
сдвигается на величину «страницы» |
|
|
|
