Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
UP04_Menyu.doc
Скачиваний:
16
Добавлен:
01.03.2025
Размер:
555 Кб
Скачать
☆

4.4. Плавающее меню

Плавающее меню создают обычным способом, но не вставляют в другое меню. Для отображения и выбора строк этого меню вызывают функцию TrackPopupMenu:

BOOL TrackPopupMenu( HMENU hMenu, UINT uFlags, int x, int y,

int nReserved, HWND hwnd, CONST RECT *prcRect);

Эта функция выводит на экран плавающее меню и создает свой собственный цикл обработки сообщений, завершающий работу после выбора строки. Она не возвращает управление до тех пор, пока работа с меню не будет завершена выбором строки или отказом от выбора.

Параметры:

  1. hMenu – дескриптор отображаемого плавающего меню. Он может быть создан функцией CreatePopupMenu или получен с помощью функции GetSubMenu.

  2. uFlags – комбинация флажков, которые задают функциональные параметры плавающего меню.

    1. Следующие константы задают способ размещения меню по горизонтали относительно параметра х:

      Константа

      Пояснение

      ТРМ_CENTERALIGN

      Центр меню по горизонтали совпадает с х

      ТРМ_LEFTALIGN

      Левый край меню совпадает с х

      TPM_RIGHTALIGN

      Правый край меню совпадает с х

    2. Следующие константы задают способ размещения меню по вертикали относительно параметра у:

      Константа

      Пояснение

      ТРМ_BOTTOMALIGN

      Нижний край меню совпадает с у

      TPM_TOPALIGN

      Верхний край меню совпадает с у

      TPM_VCENTERALIGN

      Центр меню по вертикали совпадает с у

    3. Следующие константы задают способ выбора строк меню без указания окна-владельца для меню:

      Константа

      Пояснение

      ТРМ_NONOTIFY

      Не посылать сообщения о выборе строки

      TPM_RETURNCMD

      Возвращать идентификатор выбранной команды

    4. Следующие константы задают кнопку мыши, которую прослеживает плавающее меню:

      Константа

      Пояснение

      TPM_LEFTBUTTON

      Прослеживает левую кнопку мыши

      TPM_RIGHTBUTTON

      Прослеживает правую кнопку мыши

  3. х – координата по горизонтали от левого края экрана.

  4. у – координата по вертикали от верхнего края экрана.

  5. nReserved – зарезервированный параметр, должен быть всегда равен нулю.

  6. hwnd – дескриптор уже существующего окна-владельца, которое получит сообщения от меню. Сообщение WM_COMMAND окно получит только после завершения работы функции TrackPopupMenu.

  7. prcRect – указатель на прямоугольную область, находясь в пределах которой можно работать с меню. Если сделать щелчок мышью за пределами этого прямоугольника, плавающее меню исчезнет. Если prcRect = NULL, то эта область ограничена прямоугольной рамкой плавающего меню.

В случае успешного выполнения функция возвращает ненулевое значение. Если в параметре uFlags задано TPM_RETURNCMD, то возвращаемое значение равно идентификатору команды выбранной строки. Если элемент не выбран, возвращаемое значение – нуль.

Задача. После нажатия правой клавиши мыши отобразить плавающее меню.

Листинг 4.5. Плавающее меню

#include <windows.h>

#include <tchar.h>

#define CM_EDIT_CUT 2003

#define CM_EDIT_COPY 2004

#define CM_EDIT_PASTE 2005

BOOL RegClass(WNDPROC, LPCTSTR, UINT);

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

HINSTANCE hInstance;

TCHAR szClass[] = TEXT("FloatMenu");

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow)

{

MSG msg;

HWND hwnd;

hInstance = hInst;

if (!RegClass(WndProc, szClass, COLOR_WINDOW)) return FALSE;

hwnd = CreateWindow(szClass, TEXT("Окно с плавающим меню"), WS_OVERLAPPEDWINDOW | WS_VISIBLE,

CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, NULL);

if (!hwnd) return FALSE;

while(GetMessage(&msg, 0, 0, 0))

DispatchMessage(&msg);

return msg.wParam;

}

BOOL RegClass(WNDPROC Proc, LPCTSTR szName, UINT brBackground)

{

WNDCLASS wc;

wc.style = wc.cbClsExtra = wc.cbWndExtra = 0;

wc.lpfnWndProc = Proc;

wc.hInstance = hInstance;

wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);

wc.hCursor = LoadCursor(NULL, IDC_ARROW);

wc.hbrBackground = (HBRUSH)(brBackground +1);

wc.lpszMenuName = NULL;

wc.lpszClassName = szName;

return (RegisterClass(&wc) != 0);

}

BOOL CreateMenuItem(HMENU hMenu, TCHAR *str, UINT uIns, UINT uCom, HMENU hSubMenu, BOOL flag, UINT fType)

{

MENUITEMINFO mii;

mii.cbSize = sizeof(MENUITEMINFO);

mii.fMask = MIIM_STATE | MIIM_TYPE | MIIM_SUBMENU | MIIM_ID;

mii.fType = fType;

mii.fState= MFS_ENABLED;

mii.dwTypeData = str;

mii.cch = sizeof(str);

mii.wID = uCom;

mii.hSubMenu = hSubMenu;

return InsertMenuItem(hMenu, uIns, flag, &mii);

}

LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

{

switch (msg)

{

case WM_COMMAND:

{

switch (LOWORD(wParam))

{

case CM_EDIT_CUT:

{ MessageBox(hwnd, TEXT("Вырезать"), TEXT("Сообщение"), MB_OK); return 0; }

case CM_EDIT_COPY:

{ MessageBox(hwnd, TEXT("Копировать"), TEXT("Сообщение"), MB_OK); return 0; }

case CM_EDIT_PASTE:

{ MessageBox(hwnd, TEXT("Вклеить"), TEXT("Сообщение"), MB_OK); return 0; }

}

return 0;

}

case WM_RBUTTONDOWN:

{

//Берем экранные координаты курсора мыши

DWORD xyPos = GetMessagePos();

WORD xPos = LOWORD(xyPos),

yPos = HIWORD(xyPos);

HMENU hFloatMenu = CreatePopupMenu();

int i=0;

CreateMenuItem( hFloatMenu, TEXT("Вырезать"), i++, CM_EDIT_CUT, NULL, FALSE, MFT_STRING);

CreateMenuItem( hFloatMenu, TEXT("Копировать"), i++, CM_EDIT_COPY, NULL, FALSE, MFT_STRING);

CreateMenuItem( hFloatMenu, TEXT("Вклеить"), i++, CM_EDIT_PASTE, NULL, FALSE, MFT_STRING);

//Выводим меню в позиции курсора мыши

TrackPopupMenu( hFloatMenu, TPM_CENTERALIGN | TPM_LEFTBUTTON | TPM_VCENTERALIGN, xPos, yPos, 0, hwnd, NULL);

DestroyMenu( hFloatMenu);

return 0;

}

case WM_DESTROY: { PostQuitMessage(0); return 0; }

}

return DefWindowProc(hwnd, msg, wParam, lParam);

}

При нажатии правой клавиши мыши в функцию окна поступает сообщение WM_RBUTTONDOWN. При этом параметр lParam содержит координаты курсора мыши относительно левого верхнего угла рабочей области окна. Но для функции TrackPopupMenu требуются экранные координаты. Чтобы меню всплыло вблизи курсора мыши, определяют экранные координаты курсора. С этой целью вызывают функцию GetMessagePos и выделяют горизонтальную xPos и вертикальную yPos составляющие координат:

xyPos = GetMessagePos();

xPos = LOWORD(xyPos);

yPos = HIWORD(xyPos);

Далее обычным способом создают временное меню.

На последнем этапе выводят всплывающее меню:

TrackPopupMenu(hFloatMenu,

TPM_CENTERALIGN | TPM_LEFTBUTTON | TPM_VCENTERALIGN,

xPos, yPos, 0, hwnd, NULL);

Второй аргумент вызова и координаты xPos, yPos подобраны так, что после "всплытия" меню курсор мыши оказывается точно посредине меню.

После выбора строки меню автоматически исчезает, но перед этим посылает сообщение WM_COMMAND с кодом выбранной команды. При обработке этого сообщения на экран выдается сообщение о выбранной строке. Затем уничтожают созданное временное меню.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]