Определение ресурсов диалога




 

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

Поскольку на практике большинство диалогов создаются при помощи редактора диалогов, ниже дается только краткое описание ресурсов для диалогов, исполь­зуемых в примерах.

Ресурсы для диалогов задаются оператором DIALOG, который имеет вид:

 

ИмяДиалога DIALOG [DISCARDABLE] X, Y, Width, Height

Параметры

{

Элементы диалога

}

 

ИмяДиалога является именем ресурса, который используется диалогом. Координаты верхнего левого угла диалога задаются значениями X и Y, а значения Width и Heightопределяют его размеры. Если диалог может быть удален из памяти, если он не используется, его следует определить как DISCARDABLE. Для диалога можно задать один или несколько параметров. Два из них определяют заголовок и стиль окна диалога. Элементы диалога определяют элементы управления, содержащиеся в диалоге.

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

 

// Пример файла ресурсов, описывающего меню и диалог

#include "Mydialog.h"

#include <Windows.h>

 

MYMENU MENU

{

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

MENUITEM "Диалог &2", IDM_DIALOG2

MENUITEM "Помощь", IDM_HELP

}

 

MYMENU ACCELERATORS

{

VK_F2, IDM_DIALOG 1, VIRTKEY

VK_F3, IDM_DIALOG2, VIRTKEY

VK_Fl, IDM_HELP, VIRTKEY

}

 

MYDB DIALOG 18, 18, 142, 92

CAPTION "Первый диалог"

STYLE DS_MODALFRAME|WS_POPUP|WS_CAPTION|WS_SYSMENU

{

DEFPUSHBUTTON "Красный", IDD_RED, 32, 40, 36, 14,

WS_CHILD|WS_VISIBLE|WS_TABSTOP

PUSHBUTTON "Зеленый", IDD_GREEN, 74, 40, 36, 14,

WS_CHILD|WS_VISIBLE|WS_TABSTOP

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

WS_CHILD|WS_VISIBLE|WS_TABSTOP

}

 

В этом файле определяется диалог MYDB с координатами верхнего левого угла в точке 18, 18, шириной 142 и высотой 92. Строка символов после CAPTION задает заголовок диалога. Оператор STYLE определяет тип окна для создаваемого диалога. Некоторые широко используемые стили, включая и те, которые применяются в данной главе, приведены в таблице 5.1. Их можно комбинировать, используя операцию логического сложения, чтобы получить нужный тип окна. Эти стили могут частично использоваться также элементами управления и другими окнами.

 

Таблица 5.1

Стили диалога

 

Стиль Эффект
  DS_MODALFRAME Создание модального диалога
  WS_BORDER Создание окна с рамкой
  WS_CAPTION Создание окна с заголовком
  WS_CHILD Создание дочернего окна
  WS_MAXIMIZEBOX Окно с кнопкой полноэкранного представления
  WS_MINIMIZEBOX Создание окна с кнопкой минимизации
  WS_SYSMENU Создание окна с системным меню
  WS_TABSTOP Возможность циклического выбора элемента нажатием клавиши табуляции
  WS_VISIBLE Отображение окна при активизации
  WS_POPUP Создание всплывающего окна

 

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

 

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

 

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

В нашем примере используется также файл описаний Mydialog.h. Введите его:

 

#define IDM_DIALOG1 100

#define IDM_DIALOG2 101

#define IDM_HELP 102

#define IDD_RED 103

#define IDD_GREEN 104

 

Оконная функция диалога

 

О всех событиях, происходящих в диалоге, передаются сообщения в функцию, связанную с этим диалогом (а не в функцию главного окна). Приведенная ниже функция диалога обрабатывает сообщения, связанные с диалогом MYDB:

 

// Простая функция диалога

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

MessageBox(hdwnd,

"Выбран Красный",

"Красный",МВ_ОК);

return 1;

case IDD_GREEN:

MessageBox(hdwnd,

"Выбран Зеленый",

"Зеленый",МВ_ОК);

return 1;

}

}

return 0;

}

 

Каждый раз при воздействии на элемент управления диалога в функцию DialogFunc() поступает сообщение WM_COMMAND, в котором LOWORD(wParam) содер­жит идентификатор этого элемента управления.

Функция DialogFunc() обрабатывает три командных сообщения, которые могут генерироваться в нашем диалоге. При нажатии кнопки Сброс сообщение содержит идентификатор IDCANCEL, и диалог завершится посредством вызова функции API EndDialog(). Идентификатор IDCANCEL является стандартным идентификатором, определенным в Windows.h.

Функция EndDialog() имеет следующий прототип:

BOOL EndDialog(HWND hwnd, int nStatus);

 

Параметр hwnd является дескриптором окна диалога, a nStatus содержит значение, возвращаемое функцией DialogBox(). Это значение может игнорироваться, если программа его не использует. Функция EndDialog() возвращает ненулевое значение при успешном завершении и нулевое в противном случае. Обычно эта функция завершается успешно.

Нажатие двух других кнопок вызывает появление окна сообщения, подтверждаю­щего нажатие соответствующей кнопки.

 

Пример 5-1. Ниже приводится полный текст программы с описанием диалога. В начале выполнения профаммы открывается окно, содержащее меню. При выборе команды Диалог 1 открывается диалог. После этого нажатие кнопок в диалоге вызывает соответствующую реакцию. Это отражено на рис. 5.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 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)

{

switch(message)

{

case WM_COMMAND: // Обработка команд

switch(LOWORD(wParam))

{

case IDM_DIALOG1:

DialogBox(hInst,"MYDB",hwnd,

DialogFunc);

break;

case IDM_DIALOG2:

MessageBox(hwnd,

"Этого диалога пока нет","",

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

MessageBox(hdwnd,

"Выбран Красный",

"Красный", MB_OK);

return 1;

case IDD_GREEN:

MessageBox(hdwnd,

"Выбран Зеленый",

"Зеленый", MB_OK);

return 1;

}

}

return 0;

}

 

 

Рис. 5.1. Результаты работы программы с диалогом

 

Обратите внимание на внешнюю переменную hInst. Эта переменная содержит дескриптор текущего экземпляра приложения. Ее существование обусловлено тем, что при создании диалога требуется дескриптор приложения.

Поскольку диалог создается не в WinMain(), а в WindowFunc(), необходима копия дескриптора приложения, доступная извне WinMain().

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-03-31 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: