| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C++ Builder > Проблемы с работой динамического меню |
| Автор: EnergoHokum 8.1.2010, 11:40 | ||
На форме определён обработчик события OnMouseUp. Внутри этого обработчика я пытаюсь создать всплывающее меню, и привязать его элемент(ы) к функции(ям) этой-же формы:
Но в этом варианте при выборе пункта меню не происходит вызова ItemSelected. В случае же создания puMenu и item глобально для класса (т. е. объявление в заголовочном файле, puMenu=new TPopupMenu(this); в конструкторе...) ItemSelected вызывается нормально. Это какое-либо принципиальное ограничение VCL, или я что-то недопонял? Очень хочется не размазывать меню (а их будет много) по пространству имён класса, а компактно создавать/уничтожать только там, где они действительно нужны. |
| Автор: SVN74 8.1.2010, 13:04 |
| А почему бы вам просто не воспользоваться (мышкой), благо Builder дает большие возможности для этого... Создаете на форме нужное количество PopupMenu(шек) с нужными действиями и затем привязываете их к конкретным компонентам на форме (для каждого компонента в свойствах есть LINKADE) там есть пункт PopupMenu, в котором выбираете номер нужного меню и все... Ничего писать вообще не надо. У каждого PopupMenu есть свои события , - там и пишите нужные действия. |
| Автор: EnergoHokum 8.1.2010, 13:42 | ||
Не, мышкой -- не вариант. Не получится. |
| Автор: SVN74 8.1.2010, 13:43 |
Почему? |
| Автор: EnergoHokum 8.1.2010, 18:59 | ||
1. Консепся такая (не люблю программировать мышью) 2. Уже из принципа хочется разобраться, почему не получился вариант с созданием TPopupMenu "на месте". |
| Автор: xvr 8.1.2010, 19:43 | ||||
Вот это
|
| Автор: EnergoHokum 8.1.2010, 20:28 | ||||
А можно подробнее? Отчего TPopupMenu(NULL), а не TPopupMenu(this), почему item нельзя затолкать в автоуказатель (его удалением займётся puMenu?), и если это "как минимум", то каким должен быть "как максимум"? Что я упустил/неправильно_понял в изначальном варианте? |
| Автор: xvr 8.1.2010, 20:44 | ||||||
Потому что параметр конструктора TPopupMenu - это его owner. Т.е. тот, кто его будет удалять. Вы же его удаляете сами (через auto_ptr), так что не надо его отдавать форме
|
| Автор: EnergoHokum 8.1.2010, 20:56 | ||||
А-а-а! Вот, блин, сила привычки! Оказывается, иногда и подумать надо!
Блин, вот хоть прям щас всё бросай, и беги на работу -- так охота проверить предложенный вариант! |
| Автор: xvr 9.1.2010, 13:10 | ||
Всегда, на то он и owner. Однако, при явном удалении объекта, он себя удаляет из списка объектов owner'а. Но я бы на это надеятся не стал |
| Автор: EnergoHokum 11.1.2010, 11:04 |
| Вышеприведённые изменения на работу не повлияли, по прежнему в случае объявления TPopupMenu в теле обработчика MouseUp не вызываются связанные с TMenuItem-ами обработчики. Но если объявить TPopupMenu глобально для класса, и проинициализировать в конструкторе -- всё работает корректно. Открытым остаётся вопрос: с чем связано такое поведение, и можно ли его забороть? |
| Автор: EnergoHokum 11.1.2010, 11:28 | ||
Непонятно. Для отображения меню я вызываю у TPopupMenu* метод Popup, собственно. Сразу после выбора пункта меню, когда запускается обработчик -- происходит возврат из Popup-а? Но отчего, в таком случае, не случается access violation, если само меню уже уничтожено? |
| Автор: mrbrooks 11.1.2010, 12:02 | ||
EnergoHokum, здесь все связанно с жизненным циклом объекта. К примеру кнопка никогда не появится:
ибо умный указатель вызовет деструктор по окончании метода. если btn сделать членом класса (или глобально) и выделять и высвобождать память вручную - то все ок - в данном случае, имхо, использовать умные указатели не совсем удобно - но можно. |
| Автор: xvr 11.1.2010, 15:06 | ||
|
| Автор: EnergoHokum 11.1.2010, 15:31 | ||
У меня вообще такое нехорошее ощущение, что в Builder-е не поддерживается вложенность обработчиков событий, а реализуется очередь по типу "выполнен возврат из одного обработчика -- запускаем следующий". |
| Автор: xvr 11.1.2010, 17:33 | ||
Поддерживает, и не Builder, а сама Винда. Позови ShowModal от какой нибудь формы в обработчике - получишь по полной программе |