Главная » C++, C++ Builder » Загрузка динамических меню в CBuilder

0

После предыдущей дискуссии вы могли подумать, что загрузка меню из файла ресурса будет довольно простой задачей. У меню есть свой тип ссылок, именуемый HMENU, и его можно загрузить из ресурса с помощью функции API LoadMenu. Так что вы могли решить, что для загрузки меню из файла ресурса достаточно написать примерно такую строку кода:

MainMenu1->Handle = LoadMenu( HInstance, MAKEINTRESOURCE(ID_MY_MENU));

Вы могли бы так подумать; однако суть в том, что это не работает. Меню  обрабатываются Windows API по-другому, нежели растровые рисунки, значки или строки, так как меню является частью окна, в то время как все остальное — отдельные элементы, не связанные с чем-либо. Я был, по правде говоря, слегка удивлен, что компания  Borland  не  оформила  функциональность меню так же, как оформлено все остальное, но, в конце концов, не надо обольщаться, что кто-то сделает за вас всю работу.

Почему вы не можете написать приведенный только что код? Ответ прост.  Свойство  Handle объекта TMainMenu является частным (private) членом класса, так что вы не можете обращаться к нему напрямую из вашей формы. Вместо этого вы можете обращаться к свойствам меню косвенно, добавляя или удаляя элементы из меню.

Однако выходит, что мы можем эмулировать динамическую загрузку элементов меню, делая это вручную. Для этого поместите на форму компонент TMainMenu (главное меню) без элементов. Форма, которую мы используем,  приведена на рис. 10.2. Как видите, на ней нет ничего,  кроме

главного меню без элементов.

Используя эту форму, мы собираемся загружать меню из файла ресурсов, присоединенного к программе. Во-первых, создайте файл ресурса и присоедините его к программе. Для получения файла ресурса вам нужно создать текстовый файл с определениями ресурсов (как наша таблица строк в предыдущем примере) и затем добавить файл в проект. Для нашего проекта ресурсный файл будет выглядеть так:

1001 MENU PRELOAD DISCARDABLE BEGIN

POPUP "&File"

BEGIN

MENUITEM "&New\tCtrl+N", 101

MENUITEM "&Open…\tCtrl+O", 102 MENUITEM "&P&rint setup…", 103 MENUITEM "&Recent File", 104 MENUITEM "E&xit", 105

END

POPUP "&View" BEGIN

MENUITEM "&Toolbar", 106 MENUITEM "&Status bar", 107 END

POPUP "&Help" BEGIN

MENUITEM "&About", 108 END

END

Рис. 10.2. Форма примера динамического меню

Добавление файла ресурсов в проект — дело нехитрое. Выберите команду меню Project д Add to project и выберите файл ресурса из списка, задав маску файлов *.rc (описания ресурсов). CBuilder знает о файлах ресурсов достаточно, так что он автоматически их скомпилирует и свяжет с исполняемым файлом во время сборки приложения.

Итак, у нас теперь есть некоторые ресурсы, присоединенные к проекту. Нужен нам тот, в котором определено наше меню. Теперь пора научиться загружать этот ресурс из исполняемого файла во время работы приложения. Если бы у вас было несколько меню, то вы могли бы выбирать из них одно, основываясь на каком-либо своем критерии, и точно таким же образом загружать. Давайте

посмотрим на сам код, который загружает меню из ресурса и встраивает его в форму:

void __fastcall TForm1::FormCreate(TObject *Sender)

{

// Загрузить ресурс меню из файла ресурсов

HMENU hMenu = LoadMenu((HINSTANCE) HInstance, MAKEINTRESOURCE(1001));

// Получить количество подменю в этом меню

int nCount = GetMenuItemCount(hMenu);

// Пройтись по всем пунктам,

// получая нужную информацию

for ( int i=0; i<nCount; ++i )

{

// Получить подменю

HMENU hSubMenu = GetSubMenu( hMenu, i );

// Сколько подпунктов в этом меню? char szBuffer[80];

int nSubCount = GetMenuItemCount( hSubMenu ); GetMenuString(  hMenu,i,szBuffer,80,MF_BYPOSITION); TMenuItem *pMenuItem = new TMenuItem(MainMenu1); pMenuItem->Caption = szBuffer;

MainMenu1->Items->Add( pMenuItem );

// Получить информацию о подменю

for ( int nSubPos = 0; nSubPos<bSubCount; ++nSubPos)

{

GetMenuString(  hSubMenu,nSubPos,szBuffer, 80,MF_BYPOSITION );

TMenuItem *pSubMenuItem = new TMenuItem(pMenuItem); pSubMenuItem->Caption = szBuffer;

pMenuItem->Add( pSubMenuItem );

}

}

}

Источник: Теллес М. – Borland C++ Builder. Библиотека программиста – 1998

По теме:

  • Комментарии