лекции / Shchupak_Yu._Win32_API_Razrabotka_prilozheniy_dlya_Windows
.pdf
Другие элементы управления |
431 |
||
|
|
|
|
|
|
|
|
|
Код уведомления |
Значение |
Описание |
|
|
|
|
|
TB_THUMBPOSITION |
4 |
Пользователь отпустил кнопку мыши после перемещения |
|
|
|
ползунка (это сообщение следует всегда после сообщения |
|
|
|
TB_THUMBTRACK) |
|
TB_THUMBTRACK |
5 |
Ползунок перемещается с помощью мыши |
|
TB_TOP |
6 |
Нажата клавиша «Home» (VK_HOME) — ползунок устанав- |
|
|
|
ливается в крайнее левое (верхнее) положение, соответ- |
|
|
|
ствующее значению wMin |
|
TB_BOTTOM |
7 |
Нажата клавиша «End» (VK_END) — ползунок устанавли- |
|
|
|
вается в крайнее правое (нижнее) положение, соответ- |
|
|
|
ствующее значению wMax |
|
|
|
|
Часто приложение может обойтись без обработки этих сообщений, так как с помощью управляющего сообщения TBM_GETPOS (см. ниже) можно легко узнать текущую позицию ползунка, и в большинстве случаев этого оказывается доста точно.
Управляющие сообщения
Для управления регулятором предусмотрено несколько десятков сообщений, сим волические коды которых начинаются с префикса TBM_. В табл. 8.15 приведены некоторые из этих сообщений.
Таблица 8.15. Сообщения для управления элементом Slider
Сообщение |
wParam |
lParam |
Описание |
|
|
|
|
TBM_GETPOS |
0 |
0 |
Возвращает текущую позицию ползунка |
TBM_SETPOS |
fRedraw |
newPos |
Устанавливает новую позицию ползунка. |
|
|
|
Если fRedraw равно TRUE, регулятор |
|
|
|
перерисовывается после этого |
TBM_SETRANGE |
fRedraw |
MAKELPARAM |
Устанавливает диапазон регулятора |
|
|
(wMin, wMax) |
|
TBM_SETTICFREQ |
wFreq |
0 |
Устанавливает шаг меток |
TBM_SETLINESIZE |
0 |
nLineSize |
Устанавливает размер «строки» |
TBM_SETPAGESIZE |
0 |
nPageSize |
Устанавливает размер «страницы» |
|
|
|
|
Приложение TrackBar
Для демонстрации применения регуляторов разработаем приложение TrackBar, которое является клоном приложения ModelessDlg, рассмотренного в главе 7. При ложение ModelessDlg позволяло изменять цвет фона окна с помощью полос про крутки. В нашем новом приложении вместо полос прокрутки будут применены элементы управления Slider.
Создайте новый проект с именем TrackBar. Скопируйте из папки проекта
ModelessDlg (см. листинг 7.6) в папку проекта TrackBar файлы ModelessDlg.cpp,
ModelessDlg.rc и resource.h, скорректировав имена первых двух файлов заменой подстроки ModelessDlg на TrackBar. Также скопируйте из папки проекта ToolTip (ли стинг 8.4) файлы KWndEx.cpp и KWndEx.h. Все скопированные файлы нужно доба вить в состав проекта. Также к настройкам проекта на вкладке Link следует доба вить библиотеку comctl32.lib.
Откройте вкладку ResourceView в окне Workspace. В списке ресурсов откройте папку Dialogи вызовите редактор диалоговых окон двойным щелчком мыши на эле
432 |
Глава 8. Элементы управления общего пользования |
|
|
менте IDD_MODELESS. Удалите все элементы управления с формы диалога. Размес тите три надписи и три элемента управления Slider, как показано на рис. 8.13.
Рис. 8.13. Форма диалога после размещения элементов управления
Для элементов управления установите следующие атрибуты:
Элемент |
ID |
Caption |
Свойства |
|
|
|
|
Static text |
IDC_STATIC_RED |
Red |
По умолчанию |
Static text |
IDC_STATIC_GREEN |
Green |
По умолчанию |
Static text |
IDC_STATIC_BLUE |
Blue |
По умолчанию |
Slider |
IDC_SLIDER_RED |
— |
Cтиль меток — Bottom/Right. Установлены |
|
|
|
флажки Tick marks, Auto ticks, Border |
Slider |
IDC_SLIDER_GREEN |
— |
|
Slider |
IDC_SLIDER_BLUE |
— |
Остальные свойства — по умолчанию |
|
|||
|
|
|
|
Отредактируйте исходный код в файле TrackBar.cpp, чтобы он соответствовал листингу 8.7.
Листинг 8.7. Проект TrackBar
//////////////////////////////////////////////////////////////////////
// TrackBar.cpp #include <windows.h> #include <stdio.h> #include <commctrl.h>
#include "KWndEx.h" #include "resource.h"
enum UserMsg { UM_CHANGE = WM_USER+1 };
HWND hModelessDlg;
RECT rcWork; // прямоугольник рабочей области
int rgb[3]; // интенсивность для R-, G-, B-компонентов цвета
BOOL CALLBACK ModelessDlgProc(HWND, UINT, WPARAM, LPARAM); void AdjustDlgPlace(HWND, HWND);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //====================================================================
Другие элементы управления |
433 |
|
|
|
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWndEx mainWnd("TrackBar", hInstance, nCmdShow, WndProc,
NULL, 100, 100, 400, 270);
while (GetMessage(&msg, NULL, 0, 0)) {
if (!IsDialogMessage(hModelessDlg, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg);
}
}
return msg.wParam;
}
//==================================================================== LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
/* Здесь такой же текст, как в листинге 7.6 */
}
//====================================================================
BOOL CALLBACK ModelessDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HWND hSliderRed; static HWND hSliderGreen; static HWND hSliderBlue; static HWND hStaticRed; static HWND hStaticGreen; static HWND hStaticBlue; char text[100];
switch (uMsg) { case WM_INITDIALOG:
//Определяем дескрипторы элементов управления Slider hSliderRed = GetDlgItem(hDlg, IDC_SLIDER_RED); hSliderGreen = GetDlgItem(hDlg, IDC_SLIDER_GREEN); hSliderBlue = GetDlgItem(hDlg, IDC_SLIDER_BLUE); hStaticRed = GetDlgItem(hDlg, IDC_STATIC_RED); hStaticGreen = GetDlgItem(hDlg, IDC_STATIC_GREEN); hStaticBlue = GetDlgItem(hDlg, IDC_STATIC_BLUE);
//Инициализация элементов управления Slider SendMessage(hSliderRed, TBM_SETRANGE, TRUE, MAKELONG(0, 255)); SendMessage(hSliderRed, TBM_SETTICFREQ, 32, 0); SendMessage(hSliderGreen, TBM_SETRANGE, TRUE, MAKELONG(0, 255)); SendMessage(hSliderGreen, TBM_SETTICFREQ, 32, 0); SendMessage(hSliderBlue, TBM_SETRANGE, TRUE, MAKELONG(0, 255)); SendMessage(hSliderBlue, TBM_SETTICFREQ, 32, 0);
//Вывод фона окна для начального состояния регуляторов SendMessage(hDlg, WM_HSCROLL, 0, 0);
продолжение
Другие элементы управления |
435 |
|
|
|
|
Код обработки сообщения UM_CHANGE, находящийся в теле оконной процеду ры WndProc, здесь не приведен, поскольку все тело процедуры повторяет текст, заимствованный из листинга 7.6.
На рис. 8.14 показан вид работающего приложения.
В настоящий момент ползунки регуляторов задают кремовый цвет фона окна.
Счетчик и поле с прокруткой
Элемент управления счетчик (Spin) реализован как две кнопки со стрелками, с помощью которых пользователь может увеличивать или уменьшать некоторое числовое значение. Значение, связанное со счетчиком, называется его текущей позицией.
Кроме этого счетчик можно ассоциировать с другим элементом управления, называемым приятельским окном (buddy window). Чаще всего таким окном явля ется окно редактирования. Комбинацию счетчика с окном редактирования назы вают также полем с прокруткой. Поле с прокруткой воспринимается пользовате лем как единый элемент управления. Содержимое окна редактирования в таком элементе отображает текущую позицию счетчика (рис. 8.15).
Рис. 8.15. Поле с прокруткой
Не имея ассоциированного с ним окна, счетчик функционирует как упро щенный вариант полосы прокрутки. Например, в элементе управления Tab control счетчик используется для осуществления доступа к дополнительным вкладкам (рис. 8.16).
Рис. 8.16. Элемент управления Spin в правом верхнем углу элемента управления Tab control
Создание счетчика
Счетчик можно создать несколькими способами. В первом способе используется вызов функции CreateWindowEx с указанием оконного класса UPDOWN_CLASS. Во вто ром способе вызывается функция CreateUpDownControl, создающая счетчик и одновременно определяющая его минимальную, максимальную и текущую по зиции, а также его приятельское окно.
Третий способ создания счетчика — при помощи редактора диалоговых окон на этапе визуального проектирования формы диалога. Элемент управления Spin выбирается с помощью мыши на панели инструментов Controls и просто помеща ется в нужное место формы диалога.
Затем надо вызвать окно свойств Spin Properties и на вкладке General в поле ID указать идентификатор элемента управления. На вкладке Styles, показанной на рис. 8.17, можно задать дополнительные свойства счетчика.
436 |
Глава 8. Элементы управления общего пользования |
|
|
Рис. 8.17. Свойства элемента Spin на вкладке Styles
Список Orientation предназначен для выбора ориентации элемента управления. По умолчанию используется значение Vertical, но можно также установить значе ние Horizontal.
Список Alignment позволяет выбрать один из трех стилей размещения счет чика:
Alignment |
Описание размещения |
|
|
Unattached |
Счетчик располагается рядом с ассоциированным окном (так, как вы поместили |
|
его на форму диалога) |
Left |
Счетчик располагается в левой части ассоциированного окна (уменьшая тем |
|
самым его клиентскую область) |
Right |
Счетчик располагается в правой части ассоциированного окна (уменьшая тем |
|
самым его клиентскую область) |
|
|
Флажки на вкладке Styles позволяют задать дополнительные параметры:
Флажок |
Интерпретация |
|
|
Auto buddy |
Автоматический выбор в качестве ассоциированного окна ближайшего |
|
предыдущего элемента управления в файле описания ресурсов |
Set buddy integer |
Вместе с предыдущим флажком определяет синхронную работу счетчика |
|
и ассоциированного окна: любое изменение позиции счетчика сразу |
|
отображается в ассоциированном окне. Аналогично при вводе |
|
в ассоциированное окно допустимого целого числа оно устанавливает новую |
|
позицию счетчика |
No thousands |
Если этот флажок выключен, в изображение десятичного числа после |
|
каждых трех цифр вставляется пробел, если включен — пробел не |
|
вставляется |
Wrap |
По умолчанию текущая позиция счетчика не изменяется, если пользователь |
|
пытается перейти максимальное (при увеличении) или минимальное (при |
|
уменьшении) значение. Если установлен данный флажок, то счетчик рабо- |
|
тает как циклический. После максимального значения текущим становится |
|
минимальное, и наоборот |
Arrow keys |
Поддерживается управление счетчиком с помощью клавиш «стрелка вверх» |
|
и «стрелка вниз» (независимо от ориентации элемента управления) |
|
|
Таким образом, при создании поля с прокруткой необходимо всегда выпол нять два правила. Во первых, элемент управления Spin нужно поместить на форму диалога сразу вслед за размещением приятельского окна редактирова ния. Во вторых, надо установить флажки Auto buddy и Set buddy integer. Отмет ка флажка Arrow keys установлена по умолчанию, и эту установку следует со хранить.
Другие элементы управления |
437 |
|
|
|
|
Следует отметить высокий «интеллект» поля с прокруткой. Если пользова тель введет в окно редактирования числовое значение больше максимально допу стимого или меньше минимально допустимого, то позиция счетчика будет зафик сирована на соответствующей границе диапазона. Правда, пользователь узнает об этом только после очередного воздействия на стрелки счетчика.
При попытке ввести в окно редактирования нецифровые символы счетчик со храняет текущую позицию.
Сообщения от поля с прокруткой
При нажатии одной из стрелок элемент управления Spin посылает своему роди тельскому окну сообщение WM_VSCROLL или WM_HSCROLL (в зависимости от ори ентации счетчика), в котором младшее слово параметра wParam содержит код SB_THUMBPOSITION. Кроме того, счетчик посылает уведомляющее сообщение
UDN_DELTAPOS в форме сообщения WM_NOTIFY.
Обычно в приложении нет необходимости обрабатывать все сообщения. Час то бывает достаточно получить текущую позицию счетчика, обрабатывая сооб щение WM_VSCROLL или WM_HSCROLL. Это можно сделать, отправив элементу Spin управляющее сообщение UDM_GETPOS.
При непосредственном клавиатурном вводе нового числа в окно редактирова ния элемент Edit Box посылает родительскому окну сообщение WM_COMMAND с ко дом уведомления EN_CHANGE. Если вы хотите, чтобы приложение немедленно от реагировало на изменившуюся текущую позицию счетчика (а он отслеживает все изменения в приятельском окне), то предусмотрите обработку этого сообщения. Пример такой обработки приведен ниже в приложении Spinner.
Управляющие сообщения
Для управления счетчиком предусмотрено более двадцати сообщений, символи ческие коды которых начинаются с префикса UDM_. В табл. 8.16 приведены неко торые сообщения, чаще всего используемые в работе.
Таблица 8.16. Сообщения для управления элементом Spin
Сообщение |
wParam |
lParam |
Описание |
|
|
|
|
UDM_GETPOS |
0 |
0 |
Возвращает текущую позицию счетчика |
UDM_SETPOS |
0 |
MAKELPARAM (nPos, 0) |
Устанавливает новую позицию |
|
|
|
счетчика |
UDM_SETBASE |
nBase |
0 |
Устанавливает систему счисления. |
|
|
|
nBase должно быть равно 10 или 16. По |
|
|
|
умолчанию установлена десятичная |
|
|
|
система счисления |
UDM_SETRANGE |
0 |
MAKELPARAM |
Устанавливает минимальную и макси- |
|
|
(nUpper, nLower) |
мальную позиции для счетчика (в ин- |
|
|
|
тервале –0x7FFF...0x7FFF) |
|
|
|
|
Если после создания счетчика не определить его диапазон при помощи сооб щения UDM_SETRANGE, то будет использоваться диапазон по умолчанию со значе ниями nLower=100 и nUpper=0. В этом случае «стрелка вверх» вызывает уменьше ние значения счетчика, а «стрелка вниз» — увеличение значения. Чем обусловлен такой оригинальный диапазон по умолчанию, в котором максимум меньше, чем минимум, в справочных материалах MSDN не поясняется.
Другие элементы управления |
439 |
|
|
|
|
Листинг 8.8. Проект Spinner
//////////////////////////////////////////////////////////////////////
// Spinner.cpp #include <windows.h> #include <stdio.h> #include <commctrl.h> #include "KWndEx.h" #include "resource.h"
enum UserMsg { UM_CHANGE = WM_USER+1 };
HWND hModelessDlg;
RECT rcWork; // прямоугольник рабочей области
int rgb[3]; // интенсивность для R-, G-, B-компонентов цвета
BOOL CALLBACK ModelessDlgProc(HWND, UINT, WPARAM, LPARAM); void AdjustDlgPlace(HWND, HWND);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //==================================================================== int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWndEx mainWnd("Spinner", hInstance, nCmdShow, WndProc,
NULL, 100, 100, 400, 260);
while (GetMessage(&msg, NULL, 0, 0)) {
if (!IsDialogMessage(hModelessDlg, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg);
}
}
return msg.wParam;
}
//==================================================================== LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
/* Здесь такой же текст, как в листинге 7.6 */
}
//====================================================================
BOOL CALLBACK ModelessDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HWND hSpinRed; static HWND hSpinGreen; static HWND hSpinBlue; static HWND hStaticRed; static HWND hStaticGreen; static HWND hStaticBlue;
switch (uMsg) { case WM_INITDIALOG:
// Определяем дескрипторы элементов управления Spin hSpinRed = GetDlgItem(hDlg, IDC_SPIN_RED); hSpinGreen = GetDlgItem(hDlg, IDC_SPIN_GREEN); hSpinBlue = GetDlgItem(hDlg, IDC_SPIN_BLUE);
продолжение
