Ресурсы в традиционном приложении Windows, страница 3

Теперь рассмотрим, как создать такой ресурс, как меню. Команда нашего меню вызовет стандартный диалог для выбора цвета, который мы используем для изменения цвета текста.

1.  Выберите команду Insert | Resource... Menu, New

2.  Задайте идентификатор IDR_MENU, имя меню (Edit)

3.  Задайте команду меню Color с идентификатором ID_EDIT_COLOR (он будет создан редактором автоматически).

Теперь можно вставить в WinMain строку кода:

w.lpszMenuName = (char*)(IDR_MENU);    // или MAKEINTRESOURCE(IDR_MENU);

Меню появится в окне приложения, но команда будет бездействующей (grayed). Для того, чтобы она заработала, надо обеспечить ее обработку, то есть вставить соответствующую ветвь блок switch оконной процедуры. Но сначала заготовим некоторые переменные в оконной процедуре.

static COLORREF color = RGB(255,0,0), CustColors[16];

CHOOSECOLOR cc;

Статические переменные color и CustColors[16] будут помнить текущий цвет текста и массив "любимых" цветов. Стандартный диалог по выбору цвета устроен так, что он позволяет отразить на первой странице палитру из 16 произвольных цветов. Их надо хранить в массиве и передавать в диалоговую процедуру адрес массива каждый раз, когда запускается диалог. Структура cc типа CHOOSECOLOR также необходима для работы этого диалога. Для того, чтобы цвет текста принял цвет, который хранится в переменной color, надо перед вызовом функции TextOut вставить строку кода:

SetTextColor(hdc,color);

Обработка команды меню выглядит следующим образом:

case WM_COMMAND:

if (wParam == ID_EDIT_COLOR)

{

ZeroMemory(&cc, sizeof(cc));

cc.lStructSize = sizeof(cc);

cc.lpCustColors = (LPDWORD) CustColors;

if (ChooseColor(&cc)==TRUE)     // Запуск стандартного диалога в модальном режиме

{

color = cc.rgbResult;

InvalidateRect(hWnd,NULL,TRUE);

}

}

break;

Диалог

Теперь создадим свой собственный модальный диалог, запускаемый командой меню Edit | Text Position, в котором предоставим пользователю приложения возможность изменять позицию, в которую выводится строки текста. Для начала следует создать шаблон окна диалога (его форму). На нее следует поместить элементы управления (Controls). Для наших целей достаточно взять один элемент типа Static Text, один Edit Box и две кнопки OK, Cancel. Как само окно диалога, так и все элементы управления (за исключением Static), должны быть идентифицированы. Пусть этими идентификаторами будут символические константы: IDD_XPOS, IDC_XPOS, IDOK, IDCANCEL. Реакцию на выбор второй команды меню обеспечит код, который следует вставить в конец ветви case WM_COMMAND:

else if (wParam == ID_EDIT_TEXTPOSITION)

{

DialogBox (NULL, MAKEINTRESOURCE(IDD_XPOS), hWnd, (DLGPROC) MyDlgProc);

InvalidateRect(hWnd,NULL,TRUE);

}

Обратите внимание на то, что запуск диалога в модальном режиме работы обеспечивает API-функция DialogBox, последним параметром которой является адрес (или имя) функции типа DLGPROC (диалоговой процедуры), которая должна иметь прототип:

BOOL CALLBACK DialogProc (HWND, UINT, WPARAM, LPARAM); и которая будет вызываться системой для обработки сообщений, посылаемых окну диалога.

Отметим, что описатели: CALLBACK, WINAPI и FAR PASCAL идентичны. Они появились на разных этапах развития Windows и одновременно используются системой (для обеспечения совместимости со старыми версиями).

Параметры функции имеют следующий смысл: Windows описатель окна диалога, код сообщения, два параметра, сопровождающих сообщение. Процедуру MyDlgProc предстоит еще написать, но для ее успешной работы необходимо как-то помнить число, которое связано с окном редактирования IDC_XPOS. Самым простым выходом является введение глобальной переменной, которая видна как в оконной, так и в диалоговой процедуре. Заведем сразу две переменные: gnPos и gnMaxPos, которые будут использованы для перемещения текста в окне приложения.

UINT gnPos = 20, gnMaxPos = 700;