Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Работа с контрольными переключателями






 

Контрольный переключатель (check box) применяется для установки или сброса определенных опций. Этот элемент представляет собой небольшой прямоугольник, который может быть «отмечен» крестиком или «птичкой», и текст, описывающий контрольный переключатель или его функцию. Если внутри прямоугольника переключателя имеется метка, переключатель называется выбранным или установленным, а если метка отсутствует, переключатель называется невыбранным или сброшенным. Контроль­ный переключатель, как правило, является частью диалога и определяется при описании диалога в файле ресурсов. Для добавления контрольного переключателя в окно используется оператор CHECKBOX вида:

 

CHECKBOX " строка", ID, X, Width, Height[, стиль]

 

Здесь " строка" задает текст, отображаемый рядом с прямоугольником переключа­теля в диалоге, ID задает идентификатор переключателя, X и Y – координаты верхнего левого угла переключателя, a Width и Height – размеры, включая размеры прямоугольника переключателя и текста. Стиль задает стиль переключателя. Если для стиля не указывается конкретное значение, используется стиль по умолчанию. Это означает, что текст отображается справа от прямоугольника переключателя и пользователь может перейти к данному переключателю при помощи мыши или клавиши [Tab]. Работая с Windows, Вы, вероятно, заметили, что при воздействии на контрольные переключатели они изменяют свое состояние. С точки зрения программы это не всегда происходит автоматически.

Используя оператор CHECKBOX при описании ресурсов, Вы создаете ручной переключатель, изменением состояния которого должна управлять Ваша программа (как это сделать, будет показано ниже). Вы можете создать автоматический переключатель и возложить все функции по изменению состояния контрольного переключателя на Windows.

Автоматический контрольный переключатель создается с помощью оператора AUTOCHECKBOX, который имеет такой же вид, как и CHECKBOX. Windows сама управляет автоматическими контрольными переключателями, изме­няя их состояние каждый раз, когда пользователь воздействует на них.

Прежде чем продолжить работу, нужно создать файл ресурсов, определяющий диалог с ручным и автоматическим контрольными переключателями. В этом файле следует также определить главное меню окна. Введите этот файл:

 

#include " Mydialog.h"

#include < Windows.h>

 

MYMENU MENU

{

MENUITEM " Диалог & 1", ID_DIALOG1

MENUITEM " & Статус", ID_STATUS

MENUITEM " Помощь", IDM_HELP

}

MYMENU ACCELERATORS

{

VK_F2, ID_DIALOG1, VIRTKEY

VK_F3, ID_STATUS, VIRTKEY

VK_F1, IDM_HELP, VIRTKEY

}

MYDB DIALOG 18, 18, 142, 92

CAPTION " Тестовый диалог"

STYLE DS_MODALFRAME|WS_POPUP|WS_CAPTION|WS_SYSMENU

{

PUSHBUTTON " OK", IDOK, 77, 40, 30, 13,

WS_CHILD|WS_VISIBLE|WS_TABSTOP

PUSHBUTTON " Сброс", IDCANCEL, 74, 65, 37, 14,

WS_CHILD|WS_VISIBLE|WS_TABSTOP

CHECKBOX " Параметр 1", ID_CB1, 3, 10, 50, 12

AUTOCHECKBOX " Параметр 2", ID_CB2, 3, 22, 50, 12

}

 

Далее Вам понадобится файл Mydialog.h, который приведен ниже. Этот файл определяет также идентификаторы, которые используются в последующих примерах этой главы.

 

#define ID_DIALOG1 100

#define ID_STATUS 101

#define IDM_HELP 102

#define ID_CB1 103

#define ID_CB2 104

#define ID_CT1 105

#define ID_GT1 106

#define ID_RB1 107

#define ID_RB2 108

#define ID_GB1 200

#define ID GB2 201

 

Каждый раз, когда пользователь выполняет щелчок мышью на контрольном переключателе или же выбирает контрольный переключатель клавишей [Tab], а затем нажимает [Пробел], в диалоговую функцию приходит сообщение VM_COMMAND. При этом младшее слово параметра wParam содержит идентификатор контрольного переключателя. При использовании ручного контрольного переключателя Вам нужно обработать это сообщение, изменив состояние контрольного переключателя. Для этого, используя функцию API SendDlgItemMessage(), следует направить контроль­ному переключателю сообщение BM_SETCHECK. Функция SendDlgItemMessage() уже рассматривалась в гл. 5, однако для удобства еще раз приведем ее прототип:

 

LONG SendDlgItemMessage(HWND hwnd, int ID, UINT msg,

WPARAM wParam, LPARAM lParam);

 

В сообщении BM_SETCHECK значение параметра wParam определяет состояние контрольного переключателя, которое должно быть установлено. Если это значение равно 1, то контрольный переключатель будет установлен, если оно равно 0 – то сброшен. По умолчанию при первом отображении диалога все контрольные переключатели сброшены. Параметр lParam в сообщении BM_SETCHECK не используется.

Помните следующее: если Вы используете автоматический контрольный переключатель, его состояние изменяется каждый раз при воздействии на него, поэтому автоматическому контрольному переключателю не нужно посылать сообщение BM_SETCHECK.

Вы можете определить текущее состояние контрольного переключателя, послав ему сообщение BM_GETCHECK. Контрольный переключатель возвратит значение 1, если он установлен, и 0, если он сброшен. В этом случае параметры wParam и lParam должны быть равны 0.

 

Пример 7-1. Ниже приведена программа, демонстрирующая работу ручного и автоматическо­го контрольных переключателей. Чтобы показать различия между ними, в этом примере ручной контрольный переключатель, будучи однажды установленным, оста­нется в этом состоянии и его нельзя сбросить. Пример также показывает, как управлять ручными контрольными переключателями.

 

// Демонстрация контрольных переключателей

#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 status1=0; // Для хранения состояния

int status2=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[80];

switch(message)

{

case WM_COMMAND:

switch(LOWORD(wParam))

{

case ID_DIALOG1:

DialogBox(hInst, " MYDB",

hwnd, DialogFunc);

break;

case ID_STATUS: // Состояние переключат.

if(status1)

strcpy(str,

" Переключатель 1 выбран\n");

else

strcpy(str,

" Переключатель 1 не выбран\n");

if(status2)

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_COMMAND:

switch(LOWORD(wParam))

{

case IDCANCEL:

EndDialog(hdwnd, 0);

return 1;

case IDOK:

// Обновить значения переменных,

// содержащих статус переключателей

status1=SendDlgItemMessage

(hdwnd, ID_CB1,

BM_GETCHECK, 0, 0);

// Выбран ли переключатель?

status2=SendDlgItemMessage

(hdwnd, ID_CB2,

BM_GETCHECK, 0, 0);

// Выбран ли переключатель?

EndDialog(hdwnd, 0);

return 1;

case ID_CB1:

// Пользователь выбрал этот

// переключатель - отметить его

SendDlgItemMessage(hdwnd, ID_CB1,

BM_SETCHECK, 1, 0);

return 1;

}

}

return 0;

}

 

В этой программе используются две внешние переменные – status1 и status2, сохраняющие состояния контрольных переключателей. Значения этих переменных устанавливаются при нажатии кнопки ОК в диалоге. Для активизации диалога применяется команда меню Диалог. Для просмотра состояния контрольного пере­ключателя, установленного в диалоге, используется команда меню Статус. Команда меню Помощь при работе с программой не используется. Диалог, который должен появляться на экране, изображен на рис. 7.1.

 

Управление контрольными переключателями. Предыдущая программа имеет два серьезных недостатка. Во-первых, контрольные переключатели сбрасываются при каждом открытии диалога, то есть не сохраняются ранее установленные их состояния. Во-вторых, в данной программе установленный ручной контрольный переключатель сбросить невозможно. В таком случае он уже не функционирует как контрольный переключатель. В настоящем разделе описывается, как более эффективно управлять контрольными переключателями.

 


 

Рис. 7.1. Пример окна диалога с контрольными переключателями

 

Хотя гораздо проще использовать автоматические переключатели, можно исполь­зовать и ручные контрольные переключатели, управляя ими из программы. Это означает, что пользователь должен сам предусмотреть все необходимые действия в программе, не полагаясь на Windows. Для этого в программе сначала следует определить текущее состояние контрольного переключателя, а затем изменить его состояние, как это продемонстрировано в следующем фрагменте:

 

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;

 

Инициализация контрольных переключателей. Как уже упоминалось, по умолчанию при активизации диалога все содержащиеся в нем контрольные переключатели автоматически сбрасываются. Хотя в некоторых случаях это и выглядит нормально, тем не менее, это не то, чего пользователь обычно ожидает. Как правило, при активизации диалога контрольные переключатели должны сохранять свое предыдущее состояние. Для этого их нужно инициализировать при активизации диалога. Простейший способ сделать это – направить им сообщение BM_SETCHECK. Вспомните, при активизации диалога его оконная функция получает сообщение WM_INITDIALOG. Таким образом, получив это сообщение, можно установить требуемое начальное состояние контрольных переключателей (и любых других элементов управления) в диалоге.

Следующий фрагмент программы выполняет инициализацию контрольных пе­реключателей:

 

case WM_INITDIALOG: // Инициализация диалога;

// установить состояние

// контрольных переключателей

SendDlgItemMessage(hdwnd, ID_CB1,

BM_SETCHECK, status1, 0);

SendDlgItemMessage(hdwnd, ID_CB2,

BM_SETCHECK, status2, 0);

return 1;

 

Пример 7-2. Ниже приведен полный текст программы, инициализирующей контрольные переключатели и управляющей состоянием ручного переключателя.

 

// Демонстрация контрольных переключателей

// с инициализацией

#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 status1=0; // Для хранения состояния

int status2=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[80];

switch(message)

{

case WM_COMMAND:

switch(LOWORD(wParam))

{

case ID_DIALOG1:

DialogBox(hInst, " MYDB",

hwnd, DialogFunc);

break;

case ID_STATUS: // Состояние переключат.

if(status1)

strcpy(str,

" Переключатель 1 выбран\n");

else

strcpy(str,

" Переключатель 1 не выбран\n");

if(status2)

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, status1, 0);

SendDlgItemMessage(hdwnd, ID_CB2,

BM_SETCHECK, status2, 0);

return 1;

case WM_COMMAND:

switch(LOWORD(wParam))

{

case IDCANCEL:

EndDialog(hdwnd, 0);

return 1;

case IDOK:

// Обновить значения переменных,

// содержащих статус переключателей

status1=SendDlgItemMessage

(hdwnd, ID_CB1,

BM_GETCHECK, 0, 0);

// Выбран ли переключатель?

status2=SendDlgItemMessage

(hdwnd, ID_CB2,

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;

}

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.