Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Работа с селекторными кнопками
В этом разделе описываются селекторные кнопки* (radio buttons), использующиеся для представления в окне множества опций, из которых можно выбрать только одну. Селекторная кнопка состоит из небольшой круглой кнопки и текста с описанием селекторной кнопки. Если кнопка заполнена, опция установлена, если нет – опция сброшена. Windows поддерживает два типа селекторных кнопок – устанавливаемые вручную (ручные) и автоматические. Ручные селекторные кнопки (как и ручные контрольные переключатели) требуют, чтобы все действия по управлению ими выполняла программа. Управление автоматическими селекторными кнопками выполняет сама Windows. Поскольку управление селекторными кнопками более сложно, чем управление контрольными переключателями, и поскольку автоматические селекторные кнопки используются наиболее часто, рассмотрим только этот тип селекторных кнопок. Как и другие элементы управления, селекторные кнопки описываются в файле ресурсов при определении диалога. Для создания автоматических селекторных кнопок используется оператор AUTORADIOBUTTON:
AUTORADIOBUTTON " строка", ID, X, Y, Width, Height[, стиль]
Здесь " строка" задает текст, a ID – идентификатор селекторной кнопки. Координаты верхнего левого угла задаются параметрами X и Y, a ширина и высота – параметрами Width и Height. Стиль задает вид селекторной кнопки. Если этот параметр не указан, стиль устанавливается по умолчанию, то есть строка отображается справа от маленькой кнопки и пользователь может переключаться к селекторной кнопке с помощью клавиши [Tab]. Как уже упоминалось, селекторные кнопки используются для представления группы опций, из которых можно выбрать только одну. Если в такой группе используются автоматические селекторные кнопки, Windows управляет ими таким образом, чтобы в каждый момент времени была выбрана только одна из них. То есть, если пользователь выбирает одну из селекторных кнопок, ранее выбранная кнопка автоматически очищается, и поэтому невозможно выбрать более одной селекторной кнопки одновременно. Селекторная кнопка (в том числе и автоматическая) может быть установлена в нужное состояние программно, если направить ей сообщение BM_SETCHECK, используя функцию API SendDlgItemMessage(). Значение wParam при этом определяет будущее состояние кнопки: если оно равно 1, то кнопка выбрана, если 0 – то нет. По умолчанию все кнопки изначально очищены. С помощью функции SendDlgItemMessage() можно выбрать более одной селекторной кнопки одновременно либо сбросить все селекторные кнопки. Однако нормальный стиль использования селекторных кнопок в Windows предполагает, что в каждый момент времени может быть выбрана одна, и только одна, селекторная кнопка. Нарушать это правило не рекомендуется. Состояние селекторной кнопки можно определить при помощи сообщения BM_GETCHECK. Если при этом селекторная кнопка возвращает 1, она выбрана, а если 0 – нет. Чтобы включить селекторные кнопки в пример программы, добавьте в файл ресурсов определения диалога следующие строки. Заметьте, что при этом добавляется еще одна рамка группы для селекторных кнопок. Это, конечно, не обязательно, однако в диалогах Windows выделение групп элементов является общепринятым.
GROUPBOX " Селекторы", ID_GT2, 62, 1, 53, 34 AUTORADIOBUTTON " Селектор 1", ID_RB1, 64, 10, 50, 12 AUTORADIOBUTTON " Селектор 2", ID_RB2, 64, 22, 50, 12
Пример 7-4. Ниже приводится измененный текст программы предыдущего примера, в котором добавлен фрагмент работы с двумя селекторными кнопками. Поскольку эти кнопки автоматические, изменений в программе немного. Заметьте, что состояние селекторных кнопок сохраняется во внешних переменных rstatus1 и rstatus2. Значения этих переменных используются и для установки состояний селекторных кнопок при активизации диалога, и для отображения их состояния по команде меню Статус.
// Демонстрация селекторных переключателей // (радиокнопок)
#include < Windows.h> #include < String.h> #include < Stdio.h> #include " Mydialog.h"
LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK DialogFunc(HWND, UINT, WPARAM, LPARAM); char szWinName[]=" МоеОкно"; // Имя класса окна HINSTANCE hInst; int cbstatus1=0; // Для хранения состояния int cbstatus2=0; // контрольных переключателей int rbstatus1=0; // Для хранения состояния int rbstatus2=0; // селекторных кнопок
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode) { HWND hwnd; MSG msg; WNDCLASS wcl; HACCEL hAccel; // Определить класс окна wcl.hInstance=hThisInst; // Дескриптор приложения wcl.lpszClassName=szWinName; // Имя класса окна wcl.lpfnWndProc=WindowFunc; // Функция окна wcl.style=0; // Стиль по умолчанию wcl.hIcon=LoadIcon(NULL, IDI_APPLICATION); // Иконка wcl.hCursor=LoadCursor(NULL, IDC_ARROW); // Курсор wcl.lpszMenuName=" MYMENU"; // Меню wcl.cbClsExtra=0; // Без дополнительной wcl.cbWndExtra=0; // информации wcl.hbrBackground= // Белый фон (HBRUSH)GetStockObject(WHITE_BRUSH); if(! RegisterClass(& wcl)) // Зарегистр. класс окна return 0; hwnd=CreateWindow(szWinName, // Создать окно " Работа с селекторными кнопками", WS_OVERLAPPEDWINDOW, // Стиль CW_USEDEFAULT, // Х-координата CW_USEDEFAULT, // Y-координата CW_USEDEFAULT, // Ширина CW_USEDEFAULT, // Высота HWND_DESKTOP, // Нет родит. окна NULL, // Нет меню hThisInst, // Дескрип. приложения NULL); // Без дополн. аргументов hInst=hThisInst; // Дескрип. текущ. приложения // Загрузить акселераторы hAccel=LoadAccelerators(hThisInst, " MYMENU"); ShowWindow(hwnd, nWinMode); // Показать окно UpdateWindow(hwnd); // Перерисовать содержимое while(GetMessage(& msg, NULL, 0, 0)) { // Запустить цикл обработки сообщений if(! TranslateAccelerator(hwnd, hAccel, & msg)) { TranslateMessage(& msg); // Исп. клавиатуры DispatchMessage (& msg); // Возврат к Windows } } return msg.wParam; }
// Следующая функция вызывается операционной системой // Windows и получает в качестве параметров сообщения // из очереди сообщений данного приложения
LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { char str[255]; switch(message) { case WM_COMMAND: switch(LOWORD(wParam)) { case ID_DIALOG1: DialogBox(hInst, " MYDB", hwnd, DialogFunc); break; case ID_STATUS: // Состояние переключат. if(cbstatus1) strcpy(str, " Переключатель 1 выбран\n"); else strcpy(str, " Переключатель 1 не выбран\n"); if(cbstatus2) strcat(str, " Переключатель 2 выбран\n"); else strcat(str, " Переключатель 2 не выбран\n"); if(rbstatus1) strcat(str, " Селектор 1 выбран\n"); else strcat(str, " Селектор 1 не выбран\n"); if(rbstatus2) strcat(str, " Селектор 2 выбран\n"); else strcat(str, " Селектор 2 не выбран\n"); MessageBox(hwnd, str, " ", MB_OK); break; case IDM_HELP: MessageBox(hwnd, " Помощь", " ", MB_OK); break; } break; case WM_DESTROY: // Завершение программы PostQuitMessage(0); break; default: // Все сообщения, не обрабатываемые в данной // функции, направляются на обработку по // умолчанию return DefWindowProc(hwnd, message, wParam, lParam); } return 0; }
// Простая функция диалога BOOL CALLBACK DialogFunc(HWND hdwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: // Инициализация диалога; // установить состояние // контрольн. переключателей // и селектторных кнопок SendDlgItemMessage(hdwnd, ID_CB1, BM_SETCHECK, cbstatus1, 0); SendDlgItemMessage(hdwnd, ID_CB2, BM_SETCHECK, cbstatus2, 0); SendDlgItemMessage(hdwnd, ID_RB1, BM_SETCHECK, rbstatus1, 0); SendDlgItemMessage(hdwnd, ID_RB2, BM_SETCHECK, rbstatus2, 0); return 1; case WM_COMMAND: switch(LOWORD(wParam)) { case IDCANCEL: EndDialog(hdwnd, 0); return 1; case IDOK: // Обновить значения переменных, // содержащих статус переключателей cbstatus1=SendDlgItemMessage (hdwnd, ID_CB1, BM_GETCHECK, 0, 0); // Выбран ли переключатель? cbstatus2=SendDlgItemMessage (hdwnd, ID_CB2, BM_GETCHECK, 0, 0); // Выбран ли переключатель? // Обновить значения переменных, // содержащих статус селекторных кнопок rbstatus1=SendDlgItemMessage (hdwnd, ID_RB1, BM_GETCHECK, 0, 0); // Выбран ли селектор? rbstatus2=SendDlgItemMessage (hdwnd, ID_RB2, BM_GETCHECK, 0, 0); // Выбран ли селектор? EndDialog(hdwnd, 0); return 1; case ID_CB1: // Это ручной переключатель // Пользователь его выбрал // Поэтому нужно изменить его состояние if(! SendDlgItemMessage(hdwnd, ID_CB1, BM_GETCHECK, 0, 0)) SendDlgItemMessage(hdwnd, ID_CB1, BM_SETCHECK, 1, 0); else // Очистить его SendDlgItemMessage(hdwnd, ID_CB1, BM_SETCHECK, 0, 0); return 1; } } return 0; }
Диалог, создаваемый этой программой, будет выглядеть так, как показано на рис. 7.3.
|