// - "Talk to me like I'm a 3 year old!" Programming Lessons -
//
// $Author: Ben Humphrey digiben@gametutorials.com
//
// $Program: Dialog Boxes
//
// $Description: Create a simple window with a dialog box
//
// $Date: 1/18/01
//
// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com
#include <iostream>
#include <windows.h>
#include "resource.h"
using namespace std; // Подключаем стандартную область имен
// Создаем флаг, который указывает, ввел ли пользователь правильный пароль
bool gCorrectPassword = false;
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
///////////////////////////////// CREATE MY WINDOW \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// Функция создает окно, но не имеет цикла сообщений
/////
///////////////////////////////// CREATE MY WINDOW \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
HWND CreateMyWindow(LPSTR szWindowName, int width, int height, DWORD dwStyle, HINSTANCE hInstance)
{
HWND hwnd;
WNDCLASSEX wndclass;
wndclass.cbSize = sizeof (wndclass);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon (NULL, IDI_WINLOGO);
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szWindowName; // Здесь мы устанавливаем имя для класса окна,
// мы используем имя, передаваемое в функцию.
wndclass.hIconSm = LoadIcon (NULL, IDI_WINLOGO);
RegisterClassEx (&wndclass);
// Если стиль не определен, устанавливаем стиль по умолчанию.
if(!dwStyle) dwStyle = WS_OVERLAPPEDWINDOW;
// *А теперь используем данные из параметров функции, чтобы создать окно.*
hwnd = CreateWindow (szWindowName,
szWindowName,
dwStyle,
CW_USEDEFAULT,
CW_USEDEFAULT,
width,
height,
NULL,
NULL,
hInstance,
NULL);
if(!hwnd) return NULL;
// Если CreateWindow() не дала нам ссылки на окно, возвратим NULL.
ShowWindow(hwnd, SW_SHOWDEFAULT); // Показать окно
UpdateWindow(hwnd); // Нарисовать окно
SetFocus(hwnd); // Установить фокус клавиатуры на окно
return hwnd; // Возвратить ссылку на окно
}
///////////////////////////////// DLG PASSWORD PROC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// Это наша диалоговая процедура, которая обрабатывает сообщения окна диалога.
/////
///////////////////////////////// DLG PASSWORD PROC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
LRESULT CALLBACK DlgPasswordProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
char szPassword[25]={0}; // Будет использоваться для хранения введенного текста
switch( message ) // Диалоговые сообщения
{
case WM_INITDIALOG: // Если окно диалога инициализируется
// Здесь проводим инициализацию (как WM_CREATE)
return TRUE;
case WM_COMMAND: // Если мы нажали на что-нибудь в окне диалога
switch( LOWORD( wParam ) ) // Проверяем LOWORD параметра wParam
{ // (который хранит идентификатор того, что было нажато)
case IDOK: // Проверяем, была ли нажата кнопка OK
// Так мы получаем то, что пользователь ввел в поле "Пароль".
// Функции нужны hWnd, идентификатор элемента управления окна диалога, строка,
// которая содержит то, что введено, и количество символов, которые вы
// хотите взять из поля
GetDlgItemText(hWnd, IDC_PASSWORD, szPassword, 25);
// Проверим, введен ли верный пароль
if(!strcmp(szPassword, "GameTutorials") || !strcmp(szPassword, "gametutorials"))
{
gCorrectPassword = true; // Устанавливаем глобальный флаг в true
EndDialog( hWnd, FALSE ); // Закрываем окно диалога
}
else
{ // Отображаем окно с сообщением, которое
// говорит пользователю, что введен неверный пароль.
MessageBox(hWnd, "Incorrect password! (""GameTutorials"")", "Error!", MB_OK);
}
// MessageBox нужны (ссылка на окно, строка текста, заголовок и дополнительные опции - см. msdn).
return TRUE; // Возвращаемся из процедуры dialog proc
case IDCANCEL: // Проверяем, была ли нажата кнопка отмены
// Отображаем сообщение, говорящее, что мы
// нажали отмену. (MB_OK означает окно сообщения
// с кнопкой OK)
MessageBox(hWnd, "You must enter the correct password! (""GameTutorials"")", "Error!", MB_OK);
EndDialog( hWnd, FALSE ); // Закрываем окно диалога
return TRUE; // Выходим из функции
}
break;
case WM_CLOSE: // Если мы закрываем окно диалога
EndDialog( hWnd, FALSE ); // Закрываем окно диалога
break;
case WM_DESTROY: // Это сообщение бывает, когда окно диалога закрывается
// Если нам нужно что-либо освободить, делаем это здесь
break; // Выходим из цикла
}
return FALSE; // Возвращаем false по умолчанию
}
///////////////////////////////// WIN MAIN \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// Эта функция обязательно должна быть. Это эквивалент консольной функции main().
/////
///////////////////////////////// WIN MAIN \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
MSG msg;
HWND hWnd;
// *** Здесь мы отображаем окно диалога, и затем проверяем, ввели ли мы правильный пароль.
// *** Если нет, то выходим. Если мы производим возврат из WinMain(), программа завершается. Как и с Main().
DialogBox(hInstance, MAKEINTRESOURCE(IDD_PASSWORD), NULL, (DLGPROC)DlgPasswordProc );
if(!gCorrectPassword) return false; // Проверяем, введен ли неверный пароль
// Создаем окно, используя нашу собственную функцию.
hWnd = CreateMyWindow("Dialog Boxes", 800, 600, 0, hInstance);
while (GetMessage (&msg, NULL, 0, 0)) // Это наш главный цикл.
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
UnregisterClass("Dialog Boxes",hInstance); // Нам нужно разрегистрировать класс окна, чтобы освободить память
return msg.wParam ; // Возвращаем wParam структуры "msg".
}
///////////////////////////////// WIN PROC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// Это WndProc, которая обрабатывает все сообщения
/////
///////////////////////////////// WIN PROC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch (iMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam);
}
////////////////////////////////////////////////////////////
//
// *Замечание*
//
// Чтобы у нас было диалоговое окно, нам необходимо создать файл ресурсов.
// Мы идем в меню "Insert" и нажимаем "Resource". Затем мы выбираем окно диалога и ОК.
// Теперь мы можем создать окно диалога.
// И чтобы использовать его, мы должны вызвать:
// DialogBox( HINSTANCE, идентификатор ресурса, NULL (родительское окно), dialog процедура (как WndProc) );
// Второй параметр использует макрос MAKEINTRESOURCE() который преобразует ID в строку.
// Диалоговая процедура это callback функция, которая вызывается каждый раз, когда приходит сообщение
// от диалогового окна. Поэтому когда я нажимаю его, навожу на него курсор, или нажимаю клавишу,
// вызывается та функция, которую мы указали. У каждого диалогового окна должна быть такая функция.
//
// Мы создали собственную функцию, которую мы сможем использовать снова и снова для создания окна.
// Просто вставляйте ее в программу и вызывайте.
//
//
// *Термины*
//
// - Поле : Прямоугольник, куда можно вводить текст с клавиатуры
//
// - Элемент управления: Им может быть все от кнопки до поля, картинки, линии прокрутки...
// В основном это все, что может быть в окне диалога.
//
// - Callback функция : Функция, которая обрабатывает сообщения (т.е. WndProc, DialogProc)
//
// *Элементы управления окна диалога*
//
// У нас 2 элемента управления для статического текста. Статический текст, это текст, который
// не изменяется, по крайней мере пользователем. Также у нас есть окно редактирования. Оно позволяет
// пользователю вводить текст. Есть еще две кнопки по умолчанию, OK и Cancel. Если вы нажмете двойным
// щелчком на окно редактирования (видимо, в редакторе ресурсов - прим.перев.), то появится опция,
// позволяющая скрывать пароль звездочками. Выберите "Password" чтобы установить эту опцию.
// Есть и другие опции.
//
// © 2000-2002 GameTutorials
// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com
|