Студопедия

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

КАТЕГОРИИ:

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






Использование немодального диалога






 

 

Рис. 5.3. Пример работы Win-приложения с окном ввода

 

В завершение данной главы преобразуем модальный диалог из предыдущего примера в немодальный. Использование немодального диалога потребует несколько больше усилий, чем использование модального, — в основном потому, что немо­дальный диалог является более независимым окном, нежели модальный. В процессе работы немодального диалога программа остается активной, так что диалог и породившее его окно продолжают получать сообщения. Таким образом, для включения в программу немодального диалога необходимо вставить дополнительный фрагмент в цикл обработки сообщений Вашей программы.

Для создания немодального диалога вместо функции DialogBox() используется функция API CreateDialog():

HWND CreateDialog(HINSTANCE hThisInst,

LPCSTR lpName,

HWND hwnd,

DLGPROC IpDFunc);

 

Здесь hThisInst – дескриптор текущего экземпляра приложения, который пере­дается в качестве параметра в функцию WinMain(), lpName – имя диалога, опреде­ленное в файле ресурсов, hwnd — дескриптор родительского окна для диалога, а lpDFunc – указатель на функцию диалога. Функция диалога в данном случае должна быть описана так же, как и для модального диалога.

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

Для завершения немодального диалога программа должна вызвать функцию DestroyWindow(), а не EndDialog(). Прототип функции DestroyWindow() имеет следую­щий вид:

BOLL DestroyWindow(HWND hwnd);

Параметр hwnd должен задавать дескриптор закрываемого окна (в данном случае диалога).

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

BOOL IsDialogMessage(HWND hdwnd, LPMSG msg);

Здесь hdwnd содержит дескриптор окна немодального диалога, a msg – сообще­ние, полученное в функции GetMessage(). Эта функция возвращает ненулевое значение, если сообщение предназначено для диалога, и нуль в противном случае. Если сообщение предназначено для диалога, оно будет автоматически направлено ему. Таким образом, для работы с немодальным диалогом цикл обработки сообщений Вашей программы должен выглядеть следующим образом:

 

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

if(! IsDialogMessage(hDlg, & msg))

if(! TranslateAccelerator(hwnd, hAccel, & msg))

{

TranslateMessage(& msg); // использ.клавиатуры

DispatchMessage (& msg); // возврат к Windows

}

 

Как видите, сообщение обрабатывается обычным образом только в том случае, если оно не предназначено для диалога.

Создание немодального диалога. Преобразование модального диалога из предыдущего примера в немодальный потребует небольших изменений в программе. Прежде всего необходимо внести изменения в файл ресурсов Mydialog.rc. Поскольку немодальный диалог при создании не отображается автоматически, добавьте в определение диалога стиль WS_VISIBLE. Так как с момента создания файла 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_DIALOG1, VIRTKEY

VK_F3, IDM_DIALOG2, VIRTKEY

VK_F1, IDM_HELP, VIRTKEY

}

MYDB DIALOG 18, 18, 142, 92

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

STYLE DS_MODALFRAME|WS_POPUP|WS_CAPTION|WS_SYSMENU|

WS_VISIBLE

{

DEFPUSHBUTTON " Красный", IDD_RED, 57, 45, 36, 14,

WS_CHILD|WS_VISIBLE|WS_TABSTOP

PUSHBUTTON " Зеленый", IDD_GREEN, 95, 45, 36, 14,

WS_CHILD|WS_VISIBLE|WS_TABSTOP

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

WS_CHILD|WS_VISIBLE|WS_TABSTOP

PUSHBUTTON " Выбери фрукт", IDD_SELFRUIT,

2, 45, 50, 14, WS_CHILD|

WS_VISIBLE|WS_TABSTOP

LISTBOX ID_LB1, 2, 10, 47, 28, LBS_NOTIFY|WS_CHILD|

WS_VISIBLE| WS_BORDER|WS_VSCROLL|

WS_TABSTOP

EDITTEXT ID_EB1, 68, 8, 72, 12, ES_LEFT|

ES_AUTOHSCROLL|WS_CHILD|WS_VISIBLE|

WS_BORDER|WS_TABSTOP

PUSHBUTTON " Конец ввода", IDOK, 68, 22, 60, 14,

WS_CHILD|WS_VISIBLE|WS_TABSTOP

}

 

Далее в программу необходимо внести следующие изменения:

1) вызвать IsDialogMessage() в цикле обработки сообщений.

2) создать диалог, используя функцию CreateDialog(), а не функцию DialogBox().

3) для закрытия диалога заменить функцией DestroyWindows() функцию EndDialog().

 

 

 

Пример 5-4. Полный текст программы, использующей немодальный диалог (с внесенными изменениями), приводится ниже. Пример работы программы приведен на рис. 5.4. Обязательно попробуйте запустить эту программу, чтобы полностью понять разницу между модальным и немодальным диалогами.

Рис. 5.4. В немодальном режиме основная программа и диалог

работают параллельно

 


// Демонстрация немодального диалога

#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;

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

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(! IsDialogMessage(hDlg, & msg))

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:

hDlg=CreateDialog(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)

{

long i;

char str[80];

switch(message)

{

case WM_COMMAND:

switch(LOWORD(wParam))

{

case IDCANCEL:

DestroyWindow(hdwnd);

return 1;

case IDD_RED:

MessageBox(hdwnd,

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

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

return 1;

case IDD_GREEN:

MessageBox(hdwnd,

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

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

return 1;

case ID_LB1: // Сообщение от списка, если

// это, конечно, LBN_DBLCLK

if(HIWORD(wParam) == LBN_DBLCLK)

{ // Получ. индекс выбран. элемента

i=SendDlgItemMessage(hdwnd, ID_LB1,

LB_GETCURSEL,

0, 0L);

sprintf

(str,

" Индекс выбранного элемента %d",

i);

MessageBox(hdwnd, str, " Сделан выбор",

MB_OK);

}

return 1;

case IDD_SELFRUIT: //Кнопка " Выбери фрукт"

i=SendDlgItemMessage(hdwnd, ID_LB1,

LB_GETCURSEL,

0, 0L);

if(i > -1)

sprintf

(str,

" Индекс выбранного элемента %d",

i);

else

sprintf(str, " Фрукт не выбран");

MessageBox(hdwnd, str, " Сделан выбор",

MB_OK);

return 1;

case IDOK: // Кнопка IDOK " Конец ввода"

GetDlgItemText(hdwnd, ID_EB1, str, 80);

MessageBox(hdwnd, str, " Содержимое окна ввода",

MB_OK);

return 1;

}

case WM_INITDIALOG: // Инициализация списка

SendDlgItemMessage(hdwnd, ID_LB1,

LB_ADDSTRING,

0, (LPARAM)" Яблоко");

SendDlgItemMessage(hdwnd, ID_LB1,

LB_ADDSTRING,

0, (LPARAM)" Апельсин");

SendDlgItemMessage(hdwnd, ID_LB1,

LB_ADDSTRING,

0, (LPARAM)" Груша");

SendDlgItemMessage(hdwnd, ID_LB1,

LB_ADDSTRING,

0, (LPARAM)" Виноград");

return 1;

}

return 0;

}

 

В данной главе лишь поверхностно описаны те операции, которые можно выполнять с диалогом и различными элементами управления. Другие элементы управления рассматриваются далее. Вы можете самостоятельно поэкспериментировать, изучая свойства элементов управления.



Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.023 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал