- •Лекция 7
- •Меню
- •По способу создания различают статическое и динамическое меню.
- •Элементы меню
- •Значения поля fMask
- •Алгоритм создания меню
- •Функции создания меню
- •Вставка элементов в меню
- •Вставка строк в меню
- •Значения параметра fuFlags
- •Удаление элементов из меню
- •Функция удаления элемента из меню, не разрушая связанные с ним элементы.
- •Управление состоянием
- •Получение информации о меню
- •Сообщения от меню
- •Сообщение WM_MENUSELECT: поступает в процессе курсора меню по строкам меню. Младшее слово wParam
- •Контекстное меню
- •Пример
- •AppendMenu(hmenuFile, MF_SEPARATOR, 0, NULL);
- •case WM_COMMAND:
- •// Выбрали строки "Open" или "New" в меню "File" case CM_FILEOPEN:
- •//Выбрали строку "Close" из меню "File" case CM_FILECLOSE:
- •// Завершаем работу приложения case CM_FILEEXIT:
- •Присвоение значений по умолчанию событиям нажатия пунктов меню. Заголовочный файл “dmenu.hpp”.
- •Более подробно о работе с меню в WinAPI:
- •Строка состояния
- •Сообщения для строки состояния
Контекстное меню
Контекстное меню создают обычным способом, но не вставляют в другое меню. Для отображения и выбора строк контекстного меню используют функцию:
BOOL TrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y,
int nReserved, HWND hwnd, CONST RECT
*prcRect);
hMenu – дескриптор отображаемого плавающего меню. Он может быть создан функцией CreatePopupMenu или получен с помощью GetSubMenu.
X – координата по горизонтали от левого края экрана,
Y – координата по вертикали от правого края экрана,
hwnd – дескриптор окна-владельца.
prcRect – указатель на прямоугольную область, находясь в пределах которой можно работать с меню.
|
Значения uFlags |
|
|
TPM_CENTERALIGN |
Центр меню по горизонтали совпадает с X |
|
|
TPM_LEFTALIGN |
Левый край меню по горизонтали совпадает с X |
|
|
TPM_RIGHTALIGN |
Правый край меню по горизонтали совпадает с X |
|
|
TPM_BOTTOMALIGN |
Нижний край меню по вертикали совпадает с Y |
|
|
TPM_TOPALIGN |
Верхний край меню по вертикали совпадает с Y |
|
|
TPM_VCENTERALIGN |
Центр меню по вертикали совпадает с Y |
|
|
TPM_NONOTIFY |
Не посылать сообщения о выборе строки |
TPM_RETURNCMD |
Возвращать идентификатор вызванной команды |
TPM_LEFTBUTTON |
Прослеживает левую кнопку мыши |
TPM_RIGHTBUTTON |
Прослеживает правую кнопку мыши |
Пример
Описать структуру меню работы с файлами. Добавить новые пункты меню при выборе пункта NEW. Сделать некоторые пункты неактивными.
#define STRICT #include <windows.h> #include <mem.h> #include "dmenu.hpp"
BOOL InitApp(HINSTANCE);
LRESULT CALLBACK _export WndProc(HWND, UINT, WPARAM, LPARAM);
char const szClassName[] = "DMenuClass"; |
// Имя класса окна |
|
char const szWindowTitle[] = "Menu Demo"; |
// Заголовок окна |
|
HMENU hmenu; // Идентификатор меню верхнего уровня |
||
// Идентификаторы временных меню |
|
|
HMENU hmenuFile; |
// "File" |
|
HMENU hmenuEdit; |
// "Edit" |
|
HMENU hmenuHelp; |
// "Help" |
|
//=====================================
//Функция WinMain
//=====================================
#pragma argsused
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
MSG msg; HWND hwnd;
if(!InitApp(hInstance)) return FALSE;
hwnd = CreateWindow( szClassName, szWindowTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, NULL);
if(!hwnd) return FALSE;
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, 0, 0, 0))
{
DispatchMessage(&msg);
}
return msg.wParam;
}
//=====================================
//Функция InitApp
//Выполняет регистрацию класса окна
//=====================================
BOOL InitApp(HINSTANCE hInstance)
{
ATOM aWndClass; WNDCLASS wc;
memset(&wc, 0, sizeof(wc)); // Записываем во все поля структуры нулевые значения
wc.lpszMenuName = NULL;
wc.style |
= 0; |
|
wc.lpfnWndProc |
= (WNDPROC) WndProc; |
|
wc.cbClsExtra |
= 0; |
|
wc.cbWndExtra |
= 0; |
|
wc.hInstance |
|
= hInstance; |
wc.hIcon |
= LoadIcon(NULL, IDI_APPLICATION); |
|
wc.hCursor |
= LoadCursor(NULL, IDC_ARROW); |
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.lpszClassName = (LPSTR)szClassName;
aWndClass = RegisterClass(&wc);
return (aWndClass != 0);
}
//=====================================
//Функция WndProc
//=====================================
LRESULT CALLBACK _export WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
{
hmenu = CreateMenu(); // Создаем пустое меню верхнего уровня SetMenu(hwnd, hmenu); // Подключаем меню к главному окну приложения
hmenuFile = CreatePopupMenu(); // Создаем два временных меню - "File" и "Help“ hmenuHelp = CreatePopupMenu();
// Добавляем строки к меню "File"
AppendMenu(hmenuFile, MF_ENABLED | MF_STRING, CM_FILENEW, "&New"); AppendMenu(hmenuFile, MF_ENABLED | MF_STRING, CM_FILEOPEN, "&Open"); AppendMenu(hmenuFile, MF_GRAYED | MF_STRING, CM_FILECLOSE, "&Close"); AppendMenu(hmenuFile, MF_GRAYED | MF_STRING, CM_FILESAVE, "&Save"); AppendMenu(hmenuFile, MF_GRAYED | MF_STRING, CM_FILESAVEAS, "Save &as...");
AppendMenu(hmenuFile, MF_SEPARATOR, 0, NULL); // Добавляем разделительную линию AppendMenu(hmenuFile, MF_GRAYED | MF_STRING, CM_FILEPRINT, "&Print"); AppendMenu(hmenuFile, MF_GRAYED | MF_STRING, CM_FILEPAGE_SETUP, "Page Se&tup"); AppendMenu(hmenuFile, MF_GRAYED | MF_STRING, CM_FILEPRINTER_SETUP, "P&rinter Setup");
AppendMenu(hmenuFile, MF_SEPARATOR, 0, NULL);
AppendMenu(hmenuFile, MF_DISABLED | MF_STRING, CM_FILEDEMO, "&Demo Version");
AppendMenu(hmenuFile, MF_SEPARATOR, 0, NULL);
AppendMenu(hmenuFile, MF_ENABLED | MF_STRING, CM_FILEEXIT, "E&xit");
// Отмечаем галочкой строку "Demo Version"
CheckMenuItem(hmenuFile, CM_FILEDEMO, MF_BYCOMMAND | MF_CHECKED);
// Добавляем строки к меню "Help"
AppendMenu(hmenuHelp, MF_GRAYED | MF_STRING, CM_HELPINDEX, "&Index\tF1"); AppendMenu(hmenuHelp, MF_GRAYED | MF_STRING, CM_HELPKEYBOARD, "&Keyboard"); AppendMenu(hmenuHelp, MF_GRAYED | MF_STRING, CM_HELPCOMMANDS, "&Commands"); AppendMenu(hmenuHelp, MF_GRAYED | MF_STRING, CM_HELPPROCEDURES, "&Procedures"); AppendMenu(hmenuHelp, MF_GRAYED | MF_STRING, CM_HELPUSING_HELP, "&Using help");
AppendMenu(hmenuHelp, MF_SEPARATOR, 0, NULL);
AppendMenu(hmenuHelp, MF_ENABLED | MF_STRING, CM_HELPABOUT, "&About...");
//Добавkяем временные меню к меню верхнего уровня AppendMenu(hmenu, MF_ENABLED | MF_POPUP, (UINT)hmenuFile, "&File"); AppendMenu(hmenu, MF_ENABLED | MF_POPUP, (UINT)hmenuHelp, "&Help");
//Перерисовываем меню
DrawMenuBar(hwnd);
// Записываем в идентификатор меню "Edit" значение NULL. Если это меню не будет создано, //мы не будем вызывать функцию DestroyMenu для его уничтожения
hmenuEdit = NULL;
return 0;
}
case WM_COMMAND:
{
switch (wParam)
{ // Сообщения от меню case CM_HELPUSING_HELP: case CM_HELPPROCEDURES: case CM_HELPCOMMANDS: case CM_HELPKEYBOARD: case CM_HELPINDEX:
case CM_EDITPASTE: case CM_EDITCOPY: case CM_EDITCUT: case CM_EDITUNDO:
case CM_FILEPRINTER_SETUP: case CM_FILEPAGE_SETUP: case CM_FILEPRINT:
case CM_FILESAVEAS: case CM_FILESAVE:
{
// Выводим сообщение об ошибке
MessageBox(hwnd, "Функция не реализована", NULL, MB_OK); return 0;
}
// Выбрали строку "About..." в меню "Help" case CM_HELPABOUT:
{
MessageBox(hwnd, "Приложение DMENU\n(C) Фролов А.В., 1994", szWindowTitle, MB_OK | MB_ICONINFORMATION);
return 0;
}
// Выбрали строки "Open" или "New" в меню "File" case CM_FILEOPEN:
case CM_FILENEW:
{
hmenuEdit = CreatePopupMenu(); // Создаем временное меню "Edit"
// Добавляем строки в меню "Edit"
AppendMenu(hmenuEdit, MF_GRAYED | MF_STRING, CM_EDITUNDO, "&Undo\tCtrl+Z"); AppendMenu(hmenuEdit, MF_ENABLED | MF_STRING, CM_EDITCUT, "&Cut\tCtrl+X"); AppendMenu(hmenuEdit, MF_ENABLED | MF_STRING, CM_EDITCOPY, "&Copy\tCtrl+C"); AppendMenu(hmenuEdit, MF_ENABLED | MF_STRING, CM_EDITPASTE, "&Paste\tCtrl+V");
// Вставляем меню "Edit" между меню "File" и меню "Help"
InsertMenu(hmenu, 1, MF_BYPOSITION | MF_ENABLED | MF_POPUP, (UINT)hmenuEdit, "&Edit");
//Разблокируем строки "Save", "Save as..." и "Close" в меню "File" EnableMenuItem(hmenuFile, CM_FILESAVE, MF_ENABLED | MF_BYCOMMAND); EnableMenuItem(hmenuFile, CM_FILESAVEAS, MF_ENABLED | MF_BYCOMMAND); EnableMenuItem(hmenuFile, CM_FILECLOSE, MF_ENABLED | MF_BYCOMMAND);
//Блокируем строки "New" и "Open" в меню "File"
EnableMenuItem(hmenuFile, CM_FILENEW, MF_GRAYED | MF_BYCOMMAND);
EnableMenuItem(hmenuFile, CM_FILEOPEN, MF_GRAYED | MF_BYCOMMAND);
// Перерисовываем меню DrawMenuBar(hwnd); return 0;
}
//Выбрали строку "Close" из меню "File" case CM_FILECLOSE:
{
//Уничтожаем временное меню "Edit" DestroyMenu(hmenuEdit); hmenuEdit = NULL;
//Удаляем соответствующую строку в меню верхнего уровня RemoveMenu(hmenu, 1, MF_BYPOSITION);
//Блокируем строки "Save", "Save as..." и "Close" в меню "File" EnableMenuItem(hmenuFile, CM_FILESAVE, MF_GRAYED | MF_BYCOMMAND); EnableMenuItem(hmenuFile, CM_FILESAVEAS, MF_GRAYED | MF_BYCOMMAND); EnableMenuItem(hmenuFile, CM_FILECLOSE, MF_GRAYED | MF_BYCOMMAND);
//Разблокируем строки "New" и "Open" в меню "File"
EnableMenuItem(hmenuFile, CM_FILENEW, MF_ENABLED | MF_BYCOMMAND);
EnableMenuItem(hmenuFile, CM_FILEOPEN, MF_ENABLED | MF_BYCOMMAND);
// Перерисовываем меню DrawMenuBar(hwnd); return 0;
}