Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблемы с работой динамического меню, внутри обработчика OnMouseUp 
:(
    Опции темы
EnergoHokum
Дата 8.1.2010, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 600
Регистрация: 10.11.2006
Где: Россия, Ставропол ь

Репутация: нет
Всего: 6



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

Код


void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
      TShiftState Shift, int x, int y)
{
  std::auto_ptr<TPopupMenu> puMenu(new TPopupMenu(this));
  std::auto_ptr<TMenuItem> item(new TMenuItem(puMenu.get()));
  item->OnClick=ItemSelected;
  item->Caption="Form mouse up";
  item->Enabled=true;
  puMenu->Items->Add(item.get());
  TPoint pt(x,y);
  pt=ClientToScreen(Point(x,y));
  puMenu->Popup(pt.x,pt.y);
  return;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ItemSelected(TObject* Sender)
{
  //Какое-нить действие
  return;
}



Но в этом варианте при выборе пункта меню не происходит вызова ItemSelected. В случае же создания puMenu и item глобально для класса (т. е. объявление в заголовочном файле, puMenu=new TPopupMenu(this); в конструкторе...) ItemSelected вызывается нормально. Это какое-либо принципиальное ограничение VCL, или я что-то недопонял?
Очень хочется не размазывать меню (а их будет много) по пространству имён класса, а компактно создавать/уничтожать только там, где они действительно нужны.
PM MAIL ICQ   Вверх
SVN74
Дата 8.1.2010, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 5.5.2008
Где: Комсомольск на Дн епре

Репутация: 11
Всего: 18



А почему бы вам просто не воспользоваться (мышкой),  благо Builder дает большие возможности  для этого...
Создаете на форме нужное количество PopupMenu(шек) с нужными действиями и затем привязываете их к конкретным компонентам на форме (для каждого компонента в свойствах есть LINKADE) там есть пункт PopupMenu, в котором выбираете номер нужного меню и все...
Ничего писать вообще не надо. 
У каждого PopupMenu есть свои события , - там и пишите нужные действия. 

Это сообщение отредактировал(а) SVN74 - 8.1.2010, 13:07
PM MAIL WWW   Вверх
EnergoHokum
Дата 8.1.2010, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 600
Регистрация: 10.11.2006
Где: Россия, Ставропол ь

Репутация: нет
Всего: 6



Цитата

А почему бы вам просто не воспользоваться (мышкой)

Не, мышкой -- не вариант. Не получится. smile
PM MAIL ICQ   Вверх
SVN74
Дата 8.1.2010, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 5.5.2008
Где: Комсомольск на Дн епре

Репутация: 11
Всего: 18



Цитата(EnergoHokum @  8.1.2010,  13:42 Найти цитируемый пост)
Не, мышкой -- не вариант. Не получится. 

Почему?
PM MAIL WWW   Вверх
EnergoHokum
Дата 8.1.2010, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 600
Регистрация: 10.11.2006
Где: Россия, Ставропол ь

Репутация: нет
Всего: 6



Цитата

Почему?

1. Консепся такая (не люблю программировать мышью)
2. Уже из принципа хочется разобраться, почему не получился вариант с созданием TPopupMenu "на месте".
PM MAIL ICQ   Вверх
xvr
Дата 8.1.2010, 19:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Вот это
Код

  std::auto_ptr<TPopupMenu> puMenu(new TPopupMenu(this));
  std::auto_ptr<TMenuItem> item(new TMenuItem(puMenu.get()));
должно быть так (это как минимум)
Код

  std::auto_ptr<TPopupMenu> puMenu(new TPopupMenu(NULL));
  TMenuItem* item = new TMenuItem(puMenu.get());

PM MAIL   Вверх
EnergoHokum
Дата 8.1.2010, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 600
Регистрация: 10.11.2006
Где: Россия, Ставропол ь

Репутация: нет
Всего: 6



Цитата

должно быть так (это как минимум)
Код

std::auto_ptr<TPopupMenu> puMenu(new TPopupMenu(NULL));
TMenuItem* item = new TMenuItem(puMenu.get());


А можно подробнее? Отчего TPopupMenu(NULL), а не TPopupMenu(this), почему item нельзя затолкать в автоуказатель (его удалением займётся puMenu?), и если это "как минимум", то каким должен быть "как максимум"? Что я упустил/неправильно_понял в изначальном варианте?

Это сообщение отредактировал(а) EnergoHokum - 8.1.2010, 20:31
PM MAIL ICQ   Вверх
xvr
Дата 8.1.2010, 20:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(EnergoHokum @ 8.1.2010,  20:28)
Отчего TPopupMenu(NULL), а не TPopupMenu(this), 

Потому что параметр конструктора TPopupMenu - это его owner. Т.е. тот, кто его будет удалять. Вы же его удаляете сами (через auto_ptr), так что не надо его отдавать форме
Цитата

почему item нельзя затолкать в автоуказатель (его удалением займётся puMenu?), 
Именно
Цитата

и если это "как минимум", то каким должен быть "как максимум"?
'как минимум' эначит, что это то, что мне сразу бросилось в глаза. Возможно там есть еще косяки (а может и нету)  smile 

PM MAIL   Вверх
EnergoHokum
Дата 8.1.2010, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 600
Регистрация: 10.11.2006
Где: Россия, Ставропол ь

Репутация: нет
Всего: 6



Цитата

параметр конструктора TPopupMenu - это его owner. Т.е. тот, кто его будет удалять.

А-а-а! Вот, блин, сила привычки! Оказывается, иногда и подумать надо! smile В VCL-е всегда owner удаляет явных потомков, или есть исключения из правил?

Цитата

Возможно там есть еще косяки (а может и нету)

Блин, вот хоть прям щас всё бросай, и беги на работу -- так охота проверить предложенный вариант! smile Завтра с утра побегу, а ночью ворочаться буду. smile
PM MAIL ICQ   Вверх
xvr
Дата 9.1.2010, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(EnergoHokum @ 8.1.2010,  20:56)
В VCL-е всегда owner удаляет явных потомков, или есть исключения из правил?

Всегда, на то он и owner. 
Однако, при явном удалении объекта, он себя удаляет из списка объектов owner'а. Но я бы на это надеятся не стал  smile 

PM MAIL   Вверх
EnergoHokum
Дата 11.1.2010, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 600
Регистрация: 10.11.2006
Где: Россия, Ставропол ь

Репутация: нет
Всего: 6



Вышеприведённые изменения на работу не повлияли, по прежнему в случае объявления TPopupMenu в теле обработчика MouseUp не вызываются связанные с TMenuItem-ами обработчики.
Но если объявить TPopupMenu глобально для класса, и проинициализировать в конструкторе -- всё работает корректно.
Открытым остаётся вопрос: с чем связано такое поведение, и можно ли его забороть?
PM MAIL ICQ   Вверх
mrbrooks
Дата 11.1.2010, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306



Цитата(EnergoHokum @  11.1.2010,  11:04 Найти цитируемый пост)
Открытым остаётся вопрос: с чем связано такое поведение, и можно ли его забороть? 

никак. у тебя объект живет во время обработки события OnMouseUp - создается и уничтожается. Причем настолько быстро - что ты даже этого не замечаешь. Выход - либо сделать указатель на контрол  глобальным (не айс), либо как член класса формы (айс).
PM MAIL   Вверх
EnergoHokum
Дата 11.1.2010, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 600
Регистрация: 10.11.2006
Где: Россия, Ставропол ь

Репутация: нет
Всего: 6



Цитата

у тебя объект живет во время обработки события OnMouseUp - создается и уничтожается. Причем настолько быстро - что ты даже этого не замечаешь.

Непонятно. Для отображения меню я вызываю у TPopupMenu* метод Popup, собственно.
Сразу после выбора пункта меню, когда запускается обработчик -- происходит возврат из Popup-а? Но отчего, в таком случае, не случается access violation, если само меню уже уничтожено?
PM MAIL ICQ   Вверх
mrbrooks
Дата 11.1.2010, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306



EnergoHokum, здесь все связанно с жизненным циклом объекта. К примеру кнопка никогда не появится:
Код

#include <memory>
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 std::auto_ptr<TButton>btn(new TButton(this));
 btn->Parent = Form1;
 btn->Caption = "Hello";
 btn->Show();
}


ибо умный указатель вызовет деструктор по окончании метода.

если btn сделать членом класса (или глобально) и выделять и высвобождать память вручную - то все ок - в данном случае, имхо, использовать умные указатели не совсем удобно - но можно. 

Это сообщение отредактировал(а) mrbrooks - 11.1.2010, 12:02
PM MAIL   Вверх
xvr
Дата 11.1.2010, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата

Для отображения меню я вызываю у TPopupMenu* метод Popup, собственно
Popup не блокирует исполнение. Он просто показывает меню и немедленно возвращается.

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0587 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.