- Кнопки и меню
- Командные и инструментальные кнопки
- Специальные кнопки
- Специфика обработки событий кнопок
- Создание главного меню приложения
- Работа с Редактором Меню в среде VB
- Пример создания оболочки меню в среде VB
- Пример создания оболочки меню в среде BCB
- Создание всплывающих меню в VB
- Создание всплывающих меню в BCB и Delphi
- Нестандартное меню
Нестандартное меню
Опубликовано admin в Сб, 02/27/2010 - 20:31
В приложении можно создать несколько главных и всплывающих меню и, в зависимости от сложившейся ситуации присваивать свойствам MainMenu и PopupMenu нужные значения. Кроме того, главное меню головной формы может сливаться с пунктами меню дочерних форм. Отдельные пункты меню можно исключать, делать недоступными или заменять новыми. Однако, во-первых, это занятие достаточно хлопотное. Во-вторых, инициатива входа в меню и право выбора той или иной команды целиком принадлежат пользователю.
Приложение 5_15 (BCB).
В некоторых приложениях полезно высвечивать различные меню по запланированной логике программы и требовать от пользователя обязательного выбора одного из предложенных блюд. Именно для таких ситуаций предлагается нестандартное решение, описываемое в данном разделе. Идея нестандартного меню заключается в размещении очередного раздела команд в окне списка типа ListBox, размещенного на вспомогательной форме FormMenu, которая динамически создается, формируется по номеру раздела и отображается в режиме ShowModal. Отмахнуться от такого окна пользователь просто так не может, а если еще заголовок окна лишить управляющих кнопок, то единственный выход продолжить работу приложения состоит в выборе одной строк предложенного раздела меню.
Любая функция приложения может обратиться к процедуре ShowMenu, передав ей в качестве единственного параметра целочисленный номер раздела меню. После подготовительной работы по созданию окна FormMenu управление будет передано вспомогательной форме, в момент активизации которой возникнет событие OnActivate. В обработчике этого события и сосредоточены все операции по формированию заданного раздела и подгонке размеров формы под габариты списка. В заголовке формы FormMenu предлагается расположить название раздела отображаемого меню. Для связи по данным между главной и вспомогательной формами номер текущего раздела меню можно передать в глобальную переменную Num_Menu.
В системе BCB функция ShowMenu должна быть включена в состав модуля Unit1, обслуживающего головную форму, и может быть реализована следующим образом:
int ShowMenu(int k)
{
Num_Menu=k;
if(FormMenu != NULL) delete FormMenu;
FormMenu = new TFormMenu(Application);
return FormMenu->ShowModal();
}
Проверка указателя FormMenu предпринята для того, чтобы в случае необходимости удалить форму с предыдущим разделом из памяти. Затем создается новая форма с помощью оператора new и ей передается управление в модальном режиме. Возврат управления в функцию ShowMenu теперь произойдет только тогда, когда один из обработчиков событий формы FormMenu зашлет в системную переменную ModalResult ненулевое значение. И в качестве такого значения естественно выбрать номер выделенной строки списка, увеличенный на 1 (строки в списке нумеруются от 0).
Для демонстрации изложенной идеи мы ограничились формированием двух разделов меню, содержащих соответственно 3 и 6 команд. А вместо выполнения выбранной команды на экран выдается сообщение о выборе пользователя. Сформированное меню подгоняется по высоте под число команд в разделе, а форма FormMenu смещается в верхний правый угол, чтобы не занимать экран. Дополнительные смещения в командах подгонки высоты и положения объектов пришлось подбирать экспериментальным путем. Возможно, что при другом размере или разрешении экрана вам придется проделать то же самое.
Обработчик события OnKeyDown пришлось подключить потому, что без него список реагирует на нажатие некоторых клавиш — стрелки управления курсором, пробел, <End>, <Home>, <Page Up>, <Page Down>. При этом помеченной всегда оказывалась первая строка списка. Один из фрагментов работы с нестандартным меню показан на рис. 5.27.
// Модуль Unit1
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "Unit2.h"
//------------------------------------------------------------------
#pragma resource "*.dfm"
TForm1 *Form1;
int Num_Menu; //Глобальная переменная для номера меню
int ShowMenu(int k);
//------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent *Owner)
: TForm(Owner)
{
}
//------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject* /*Sender*/)
{//Имитация работы с меню
int resp;
resp=ShowMenu(1); //Вывод меню с командами раздела 1
switch (resp)
{ case 1: ShowMessage("Выбрана Команда 1-1");break;
case 2: ShowMessage("Выбрана Команда 1-2");break;
case 3: ShowMessage("Выбрана Команда 1-3");
}
resp=ShowMenu(2); //Вывод меню с командами раздела 2
switch (resp)
{ case 1: ShowMessage("Выбрана Команда 2-1");break;
case 2: ShowMessage("Выбрана Команда 2-2");break;
case 3: ShowMessage("Выбрана Команда 2-3");break;
case 4: ShowMessage("Выбрана Команда 2-4");break;
case 5: ShowMessage("Выбрана Команда 2-5");break;
case 6: ShowMessage("Выбрана Команда 2-6");
}
}
//------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{//Освобождение занятых ресурсов
if(FormMenu != NULL) delete FormMenu;
}
//------------------------------------------------------------------
int ShowMenu(int k)
{//Подготовка и создание формы для меню
Num_Menu=k;
if(FormMenu != NULL) delete FormMenu;
FormMenu = new TFormMenu(Application);
return FormMenu->ShowModal();
}
//Модуль Unit2
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
//-----------------------------------------------------------------
#pragma resource "*.dfm"
TFormMenu *FormMenu;
extern int Num_Menu;
//-----------------------------------------------------------------
__fastcall TFormMenu::TFormMenu(TComponent *Owner)
: TForm(Owner)
{
}
//-----------------------------------------------------------------
void __fastcall TFormMenu::FormActivate(TObject *Sender)
{//Формирование команд меню в списке
ListMenu->Clear();
switch(Num_Menu)
{
case 1: Caption="Раздел 1";
ListMenu->Items->Add("Команда 1-1");
ListMenu->Items->Add("Команда 1-2");
ListMenu->Items->Add("Команда 1-3");
break;
case 2: Caption="Раздел 2";
ListMenu->Items->Add("Команда 2-1");
ListMenu->Items->Add("Команда 2-2");
ListMenu->Items->Add("Команда 2-3");
ListMenu->Items->Add("Команда 2-4");
ListMenu->Items->Add("Команда 2-5");
ListMenu->Items->Add("Команда 2-6");
break;
}
Top=0; //Прижим формы к верхней части экрана
Left=Screen->Width-Width-2;//Прижим формы к правой границе
//Установка высоты списка с небольшим запасом
ListMenu->Height=ListMenu->Items->Count*ListMenu->ItemHeight+5;
//Установка высоты формы с небольшим запасом
Height=ListMenu->Height+27;
}
//------------------------------------------------------------------
void __fastcall TFormMenu::ListMenuClick(TObject *Sender)
{
ModalResult=ListMenu->ItemIndex+1;
}
//------------------------------------------------------------------
void __fastcall TFormMenu::ListMenuKeyDown(TObject *Sender,
WORD &Key, TShiftState Shift)
{
Key=0;
}

Рис. 5.27. Нестандартное меню рядом с главной формой
