- •Глава 10 Меню и быстрые клавиши
- •Структура меню
- •Шаблон меню
- •Ссылки на меню в вашей программе
- •Меню и сообщения
- •Образец программы
- •Этикет при организации меню
- •Сложный способ определения меню
- •Независимые всплывающие меню
- •Третий подход к определению меню
- •Использование системного меню
- •Изменение меню
- •Другие команды меню
- •Нестандартный подход к меню
- •Использование в меню битовых образов
- •Два способа создания битовых образов для меню
- •Контекст памяти
- •Создание битового образа, содержащего текст
- •Масштабирование битовых образов
- •Соберем все вместе
- •Добавление интерфейса клавиатуры
- •Быстрые клавиши
- •Зачем нужны быстрые клавиши?
- •Некоторые правила назначения быстрых клавиш
- •Загрузка таблицы быстрых клавиш
- •Преобразование нажатий клавиш клавиатуры
- •Получение сообщений быстрых клавиш
- •Программа poppad, имеющая меню и быстрые клавиши
- •Разрешение пунктов меню
- •Обработка опций меню
Третий подход к определению меню
Функция LoadMenuIndirect получает указатель на структуру типа MENUITEMTEMPLATE, а возвращает описатель меню. Эта функция используется в Windows для создания меню после загрузки из файла описания ресурсов обычного шаблона меню. Если вы — решительный человек, то можете попытаться самостоятельно определить меню таким образом.
Независимые всплывающие меню
Вы также можете создать меню без строки главного меню. Вместо нее можно создать всплывающее меню, которое будет появляться в любой части экрана. Один из подходов состоит в том, что всплывающее меню должно появляться при щелчке правой кнопки мыши. Однако, сами пункты меню по-прежнему должны выбираться левой кнопкой мыши. Как это делается, показано в программе POPMENU, представленной на рис. 10.3.
POPMENU.MAK
#-----------------------
# POPMENU.MAK make file
#-----------------------
popmenu.exe : popmenu.obj popmenu.res
$(LINKER) $(GUIFLAGS) -OUT:popmenu.exe popmenu.obj \
popmenu.res $(GUILIBS)
popmenu.obj : popmenu.c popmenu.h
$(CC) $(CFLAGS) popmenu.c
popmenu.res : popmenu.rc popmenu.h
$(RC) $(RCVARS) popmenu.rc
POPMENU.C
/*----------------------------------------
POPMENU.C -- Popup Menu Demonstration
(c) Charles Petzold, 1996
----------------------------------------*/
#include <windows.h>
#include "popmenu.h"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
char szAppName[] = "PopMenu" ;
HINSTANCE hInst ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
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) ;
hInst = hInstance ;
hwnd = CreateWindow (szAppName, "Popup Menu Demonstration",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
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)
{
static HMENU hMenu ;
static int iColorID[5] = { WHITE_BRUSH, LTGRAY_BRUSH, GRAY_BRUSH,
DKGRAY_BRUSH, BLACK_BRUSH } ;
static int iSelection = IDM_WHITE ;
POINT point ;
switch (iMsg)
{
case WM_CREATE :
hMenu = LoadMenu (hInst, szAppName) ;
hMenu = GetSubMenu (hMenu, 0) ;
return 0 ;
case WM_RBUTTONDOWN :
point.x = LOWORD (lParam) ;
point.y = HIWORD (lParam) ;
ClientToScreen (hwnd, &point) ;
TrackPopupMenu (hMenu, 0, point.x, point.y, 0, hwnd, NULL) ;
return 0 ;
case WM_COMMAND :
switch (LOWORD (wParam))
{
case IDM_NEW :
case IDM_OPEN :
case IDM_SAVE :
case IDM_SAVEAS :
case IDM_UNDO :
case IDM_CUT :
case IDM_COPY :
case IDM_PASTE :
case IDM_DEL :
MessageBeep (0) ;
return 0 ;
case IDM_WHITE : // Note: Logic below
case IDM_LTGRAY : // assumes that IDM_WHITE
case IDM_GRAY : // through IDM_BLACK are
case IDM_DKGRAY : // consecutive numbers in
case IDM_BLACK : // the order shown here.
CheckMenuItem (hMenu, iSelection, MF_UNCHECKED) ;
iSelection = LOWORD (wParam) ;
CheckMenuItem (hMenu, iSelection, MF_CHECKED) ;
SetClassLong (hwnd, GCL_HBRBACKGROUND,
(LONG) GetStockObject
(iColorID[LOWORD (wParam) - IDM_WHITE])) ;
InvalidateRect (hwnd, NULL, TRUE) ;
return 0 ;
case IDM_ABOUT :
MessageBox (hwnd, "Popup Menu Demonstration Program.",
szAppName, MB_ICONINFORMATION | MB_OK) ;
return 0 ;
case IDM_EXIT :
SendMessage (hwnd, WM_CLOSE, 0, 0) ;
return 0 ;
case IDM_HELP :
MessageBox (hwnd, "Help not yet implemented!",
szAppName, MB_ICONEXCLAMATION | MB_OK) ;
return 0 ;
}
break ;
case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
}
POPMENU.RC
/*----------------------------
POPMENU.RC resource script
----------------------------*/
#include "popmenu.h"
PopMenu MENU
{
POPUP ""
{
POPUP "&File"
{
MENUITEM "&New", IDM_NEW
MENUITEM "&Open...", IDM_OPEN
MENUITEM "&Save", IDM_SAVE
MENUITEM "Save &As...", IDM_SAVEAS
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_EXIT
}
POPUP "&Edit"
{
MENUITEM "&Undo", IDM_UNDO
MENUITEM SEPARATOR
MENUITEM "Cu&t", IDM_CUT
MENUITEM "&Copy", IDM_COPY
MENUITEM "&Paste", IDM_PASTE
MENUITEM "De&lete", IDM_DEL
}
POPUP "&Background"
{
MENUITEM "&White", IDM_WHITE, CHECKED
MENUITEM "&Lt Gray", IDM_LTGRAY
MENUITEM "&Gray", IDM_GRAY
MENUITEM "&Dk Gray", IDM_DKGRAY
MENUITEM "&Black", IDM_BLACK
}
POPUP "&Help"
{
MENUITEM "&Help...", IDM_HELP
MENUITEM "&About PopMenu...", IDM_ABOUT
}
}
}
POPMENU.H
/*-----------------------
POPMENU.H header file
-----------------------*/
#define IDM_NEW 1
#define IDM_OPEN 2
#define IDM_SAVE 3
#define IDM_SAVEAS 4
#define IDM_EXIT 5
#define IDM_UNDO 10
#define IDM_CUT 11
#define IDM_COPY 12
#define IDM_PASTE 13
#define IDM_DEL 14
#define IDM_WHITE 20
#define IDM_LTGRAY 21
#define IDM_GRAY 22
#define IDM_DKGRAY 23
#define IDM_BLACK 24
#define IDM_HELP 30
#define IDM_ABOUT 31
Рис. 10.3. Программа POPMENU
В файле описания ресурсов POPMENU.RC меню определяется почти так, как оно определяется в файле MENUDEMO.RC. Отличие состоит только в том, что главное меню содержит только один пункт — всплывающее меню, содержащее опции File, Edit, Background и Help.
При обработке в WndProc сообщения WM_CREATE программа POPMENU получает описатель этого всплывающего меню:
hMenu = LoadMenu (hInst, szAppName) ;
hMenu = GetSubMenu (hMenu, 0) ;
При обработке сообщения WM_RBUTTONDOWN, программа POPMENU получает положение указателя мыши, преобразует это положение в координаты экрана и передает их функции TrackPopupMenu:
point.x = LOWORD (lParam) ;
point.y = HIWORD (lParam) ;
ClientToScreen (hwnd, &point) ;
TrackPopupMenu (hMenu, 0, point.x, point.y, 0, hwnd, NULL) ;
Затем Windows выводит на экран всплывающее меню с пунктами File, Edit, Background и Help. Выбор любого из этих пунктов приводит к тому, что вложенное всплывающее окно меню появляется на экране правее выбранной опции. Функции этого меню те же, что и у обычного меню.
