- •Глава 10 Меню и быстрые клавиши
- •Структура меню
- •Шаблон меню
- •Ссылки на меню в вашей программе
- •Меню и сообщения
- •Образец программы
- •Этикет при организации меню
- •Сложный способ определения меню
- •Независимые всплывающие меню
- •Третий подход к определению меню
- •Использование системного меню
- •Изменение меню
- •Другие команды меню
- •Нестандартный подход к меню
- •Использование в меню битовых образов
- •Два способа создания битовых образов для меню
- •Контекст памяти
- •Создание битового образа, содержащего текст
- •Масштабирование битовых образов
- •Соберем все вместе
- •Добавление интерфейса клавиатуры
- •Быстрые клавиши
- •Зачем нужны быстрые клавиши?
- •Некоторые правила назначения быстрых клавиш
- •Загрузка таблицы быстрых клавиш
- •Преобразование нажатий клавиш клавиатуры
- •Получение сообщений быстрых клавиш
- •Программа poppad, имеющая меню и быстрые клавиши
- •Разрешение пунктов меню
- •Обработка опций меню
Использование системного меню
В родительских окнах, стиль которых содержит идентификатор WS_SYSMENU, имеется зона системного меню в левой части строки заголовка. При желании, можно модифицировать это меню. Например, к системному меню можно добавить собственные команды. Хотя это и не рекомендуется, модификация системного меню — это, как правило, быстрый, но некрасивый способ добавления меню к короткой программе, без определения его в файле описания ресурсов. Здесь имеется только одно ограничение: идентификатор, который вы используете для добавления команды к системному меню должен быть меньше, чем 0xF000. В противном случае он будет конфликтовать с идентификаторами, которые Windows использует для команд обычного системного меню. И запомните: при обработке сообщений WM_SYSCOMMAND для этих новых пунктов меню в вашей оконной процедуре, остальные сообщения WM_SYSCOMMAND вы должны передавать в DefWindowProc. Если вы этого не сделаете, то гарантировано запретите все обычные опции системного меню.
Программа POORMENU ("Poor Person's Menu"), представленная на рис. 10.4, добавляет к системному меню разделительную линию и три команды. Последняя из этих команд удаляет добавления.
POORMENU.MAK
#------------------------
# POORMENU.MAK make file
#------------------------
poormenu.exe : poormenu.obj
$(LINKER) $(GUIFLAGS) -OUT:poormenu.exe poormenu.obj $(GUILIBS)
poormenu.obj : poormenu.c
$(CC) $(CFLAGS) poormenu.c
POORMENU.C
/*-----------------------------------------
POORMENU.C -- The Poor Person's Menu
(c) Charles Petzold, 1996
-----------------------------------------*/
#include <windows.h>
#define IDM_ABOUT 1
#define IDM_HELP 2
#define IDM_REMOVE 3
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
static char szAppName[] = "PoorMenu" ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
HMENU hMenu ;
HWND hwnd ;
MSG msg ;
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_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ;
RegisterClassEx (&wndclass) ;
hwnd = CreateWindow (szAppName, "The Poor-Person's Menu",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
hMenu = GetSystemMenu (hwnd, FALSE) ;
AppendMenu (hMenu, MF_SEPARATOR, 0, NULL) ;
AppendMenu (hMenu, MF_STRING, IDM_ABOUT, "About...") ;
AppendMenu (hMenu, MF_STRING, IDM_HELP, "Help...") ;
AppendMenu (hMenu, MF_STRING, IDM_REMOVE, "Remove Additions") ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch (iMsg)
{
case WM_SYSCOMMAND :
switch (LOWORD (wParam))
{
case IDM_ABOUT :
MessageBox (hwnd, "A Poor-Person's Menu Program.",
szAppName, MB_OK | MB_ICONINFORMATION) ;
return 0 ;
case IDM_HELP :
MessageBox (hwnd, "Help not yet implemented!",
szAppName, MB_OK | MB_ICONEXCLAMATION) ;
return 0 ;
case IDM_REMOVE :
GetSystemMenu (hwnd, TRUE) ;
return 0 ;
}
break ;
case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
}
Рис. 10.4. Программа POORMENU
Три идентификатора меню определяются в самом начале программы POORMENU.С:
#define IDM_ABOUT 1
#define IDM_HELP 2
#define IDM_REMOVE 3
После создания окна POORMENU получает описатель системного меню:
hMenu = GetSystemMenu (hwnd, FALSE) ;
При первом вызове функции GetSystemMenu необходимо установить второй параметр в FALSE для подготовки к модификации меню.
Меню изменяется четырьмя вызовами функции AppendMenu:
AppendMenu (hMenu, MF_SEPARATOR, 0, NULL) ;
AppendMenu (hMenu, MF_STRING, IDM_ABOUT, "About...") ;
AppendMenu (hMenu, MF_STRING, IDM_HELP, "Help...") ;
AppendMenu (hMenu, MF_STRING, IDM_REMOVE, "Remove Additions") ;
Первый вызов функции AppendMenu добавляет разделитель. Выбор пункта меню Remove Additions заставляет программу POORMENU удалить эти добавления, что выполняется просто путем повторного вызова функции GetSystemMenu со вторым параметром, установленным в TRUE:
GetSystemMenu (hwnd, TRUE) ;
В стандартном системном меню имеются опции Restore, Move, Size, Minimize, Maximize, Close и Switch To. Они генерируют сообщения WM_SYSCOMMAND с параметром wParam, равным SC_RESTORE, SC_MOVE, SC_SIZE, SC_MINIMIZE, SC_MAXIMIZE, SC_CLOSE и SC_TASKLIST. Хотя в программах для Windows этого обычно не делается, вы сами можете обработать эти сообщения, а не передавать их в DefWindowProc. Вы также можете запретить или удалить из системного меню некоторые из этих стандартных опций, используя описанные ниже способы. В документацию Windows также включено несколько стандартных дополнений к системному меню. В них используются идентификаторы SC_NEXTWINDOW, SC_PREVWINDOW, SC_VSCROLL, SC_HSCROLL и SC_ARRANGE. Как вы, наверное, догадались, они предназначены для добавления этих команд к системному меню в некоторых приложениях.
