- •Лабораторный практикум «Основы разработки приложений Windows» Книга 1
- •Часть 1. Теоретические сведения4
- •Часть 2. Лабораторный практикум95
- •Часть 1 Теоретические сведения
- •1. Структура приложения Windows Простейшая программа с главным окном
- •Структура программы
- •Главная функция WinMain()
- •Регистрация класса окна
- •Создание и показ окна
- •Сообщения Windows и цикл их обработки
- •Оконная функция
- •Макрос handle_msg и структурирование программы
- •2. Интерфейс графических устройств
- •Простая программа, использующая средства gdi
- •Обработка сообщений wmpaint
- •Контекст устройства
- •Использование графических инструментов
- •3. Ресурсы: меню Простая программа с меню
- •Файл ресурсов
- •Описание меню в файле ресурсов
- •Сообщение wmcommand
- •Программное создание меню
- •Плавающее меню
- •Инструментальная панель
- •Всплывающие подсказки
- •0,"Первая строка"
- •1,"Вторая строка"
- •2,"Третья строка"
- •4. Ресурсы: диалоговые окна
- •Простая программа с меню и диалогом
- •Описание диалога в файле ресурсов
- •Обслуживание модального диалога
- •Модальный диалог как главное окно приложения
- •Немодальный диалог
- •Список в диалоговом окне
- •Окно редактирования и статический элемент управления
- •Графика в диалоговом окне
- •Перекрашивание диалогового окна и его элементов
- •Часть 2 Лабораторный практикум Работы лабораторного практикума Работа 1. Вызов функций Windows
- •Работа 2. Главное окно приложения (пример 1-1 из настоящего пособия)
- •Работа 3. Вывод в главное окно приложения текста и фигур (пример 2-1 из настоящего пособия)
- •Работа 4.Вывод в главное окно приложения текста и фигур (индивидуальное задание а)
- •Работа 5. Меню и модальный диалог (пример 4-1 из настоящего пособия)
- •Работа 6.Меню (индивидуальное задание в)
- •Работа 7.Модальный диалог в качестве главного окна приложения (индивидуальное задание с)
- •Работа 8.Вывод графика в главное окно приложения (индивидуальное заданиеD)
- •Работа 9. Немодальный диалог
- •Работа 10. Диалог с окном редактирования
- •Работа 11. Программное создание меню
- •Работа 12. Плавающее меню
- •Работа 13. График в диалоговом окне
- •Работа 14. Инструментальная панель (tool bar)
- •Работа 15. Инструментальная панель со всплывающими подсказками (tool tips)
- •Работа 16. Пользовательские пиктограммы и курсоры
- •Работа 17. Локализация программных продуктов
- •Индивидуальные задания лабораторного практикума
Немодальный диалог
Как уже говорилось, немодальный диалог отличается от модального способом его взаимодействия с программой: модальный диалог блокирует программу до своего завершения, а немодальный сосуществует с программой и может влиять на ход ее выполнения. В составе же диалоговых окон того и другого типа, как и в их описании в файле ресурсов нет никакой специфики. Преобразуем программу примера 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 иIDGREEN.Самому диалогу придается стиль WSVISIBLE | WSCHILD; в этом случае, во-первых, диалоговое окно появится на экране и, во-вторых, его нельзя будет вытащить за пределы главного окна. Если константуWSCHILD опустить, то диалоговое окно можно будет перемещать по всему рабочему столу Windows, что вряд ли целесообразно.
Наш диалог должен появиться на экране вместе с главным окном, поэтому мы создаем его в функции OnCreate(), которая вызывается Windows в процессе создания главного окна.Модальный диалог создавался функциейDialogBox(); немодальный диалог создается другой функцией –CreateDialog(), имеющей те же параметры, что иDialogBox(). В качестве второго параметра функцииCreateDialog() указывается имя диалога в файле ресурсов (в нашем случае"Colors"), а в качестве последнего – имя оконной функции диалогового окна (у насDlgProc). В оконной функции предусмотрена обработка двух сообщений:WMINITDIALOG, поступающего в приложение в процессе создания диалогового окна, иWMCOMMAND, возбуждаемого в случае нажатия нами селективных кнопок.
Как и в примере 3-1, перед функцией WinMain() объявлена глобальная переменнаяsw, с помощью которой осуществляется переключение цвета окна. Этой переменной при объявлении присвоено начальное значение 1, чтобы при запуске программы окно сразу стало синим. Однако это назначение никак не повлияет на начальное состояние селективных кнопок – по умолчанию обе они будут отжаты. Поэтому в функцииDlgOnInitDialog() выполняется начальная установка селективных кнопок – “нажатие” кнопки, отвечающей за синий цвет окна. Эта операция – программное управление кнопкой – осуществляется посредством функцииSendDlgItemMessage().
Функция 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 посылается селективной кнопке с идентификаторомIDBLUE (верхней на рис.4.4). Вторая кнопка в этом случае автоматически отжимается.
Функция DlgOnCommand(), вызываемая при щелчке мышью по той или иной селективной кнопке диалогового окна, практически не отличается от аналогичной функции примера 3-1.