// Done by TheTutor -- 9/01/02
// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com
/* Эта обучалка об окнах диалога. Прежде чем мы начнем, будет неплохо определить,
что конкретно подразумевается под диалоговым окном. Вот что говорит Майкрософт:
"Временное окно, содержащее элементы управления. Вы можете использовать его
для отображения информации и получения пользовательского ввода." Ну что же,
действительно, диалоговое окно это в основном "мини-окно" для отображения и/или
получения информации.
Благодаря этой всеобъемлющей функциональности есть сотни различных стилей
диалоговых окон, которые вы можете создавать. Есть несколько способов создания
диалоговых окон в приложениях. В этой обучалке мы используем для этого функцию
CreateDialog(). Используя DialogProc() (реализацию диалогового окна) мы создадим
простейшее диалоговое окно, у которого будет заголовок, 3 кнопки выбора и одна
кнопка. Когда вы нажмете кнопку, появится окно с сообщением (которое, в принципе,
тоже является диалоговым окном), с предложением, указывающим, сколько отмечено
кнопок выбора.
За этим введением следует список шагов, требуемых для создания диалогового окна
с использованием редактора ресурсов VC++6.0. Если вы еще не пользовались этим
редактором, вам следует попробовать. Он значительно упрощает создание меню,
значков, диалоговых окон и т.д.
*/
/************ Список шагов, необходимых для создания нашего диалогового окна
1) Выбрать Project --> Add To Project --> New
2) Выбрать "Resource Script" и назвать "dbox"
3) Нажать правой кнопкой мыши "dbox" --> выбрать Insert --> выбрать IDD_DIALOGBAR (под заголовком Dialog)
4) Нажать New
**Замечание** Если вы не видите "Панель управления" (мини-окно с значками), то
нажмите правой клавишей на меню. Вы увидите список выбранных или не выбранных
пунктов (например: Build MiniBar, ATL, и т.д.). Убедитесь, что выбрано
"Controls".
5) Выбрать "check box" из "Controls" и поместить кнопку выбора в диалоговое окно
6) Повторить шаг #5 еще два раза.
7) Выбрать "button" из "Controls" и поместить в окно диалога
8) Нажать на кнопку правой клавишей --> выбрать Properties --> Поменять надпись на "Apply"
9) Нажать правой клавишей на диалоговое окно --> Выбрать Properties --> Поменять надпись на "Dialog Box",
Выбрать Thin Border, переименовать ID на "DLG_BOX", и выбрать следующие опции:
Title Bar, System Menu, Visible, Tool Window, Client Edge
************/
#include <windows.h>
#include "resource.h" // Это заголовочный файл, который был любезно создан
// для нас VC++6.0, и который содержит все определения
// для нашего диалогового окна
// Ширина и высота окна
#define WIN_WIDTH 640
#define WIN_HEIGHT 480
// Строка с именем для нашего оконного класса
#define CLASS_NAME "GameTutorials_Dialog2"
typedef unsigned char uchar;
// Стандартная callback функция
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
/* Это наша callback для диалогового окна. Если вы внимательно посмотрите, вы
заметите, что ей требуются точно такие же параметры, как и для callback
окна. Это хорошо. Также, как и оконная процедура, эта функция (процедура)
вызывается каждый раз, когда окно получает сообщения. Если, к примеру,
кто-то нажимает кнопку диалогового окна, DialogProc() получит сообщение.
И значит, программный код для диалогового окна будет размещаться внутри
этой функции.
*/
BOOL CALLBACK DialogProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
// WinMain
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow)
{
HWND hwnd; // Ссылка на наше окно
HWND dlgHwnd; // Ссылка на диалоговое окно
MSG msg; // Сообщения, которые может получить наше окно
WNDCLASSEX wndclassex = {0}; // Класс окна
wndclassex.cbSize = sizeof(WNDCLASSEX);
wndclassex.style = CS_HREDRAW | CS_VREDRAW;
wndclassex.lpfnWndProc = WinProc;
wndclassex.hInstance = hinstance;
wndclassex.lpszClassName = CLASS_NAME;
wndclassex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
RegisterClassEx(&wndclassex); // Регистрируем оконный класс
hwnd = CreateWindowEx(NULL,
CLASS_NAME,
"Dialog Box2",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
WIN_WIDTH,
WIN_HEIGHT,
NULL,
NULL,
hinstance,
NULL);
// Проверка на ошибку
if(!hwnd)
return EXIT_FAILURE;
// А здесь мы создаем диалоговое окно
// По параметрам:
// hinstance -- ссылка на экземпляр приложения. Это тот же параметр, который
// передается в CreateWindowEx()
// MAKEINTRESOURCE(DLG_BOX) -- Это макрос Win32, который преобразует целое число
// в тип ресурсов, с которым работает менеджер ресурсов.
// Как правило, вы передаете в этом макросе ID вашего
// диалогового окна (DLG_BOX в нашем случае).
// hwnd -- ссылка на родительское окно
// (DLGPROC)DialogProc -- Указатель на функцию (процедуру), которая обрабатывает
// сообщения диалогового окна.
dlgHwnd = CreateDialog(hinstance,MAKEINTRESOURCE(DLG_BOX),hwnd,(DLGPROC)DialogProc);
// Проверка на ошибку
if(!dlgHwnd)
return EXIT_FAILURE;
ShowWindow(hwnd, ishow);
UpdateWindow(hwnd);
// Главный цикл приложения
while(1)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
}
}
DestroyWindow(dlgHwnd); // Уничтожает (освобождает) наше диалоговое окно
UnregisterClass(CLASS_NAME,hinstance); // Освобождает WNDCLASSEX
return msg.wParam;
}
// WinProc
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
switch(message)
{
case WM_DESTROY:
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wparam, lparam);
}
/* Здесь мы обрабатываем диалоговое окно. Так же, как и в случае с WinProc(),
мы используем эту функцию чтобы обработать все сообщения диалогового окна.
Единственная разница в том, что она возвращает BOOL вместо LRESULT.
Если вы обрататываете сообщение, вы возвращаете TRUE, в противном случае
FALSE.
*/
BOOL CALLBACK DialogProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
// Это три статические переменные, которые будут хранить состояние
// кнопок выбора. Когда мы начинаем, они все не выбраны.
static uchar check1 = 0; // 0 == не выбрано, 1 == выбрано
static uchar check2 = 0;
static uchar check3 = 0;
switch(message)
{
case WM_INITDIALOG: // Это сообщение посылается при создании (инициализации)
// диалогового окна. Поэтому если вы хотите установить
// диалоговое окно в состояние по умолчанию, вам следует
// сделать это здесь.
return TRUE; // Возвращаем true так как мы обработали это сообщение
// (ничего не сделали, но все равно обработали его).
/*
**Замечание** Особое правило для сообщения WM_INITDIALOG. Если вы вызываете
функцию SetFocus() в сообщении WM_INITDIALOG, вам следует возвращать FALSE.
В других случаях возвращайте TRUE как обычно.
*/
/* Сообщение WM_COMMAND посылается при выборе пункта меню, когда элемент управления
посылает уведомление родительскому окну, и т.д.
Как правило, когда что-то нажимается или набирается в нашем диалоговом окне,
мы получаем сообщение WM_COMMAND.
*/
case WM_COMMAND:
switch(LOWORD(wparam))
{
// Если кто-то выбрал кнопку выбора #1
case IDC_CHECK1:
check1 ^= 1; // Изменяем флаг выбора
break;
// Если кто-то выбрал кнопку выбора #2
case IDC_CHECK2:
check2 ^= 1;
break;
// Если кто-то выбрал кнопку выбора #3
case IDC_CHECK3:
check3 ^= 1;
break;
// Если кто-то нажал кнопку "Apply"
case IDC_BUTTON1:
{
char buff[256] = {0};
// Если выбрано "Check 1", добавить это к отображаемой строке
if(check1)
strcat(buff,"Check1 is ON! ");
// Если выбрано "Check 2", добавить это к отображаемой строке
if(check2)
strcat(buff,"Check2 is ON! ");
// Если выбрано "Check 3", добавить это к отображаемой строке
if(check3)
strcat(buff,"Check3 is ON! ");
// Отобразить окно сообщения, которое выводит строку всех
// "отмеченных" кнопок выбора. Если ничего не выбрано,
// появится пустое окно без сообщений.
MessageBox(hwnd,buff,"Check This Out",MB_OK);
break;
}
}
return TRUE; // Мы обработали сообщение, поэтому возвращаем true
case WM_CLOSE:
case WM_DESTROY:
EndDialog(hwnd,0); // EndDialog() закрывает DialogProc() окна диалога.
// Второй параметр это "код возврата", который указывает,
// был ли процесс успешным или нет.
return TRUE; // Мы обработали сообщение, поэтому возвращаем true
}
return FALSE; // Когда вы НЕ обрабатываете сообщение в DialogProc(), вы возвращаете "FALSE"
}
// Как говорилось в обучалке, есть и другие способы вывода окна диалога. Вот еще
// несколько функций, которые создают их:
// CreateDialogIndirect(), DialogBox(), DialogBoxIndirect(), и MessageBoxIndirect()
/*** Задание ***
Сделайте диалоговое окно, которое запрашивает RGB цвет и имеет кнопку "Apply".
Когда пользователь нажимает "Apply", отобразите в окне "Hello World" заданным цветом.
*****************/
/*
| TheTutor
| thetutor@gametutorials.com
| © 2001-2002 GameTutorials
*/
// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com
|