Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторный практикум «Основы разработки приложений Windows» книга 1.DOC
Скачиваний:
107
Добавлен:
10.05.2014
Размер:
721.41 Кб
Скачать

Немодальный диалог

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

Рис. 4.4. Немодальный диалог в главном окне приложения

/*Пример 4-3.Немодальный диалог */

/*Файл 4-3.H*/

#define ID_BLUE 100

#define ID_GREEN 101

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

BOOL OnCreate(HWND,LPCREATESTRUCT);

void OnPaint(HWND);

void OnCommand(HWND,int,HWND,UINT);

void OnDestroy(HWND);

BOOL CALLBACK DlgProc(HWND,UINT,WPARAM,LPARAM);

BOOL DlgOnInitDialog(HWND,HWND,LPARAM);

void DlgOnCommand(HWND,int,HWND,UINT);

/*Файл 4-3.RC*/

#include "4-3.h"

Colors DIALOG 80, 5, 53, 47

STYLE WS_VISIBLE | WS_CHILD

CAPTION "Управление" {

CONTROL "Цвет окна",-1,"BUTTON",BS_GROUPBOX,2,3,49,40

CONTROL "Синий",ID_BLUE,"BUTTON",

BS_AUTORADIOBUTTON, 8, 12, 40, 12

CONTROL "Зеленый", ID_GREEN, "BUTTON",

BS_AUTORADIOBUTTON, 8, 28, 40, 12

}

/*Файл 4-3.CPP*/

#include <windows.h>

#include <windowsx.h>

#include "4-3.h"

HBRUSH hBlueBrush,hGreenBrush;//Дескрипторы кистей фона

int sw=1;//Переключатель цвета, начальный – синий

HWND hWnd;//Дескриптор главного окна

HINSTANCE hInst;//Дескриптор приложения

/*Главная функция WinMain*/

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR,int){

char szClassName[]="MainWindow";

char szTitle[]="Программа 4-3";

MSG msg;

WNDCLASS wc;

hInst=hInstance;

ZeroMemory(&wc,sizeof(wc));

wc.lpfnWndProc=WndProc;

wc.hInstance=hInst;

wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);

wc.hCursor=LoadCursor(NULL,IDC_ARROW);

wc.hbrBackground=GetStockBrush(WHITE_BRUSH);

wc.lpszClassName=szClassName;

RegisterClass(&wc);

hWnd=CreateWindow(szClassName,szTitle,

WS_OVERLAPPEDWINDOW,10,10,300,180,

HWND_DESKTOP,NULL,hInst,NULL);

ShowWindow(hWnd,SW_SHOWNORMAL);

while(GetMessage(&msg,NULL,0,0))

DispatchMessage(&msg);

return 0;

}

/*Оконная функция WndProcглавного окна*/

LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM

wParam,LPARAM lParam){

switch(msg){

HANDLE_MSG(hwnd,WM_CREATE,OnCreate);

HANDLE_MSG(hwnd,WM_PAINT,OnPaint);

HANDLE_MSG(hwnd,WM_DESTROY,OnDestroy);

default:

return(DefWindowProc(hwnd,msg,wParam,lParam));

}

}

/*ФункцияOnCreateобработки сообщенийWM_CREATE*/

BOOL OnCreate(HWND hwnd,LPCREATESTRUCT){

hBlueBrush=CreateSolidBrush(RGB(100,100,255));

hGreenBrush=CreateSolidBrush(RGB(100,255,100));

CreateDialog(hInst,"Colors",hwnd,DlgProc);

return TRUE;

}

/*ФункцияOnPaintобработки сообщений WM_PAINT*/

void OnPaint(HWND hwnd){

PAINTSTRUCT ps;

HDC hdc=BeginPaint(hwnd,&ps);

if(sw==1)

FillRect(hdc,&ps.rcPaint,hBlueBrush);

if(sw==2)

FillRect(hdc,&ps.rcPaint,hGreenBrush);

EndPaint(hwnd,&ps);

}

/*Функция OnDestroyобработки сообщенияWM_DESTROY*/

void OnDestroy(HWND){

PostQuitMessage(0);

}

/*Оконная функция немодального диалога*/

BOOL CALLBACK DlgProc(HWND hwnd,UINT msg,

WPARAM wParam,LPARAM lParam){

switch(msg){

HANDLE_MSG(hwnd,WM_INITDIALOG,DlgOnInitDialog);

HANDLE_MSG(hwnd,WM_COMMAND,DlgOnCommand);

default:

return FALSE;

}

}

/*Функция DlgOnInitDialogобработки сообщенияWM_INITDIALOG*/

BOOL DlgOnInitDialog(HWND,HWND,LPARAM){

SendDlgItemMessage(hwnd,ID_BLUE,BM_SETCHECK,1,0);

return TRUE;

}

/*Функция DlgOnCommandобработки сообщения WM_COMMAND*/

void DlgOnCommand(HWND,int id,HWND,UINT){

switch(id){

case ID_BLUE:

sw=1;

InvalidateRect(hWnd,NULL,TRUE);

break;

case ID_GREEN:

sw=2;

InvalidateRect(hWnd,NULL,TRUE);

break;

}

}

В файле ресурсов описывается состав немодального диалогового окна: групповая рамка, имеющая чисто декоративные цели, и две селективные кнопки с идентификаторами IDBLUE иIDGRE­EN.Самому диалогу придается стиль WSVISIBLE | WSCHILD; в этом случае, во-первых, диалоговое окно появится на экране и, во-вторых, его нельзя будет вытащить за пределы главного окна. Если константуWSCHILD опустить, то диалоговое окно можно будет перемещать по всему рабочему столу Windows, что вряд ли целесообразно.

Наш диалог должен появиться на экране вместе с главным окном, поэтому мы создаем его в функции OnCreate(), которая вызывается Windows в процессе создания главного окна.Модальный диалог создавался функциейDialogBox(); немодальный диалог создается другой функцией –CreateDialog(), имеющей те же параметры, что иDialogBox(). В качестве второго параметра функцииCreateDialog() указывается имя диалога в файле ресурсов (в нашем случае"Colors"), а в качестве последнего – имя оконной функции диалогового окна (у насDlgProc). В оконной функции предусмотрена обработка двух сообщений:WMINIT­DIALOG, поступающего в приложение в процессе создания диалогового окна, иWMCOMMAND, возбуждаемого в случае нажатия нами селективных кнопок.

Как и в примере 3-1, перед функцией WinMain() объявлена глобальная переменнаяsw, с помощью которой осуществляется переключение цвета окна. Этой переменной при объявлении присвоено начальное значение 1, чтобы при запуске программы окно сразу стало синим. Однако это назначение никак не повлияет на начальное состояние селективных кнопок – по умолчанию обе они будут отжаты. Поэтому в функцииDlgOnInitDialog() выполняется начальная установка селективных кнопок – “нажатие” кнопки, отвечающей за синий цвет окна. Эта операция – программное управление кнопкой – осуществляется посредством функцииSend­DlgItemMessage().

Функция SendDlgItemMessage() служит для посылки элементам управления диалоговых окон воспринимаемых ими сообщений (для посылки сообщений в обычные окна предусмотрена функция более общего характера –SendMessage()). Прототип функцииSendDlgItemMessage() имеет такой вид:

LONG SendDlgItemMessage (

HWND hwnd,//Дескриптор окна диалога

int id,/*Идентификатор элемента управления, которому

адресовано сообщение*/

UINT uMsg,//Символическая константа – код сообщения

WPARAM wParam,//Первый параметр сообщения

LPARAM lParam//Второй параметр сообщения

);

Каждый элемент управления (кнопка, список и т. д.) характеризуется своим набором сообщений. Для селективных кнопок и кнопок-флажков чаще других используется сообщение BMSETCHECK, позволяющее программно нажать на кнопку. При вызове функцииSendDlgItemMessage()с передачей этого сообщения параметруwParam дается значениеTRUE, если кнопку надо перевести в нажатое состояние, иFALSE, если кнопку надо отпустить. ПараметрlParam не используется и должен быть равен 0.

В примере 4-3 сообщение BMSETCHECKс параметромwParam = TRUE посылается селективной кнопке с идентификаторомID­BLUE (верхней на рис.4.4). Вторая кнопка в этом случае автоматически отжимается.

Функция DlgOnCommand(), вызываемая при щелчке мышью по той или иной селективной кнопке диалогового окна, практически не отличается от аналогичной функции примера 3-1.