лекции / Shchupak_Yu._Win32_API_Razrabotka_prilozheniy_dlya_Windows
.pdf
Внесение изменений в меню |
281 |
|
|
|
|
Так как во всех примерах программного кода в данной книге главное окно прило жения создается с использованием объекта класса KWnd, то рассматриваемый способ присоединения меню реализуется передачей значения MAKEINTRESOURCE(IDR_MENU1) параметру menuName конструктора класса KWnd (чуть позже вы увидите, как это делается, в листинге 6.1).
Напомним, что оконный класс1, регистрируемый с использованием структуры wc типа WNDCLASSEX, определяет меню, используемое по умолчанию всеми окнами этого класса. А что значит «используемое по умолчанию»? Только то, что при со здании окна с помощью функции CreateWindow параметру hMenu этой функции передается значение NULL. Это видно в коде конструктора класса KWnd.
Вы можете связать с окном при его создании другое меню, отличающееся от того, которое применяется по умолчанию. В этом способе требуемое меню снача ла загружается при помощи функции LoadMenu, имеющей следующий прототип:
HMENU LoadMenu(HINSTANCE hInstance, LPCTSTR lpMenuName);
Затем дескриптор меню hMenu, возвращаемый функцией LoadMenu, передается параметру hMenu функции CreateWindow.
Есть и еще один способ назначения меню, когда для этой цели используется функция SetMenu:
BOOL SetMenu(HWND hWnd, HMENU hMenu);
В качестве параметров данная функция принимает дескриптор окна и деск риптор меню, возвращенный функцией LoadMenu. Новое меню заменяет старое меню, если оно уже было.
Внесение изменений в меню
Обычно в сложных приложениях возникает необходимость изменять меню в ходе выполнения программы. Win32 API предоставляет соответствующие функции для модификации меню и его отдельных пунктов.
Состав меню можно изменять с помощью следующих функций:
AppendMenu — добавляет новый элемент в конец меню;
DeleteMenu — удаляет существующий пункт меню и уничтожает его;
InsertMenu — вставляет в меню новый пункт;
RemoveMenu — удаляет существующий пункт меню.
Необходимо хорошо понимать, как различаются функции DeleteMenuи RemoveMenu, когда они применяются к пунктам подменю. Функция DeleteMenu уничтожает это подменю, а функция RemoveMenu — нет.
Для пунктов меню наиболее часто применяются такие изменения, как смена символьной строки имени пункта, установка или снятие отметки, изменение ста туса пункта. Функция SetMenuItemInfo позволяет выполнять сразу несколько та ких операций в одном вызове функции. Можно также использовать более конк
1Не забываете, что оконный класс — это термин Windows, не имеющий никакого отношения к клас сам C++.
282 |
Глава 6. Меню и быстрые клавиши |
|
|
ретные функции для выполнения отдельных операций, которые приведены в сле дующем списке:
CheckMenuItem — управляет отметкой пунктов флажков;
CheckMenuRadioItem — управляет отметкой пунктов переключателей;
EnableMenuItem — изменяет статус пункта меню;
ModifyMenu — изменяет имя пункта меню.
Некоторые из функций стоит рассмотреть более подробно.
Функция CheckMenuItem
Функция ставит или снимает отметку на пункте меню, который интерпретирует ся как флажок:
DWORD CheckMenuItem ( |
|
|
HMENU hmenu, |
// |
дескриптор меню |
UINT uIDCheckItem, // |
идентификатор или позиция пункта меню |
|
UINT uCheck |
// интерпретация второго параметра и выполняемое действие |
|
); |
|
|
Пункт меню, для которого применяется функция, задается вторым парамет ром. Этому параметру передается либо идентификатор пункта меню в файле опи сания ресурсов, либо позиция пункта меню. Выбор варианта интерпретации зада ется в третьем параметре.
Третий параметр, uCheck, задается как побитовая операция объединения двух флагов. Первый флаг может содержать одно из значений: MF_BYCOMMAND или MF_BYPOSITION. Второй флаг может принимать одно из значений: MF_CHECKED или MF_UNCHECKED. Интерпретация указанных значений приведена в табл. 6.2.
Таблица 6.2. Значения флагов для параметра uCheck
Значение |
Описание |
|
|
MF_BYCOMMAND |
Значение uIDCheckItem содержит идентификатор пункта меню |
MF_BYPOSITION |
Значение uIDCheckItem содержит относительную позицию пункта |
|
меню с отсчетом от нуля |
MF_CHECKED |
Поместить отметку слева от имени пункта меню |
MF_UNCHECKED |
Снять отметку слева от имени пункта меню |
|
|
Функцию CheckMenuItem так же, как и функцию CheckMenuRadioItem, можно применять только для пунктов подменю. Пункты главного меню не могут быть помечены.
ВНИМАНИЕ
Используйте всегда флаг MF_BYCOMMAND, передавая параметру uIDCheckItem идентификатор пункта меню. Это предотвратит возможные проблемы в процессе сопровождения программы, если потребуется модификация меню, изменяющая относительные позиции пунктов меню.
Данная рекомендация относится и к последующим функциям, интерфейс которых предоставляет два варианта передачи ссылок на пункты меню.
Функция CheckMenuRadioItem
Эта функция ставит отметку на выбранном пункте переключателе и снимает от метку со всех остальных пунктов переключателей в указанной группе пунктов:
Внесение изменений в меню |
283 |
||
|
|
|
|
|
BOOL CheckMenuRadioItem ( |
|
|
|
HMENU hmenu, |
// дескриптор меню |
|
|
UINT idFirst, // идентификатор или позиция первого пункта в группе |
|
|
|
UINT idLast, |
// идентификатор или позиция последнего пункта в группе |
|
|
UINT idCheck, // идентификатор или позиция выбранного пункта |
|
|
|
UINT uFlags |
// интерпретация параметров idFirst, idLast и idCheck |
|
); |
|
|
|
Если параметр uFlags имеет значение MF_BYCOMMAND, то параметры со второго по четвертый указывают идентификаторы пунктов меню. Если параметр uFlags равен MF_BYPOSITION, то эти параметры указывают позиции пунктов меню.
ВНИМАНИЕ
Задавая в редакторе пункты меню для группы переключателей, следует убедиться, что их идентификаторы в файле resource.h имеют сквозную нумерацию и упорядочены в соответствии с позициями этих пунктов на полосе меню. При нарушении этого условия функция CheckMenuRadioItem может работать некорректно.
Функция EnableMenuItem
Функция позволяет изменять статус пункта меню. Она имеет следующий про тотип:
BOOL EnableMenuItem ( |
|
|
HMENU hMenu, |
// |
дескриптор меню |
UINT uIDEnableItem, // |
идентификатор или позиция пункта |
|
UINT uEnable |
// интерпретация второго параметра и выполняемое действие |
|
); |
|
|
Как и при работе с функцией CheckMenuItem, параметр uEnable должен содер жать флаг MF_BYCOMMAND или MF_BYPOSITION, а также один из трех флагов: MF_ENABLED(пункт разрешен), MF_DISABLED(пункт запрещен) или MF_GRAYED(пункт недоступен).
Если в результате применения функции изменяется статус пункта главного меню, то следует обязательно вызвать функцию DrawMenuBar для повторного ото бражения изменившейся полосы меню.
Функция ModifyMenu
Функция изменяет существующий пункт меню:
BOOL ModifyMenu ( |
|
HMENU hMnu, |
// дескриптор меню |
UINT uPosition, |
// идентификатор или позиция пункта |
UINT uFlags, |
// флаги |
UINT_PTR uIDNewItem, // новый идентификатор пункта |
|
LPCTSTR lpNewItem |
// новое содержание пункта |
); |
|
Параметр uFlags должен содержать один из флагов: MF_BYCOMMAND или MF_BYPOSITION, — значение которых рассматривалось ранее. Кроме того, параметр uFlags может содержать другие флаги, в частности, влияющие на интерпретацию парамет ра lpNewItem. Значения некоторых дополнительных флагов приведены в табл. 6.3.
В этой книге мы рассматриваем меню только с традиционным текстовым пред ставлением его пунктов. Применяя функцию ModifyMenu для меню с текстовым представлением пунктов, используйте флаг по умолчанию MF_STRING.
284 |
Глава 6. Меню и быстрые клавиши |
|
|
Таблица 6.3. Флаги, влияющие на интерпретацию параметра lpNewItem |
|
|
|
Ôëàã |
Значение параметра lpNewItem |
|
|
MF_STRING |
Содержит указатель на C-строку. Этот флаг используется по умолчанию |
MF_BITMAP |
Параметр содержит дескриптор растра. В этом случае пункт меню будет |
|
отображен не в виде текстовой строки, а в виде рисунка |
MF_OWNERDRAW |
Содержит данные, используемые для рисования пункта меню способом |
|
OwnerDraw |
|
|
Отметим, что во всех рассмотренных функциях в качестве первого параметра указывается дескриптор меню. К счастью, Win32 API предоставляет функции, позволяющие определять значения дескрипторов как для главного меню, так и для любого подменю.
Функции для получения дескриптора меню
Дескриптор меню верхнего уровня, связанного с окном hWnd, можно получить при помощи функции GetMenu:
HMENU GetMenu(HWND hWnd);
Функция возвращает значение NULL, если окно hWnd не имеет меню. Эту функ цию нельзя применять для дочерних окон.
Дескриптор подменю определяется вызовом функции GetSubMenu:
HMENU GetSubMenu (
HMENU hMenu, // дескриптор родительского меню
int nPos |
// позиция пункта-подменю в родительском меню |
); |
|
Относительная позиция nPos для пункта родительского меню отсчитывается от нуля. Если пункт с позицией nPos не активизирует всплывающее меню, а явля ется пунктом командой, то функция возвращает значение NULL.
Сообщения меню
Система Windows посылает сообщение WM_COMMAND при каждом выборе пунк та меню, определяющего команду. Обычно это единственное сообщение, обра батываемое приложением, которое может поступить от меню. При выборе пунк тов системного меню вместо указанного сообщения отправляется сообщение
WM_SYSCOMMAND.
Иногда в программе может потребоваться обработка сообщений WM_INITMENU и WM_INITMENUPOPUP. Они отправляются непосредственно перед активизацией главного меню или всплывающего меню. Эти сообщения позволяют приложению изменить меню перед тем, как оно будет отображено на экране.
Сообщение WM_MENUCHAR отправляется, если пользователь пытается исполь зовать клавиатурную «горячую» клавишу, которая не соответствует ни одному из мнемонических символов меню. Это позволяет обрабатывать несколько «горя чих» клавиш для одного пункта меню или отображать сообщение об ошибке.
При навигации по меню система отправляет также сообщение WM_MENUSELECT. Оно более универсально по сравнению c WM_COMMAND, так как инициируется даже тогда, когда выделен недоступный или запрещенный пункт. Это сообщение мо
Сообщения меню |
285 |
|
|
|
|
жет использоваться для формирования контекстной справки меню, которая ото бражается в строке состояния приложения.
В большинстве программ все сообщения от меню, кроме WM_COMMAND, переда ются на обработку в функцию DefWindowProc.
Окно получает и обрабатывает сообщение WM_COMMAND при помощи своей оконной процедуры:
LRESULT CALLBACK WndProc (
HWND |
hWnd, |
// дескриптор окна |
UINT |
uMsg, |
// WM_COMMAND |
WPARAM wParam, // идентификатор пункта меню |
||
LPARAM lParam |
// 0 |
|
);
На самом деле источником сообщений WM_COMMAND могут быть не только пунк ты меню, но и быстрые клавиши, а также другие элементы управления (кнопки, списки, текстовые поля и т. д.). Сообщения от меню или быстрых клавиш всегда имеют нулевое значение параметра lParam. Между собой эти два вида сообщений различаются значением старшего слова wParam (табл. 6.4).
Таблица 6.4. Интерпретация параметров wParam и lParam для сообщений от разных источников
Источник |
Младшее |
Старшее |
lParam |
|
слово wParam |
слово wParam |
|
|
|
|
|
Ìåíþ |
Идентификатор пункта |
0 |
0 |
|
ìåíþ |
|
|
Быстрая клавиша |
Идентификатор быстрой |
1 |
0 |
|
клавиши |
|
|
Элемент управления |
Идентификатор элемента |
Код уведомления |
Дескриптор элемента |
|
управления |
(нотификационного |
управления (HWND) |
|
|
сообщения) |
|
|
|
|
|
Обработка сообщения WM_COMMAND в оконной процедуре осуществляется в блоке оператора switch. Например, в программе MenuDemo1, рассматриваемой ниже, для обработки команд подменю File используется следующий фрагмент кода:
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDM_OPEN:
MessageBox(hWnd, "Выбран пункт 'Open'", "Меню File", MB_OK); break;
case IDM_CLOSE:
MessageBox(hWnd, "Выбран пункт 'Close'", "Меню File", MB_OK); break;
case IDM_SAVE:
MessageBox(hWnd, "Выбран пункт 'Save'", "Меню File", MB_OK); break;
case IDM_EXIT:
SendMessage(hWnd, WM_DESTROY, 0, 0); break;
}
// ...
286 |
Глава 6. Меню и быстрые клавиши |
|
|
Поскольку этот пример является учебным, то вся обработка для команд IDM_OPEN, IDM_CLOSE и IDM_SAVE сводится к выводу окна сообщений при помощи функции MessageBox. Но обработка команды IDM_EXIT содержит вполне реальный код, вы полнение которого вызывает завершение работы приложения.
Приложение MenuDemo1
Для демонстрации техники использования меню приведем пример разработки специального учебного приложения MenuDemo1.
Окно программы MenuDemo1 показано на рис. 6.3. Эта программа должна рисо вать в центре окна прямоугольник, ромб или эллипс по выбору пользователя. Фигура закрашивается однородной кистью. Цвет кисти задается пользователем как комбинация цветовых составляющих Red, Green, Blue с учетом интенсивности, выбираемой из трех вариантов: Dark (темный цвет), Medium (средний цвет), Light (светлый цвет). Также по команде пользователя программа должна увеличивать размеры фигур до полного заполнения клиентской области окна, а также возвра щать их к исходному размеру. Программа должна позволить пользователю скрыть изображение, а потом снова показать его. Также в приложении должно функцио нировать подменю File, пункты которого вызывают окна сообщений с информа цией о выбранном пункте.
Приступим к разработке.
Создайте новый проект с именем MenuDemo1. Скопируйте в папку проекта фай лы KWnd.h и KWnd.cpp из листинга 1.2 и добавьте их в состав проекта. Определите ресурс меню по описанной выше процедуре с сохранением в файле MenuDemo1.rc.
Главное меню должно содержать пункты, которые приведены в табл. 6.5.
Таблица 6.5. Пункты главного меню (0-й уровень)
Имя пункта |
Тип пункта |
Идентификатор |
Позиция |
|
|
|
|
&File |
Подменю |
— |
0 |
&View |
Подменю |
— |
1 |
&Draw shape |
Подменю |
— |
2 |
&Increase! |
Команда |
IDM_RESIZE |
3 |
&About… |
Команда |
IDM_ABOUT |
4 |
|
|
|
|
Имя пункта Increase завершается восклицательным знаком. Это подсказка для пользователя, информирующая, что данный пункт главного меню является ко мандой, а не заголовком подменю.
Подменю File должно содержать пункты, перечисленные в табл. 6.6.
Таблица 6.6. Пункты подменю File (1-й уровень)
Имя пункта |
Тип пункта |
Идентификатор |
|
|
|
&Open… |
Команда |
IDM_OPEN |
&Close… |
Команда |
IDM_CLOSE |
&Save… |
Команда |
IDM_SAVE |
—SEPARATOR —
E&xit |
Команда |
IDM_EXIT |
|
|
|
Приложение MenuDemo1 |
287 |
|
|
|
|
Подменю View должно содержать пункты, перечисленные в табл. 6.7.
Таблица 6.7. Пункты подменю View (1-й уровень)
Имя пункта |
Тип пункта |
Идентификатор |
|
|
|
&Show shape |
Команда |
IDM_SHOW_SHAPE |
&Hide shape |
Команда |
IDM_HIDE_SHAPE |
|
|
|
Подменю Draw shape должно содержать пункты, перечисленные в табл. 6.8.
Таблица 6.8. Пункты подменю Draw shape (1-й уровень)
Имя пункта |
Тип пункта |
Идентификатор |
|
|
|
&Shape |
Подменю |
— |
&Color |
Подменю |
— |
|
|
|
Подменю Shape должно содержать пункты, перечисленные в табл. 6.9.
Таблица 6.9. Пункты подменю Shape (2-й уровень)
Имя пункта |
Тип пункта |
Идентификатор |
|
|
|
&Rectangle |
Команда |
ID_RECTANGLE |
Rhom&b |
Команда |
ID_RHOMB |
&Ellipse |
Команда |
ID_ELLIPSE |
|
|
|
Подменю Color должно содержать пункты, перечисленные в табл. 6.10.
Таблица 6.10. Пункты подменю Color (2-й уровень)
Имя пункта |
Тип пункта |
Идентификатор |
|
|
|
&Red |
Команда |
ID_RED |
&Green |
Команда |
ID_GREEN |
&Blue |
Команда |
ID_BLUE |
— |
SEPARATOR |
— |
&Dark |
Команда |
ID_DARK |
&Medium |
Команда |
ID_MEDIUM |
&Light |
Команда |
ID_LIGHT |
|
|
|
Теперь добавьте к проекту новый файл с именем MenuDemo1.cpp и введите в файл исходный код, приведенный в листинге 6.11.
Листинг 6.1. Проект MenuDemo1
//////////////////////////////////////////////////////////////////////
// MenuDemo1.cpp #include <windows.h> #include <stdio.h> #include "KWnd.h" #include "resource.h"
#define |
W |
200 |
// |
ширина |
фигуры |
|
#define |
H |
140 |
// |
высота |
фигуры |
продолжение |
1Исходные тексты программ, приведенных в книге, можно скачать с сайта издательства http:// www.piter.com.
288 Глава 6. Меню и быстрые клавиши
Листинг 6.1 (продолжение) enum ShapeSize { MAX, MIN };
typedef struct { |
|
int id_shape; |
// идентификатор фигуры |
BOOL fRed; |
// компонент красного цвета |
BOOL fGreen; |
// компонент зеленого цвета |
BOOL fBlue; |
// компонент синего цвета |
int id_bright; |
// идентификатор яркости цвета |
} ShapeData; |
|
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //==================================================================== int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
KWnd mainWnd("MenuDemo1", hInstance, nCmdShow, WndProc, MAKEINTRESOURCE(IDR_MENU1), 100, 100, 400, 300);
while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg);
}
return msg.wParam;
}
//==================================================================== LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC; PAINTSTRUCT ps; RECT rect;
static HMENU hMenu; // дескриптор главного меню int x0, y0, x1, y1, x2, y2;
POINT pt[4];
static ShapeSize shapeSize = MIN; static BOOL bShow = TRUE;
static HBRUSH hBrush, hOldBrush;
char* itemResizeName[2] = { "Decrease!", "Increase!"};
int intensity[3] = { 85, 170, 255 }; // интенсивность RGB-компонентов цвета int brightness;
static ShapeData shapeData;
switch (uMsg)
{
case WM_CREATE:
hMenu = GetMenu(hWnd);
//IDM_OPEN - пункт меню, применяемый по умолчанию SetMenuDefaultItem(GetSubMenu(hMenu, 0), IDM_OPEN, FALSE);
//Исходные отметки пунктов меню CheckMenuRadioItem(GetSubMenu(hMenu, 1), IDM_SHOW_SHAPE,
IDM_HIDE_SHAPE, IDM_SHOW_SHAPE, MF_BYCOMMAND); CheckMenuRadioItem(GetSubMenu(hMenu, 2), ID_RECTANGLE,
ID_ELLIPSE, ID_RECTANGLE, MF_BYCOMMAND); CheckMenuRadioItem(GetSubMenu(hMenu, 2), ID_DARK,
ID_LIGHT, ID_DARK, MF_BYCOMMAND);
shapeData.id_shape = ID_RECTANGLE;
Приложение MenuDemo1 |
289 |
|
|
|
|
|
shapeData.id_bright = ID_DARK; |
|
|
break; |
|
|
case WM_COMMAND: |
|
|
switch (LOWORD(wParam)) |
|
{ |
|
|
|
case IDM_OPEN: |
|
|
MessageBox(hWnd, "Выбран пункт 'Open'", "Меню File", MB_OK); |
|
|
break; |
|
|
case IDM_CLOSE: |
|
|
MessageBox(hWnd, "Выбран пункт 'Close'", "Меню File", MB_OK); |
|
|
break; |
|
|
case IDM_SAVE: |
|
|
MessageBox(hWnd, "Выбран пункт 'Save'", "Меню File", MB_OK); |
|
|
break; |
|
|
case IDM_EXIT: |
|
|
SendMessage(hWnd, WM_DESTROY, 0, 0); |
|
|
break; |
|
|
case IDM_SHOW_SHAPE: |
|
|
bShow = TRUE; |
|
|
CheckMenuRadioItem(GetSubMenu(hMenu, 1), IDM_SHOW_SHAPE, |
|
|
IDM_HIDE_SHAPE, LOWORD(wParam), MF_BYCOMMAND); |
|
|
EnableMenuItem(hMenu, IDM_RESIZE, MF_BYCOMMAND | MFS_ENABLED); |
|
|
DrawMenuBar(hWnd); |
|
|
break; |
|
|
case IDM_HIDE_SHAPE: |
|
|
bShow = FALSE; |
|
|
CheckMenuRadioItem(GetSubMenu(hMenu, 1), IDM_SHOW_SHAPE, |
|
|
IDM_HIDE_SHAPE, LOWORD(wParam), MF_BYCOMMAND); |
|
|
EnableMenuItem(hMenu, IDM_RESIZE, MF_BYCOMMAND | MFS_GRAYED); |
|
|
DrawMenuBar(hWnd); |
|
|
break; |
|
|
case ID_RECTANGLE: |
|
|
shapeData.id_shape = ID_RECTANGLE; |
|
|
CheckMenuRadioItem(GetSubMenu(hMenu, 2), ID_RECTANGLE, |
|
|
ID_ELLIPSE, LOWORD(wParam), MF_BYCOMMAND); |
|
|
break; |
|
|
case ID_RHOMB: |
|
|
shapeData.id_shape = ID_RHOMB; |
|
|
CheckMenuRadioItem(GetSubMenu(hMenu, 2), ID_RECTANGLE, |
|
|
ID_ELLIPSE, LOWORD(wParam), MF_BYCOMMAND); |
|
|
break; |
|
|
case ID_ELLIPSE: |
|
|
shapeData.id_shape = ID_ELLIPSE; |
|
|
CheckMenuRadioItem(GetSubMenu(hMenu, 2), ID_RECTANGLE, |
|
|
ID_ELLIPSE, LOWORD(wParam), MF_BYCOMMAND); |
|
|
break; |
|
|
case ID_RED: |
|
|
shapeData.fRed = ~shapeData.fRed; |
|
|
CheckMenuItem(GetSubMenu(hMenu, 2), ID_RED, |
|
|
MF_BYCOMMAND | shapeData.fRed? MF_CHECKED : MF_UNCHECKED); |
|
|
break; |
|
|
case ID_GREEN: |
|
|
shapeData.fGreen = ~shapeData.fGreen; |
продолжение |
|
|
|
290 Глава 6. Меню и быстрые клавиши
Листинг 6.1 (продолжение)
CheckMenuItem(GetSubMenu(hMenu, 2), ID_GREEN,
MF_BYCOMMAND | shapeData.fGreen? MF_CHECKED : MF_UNCHECKED); break;
case ID_BLUE:
shapeData.fBlue = ~shapeData.fBlue; CheckMenuItem(GetSubMenu(hMenu, 2), ID_BLUE,
MF_BYCOMMAND | shapeData.fBlue? MF_CHECKED : MF_UNCHECKED); break;
case ID_DARK:
shapeData.id_bright = ID_DARK; CheckMenuRadioItem(GetSubMenu(hMenu, 2), ID_DARK,
ID_LIGHT, LOWORD(wParam), MF_BYCOMMAND); break;
case ID_MEDIUM:
shapeData.id_bright = ID_MEDIUM; CheckMenuRadioItem(GetSubMenu(hMenu, 2), ID_DARK,
ID_LIGHT, LOWORD(wParam), MF_BYCOMMAND); break;
case ID_LIGHT:
shapeData.id_bright = ID_LIGHT; CheckMenuRadioItem(GetSubMenu(hMenu, 2), ID_DARK,
ID_LIGHT, LOWORD(wParam), MF_BYCOMMAND); break;
case IDM_RESIZE:
shapeSize = (shapeSize == MIN)? MAX : MIN; ModifyMenu(hMenu, IDM_RESIZE, MF_BYCOMMAND, IDM_RESIZE,
itemResizeName[shapeSize]);
DrawMenuBar(hWnd);
break;
case IDM_ABOUT: MessageBox(hWnd,
"MenuDemo1\nVersion 1.0\nCopyright: Finesoft Corporation, 2005.", "About MenuDemo1", MB_OK);
break;
default:
break;
}
InvalidateRect(hWnd, NULL, TRUE); break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
brightness = intensity[shapeData.id_bright - ID_DARK];
if (bShow) {
hBrush = CreateSolidBrush(RGB( shapeData.fRed? brightness : 0, shapeData.fGreen? brightness : 0, shapeData.fBlue? brightness : 0));
hOldBrush = (HBRUSH)SelectObject(hDC, hBrush);
// Определение центра фигуры (x0, y0) GetClientRect(hWnd, &rect);
