Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как правильно убить меню 
:(
    Опции темы
_hunter
  Дата 21.7.2004, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 15
Всего: 98



экземпляр TPopupMenu я создаю динамически а как его освобождать?
( ничего типа OnExit у него нет )


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
<Spawn>
Дата 21.7.2004, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Око кары:)
****


Профиль
Группа: Экс. модератор
Сообщений: 2776
Регистрация: 29.1.2003
Где: Екатеринбург

Репутация: 44
Всего: 64



_hunter Была подобная тема - при активизации метода Popup, меню ведет себя как модальное окно, то есть можно писать так:

Код
 try
   Menu := TPopupMenu.Create(Self);
   Menu.Items.Add(TMenuItem.Create(Self));
   Menu.Items[0].Caption := 'sdf';
   Menu.Popup(100, 100);
 finally
   FreeAndNil(Menu);
 end;



--------------------
"Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков.
PM MAIL ICQ   Вверх
_hunter
Дата 21.7.2004, 19:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 15
Всего: 98



спасибо!
оно -- родимое smile.gif

Это сообщение отредактировал(а) _hunter - 21.7.2004, 19:26


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
_hunter
Дата 21.7.2004, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 15
Всего: 98



обнаружил одну проблему -- при щелчке на меню форма отмерзает раньше срабатывания обработчика клика по меню sad.gif
как с этим бороться?


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Петрович
Дата 22.7.2004, 00:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 25
Всего: 55



Цитата
при щелчке на меню форма отмерзает раньше срабатывания обработчика клика по меню

Еще раз, и попонятнее smile.gif


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
p0s0l
Дата 22.7.2004, 00:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 58
Всего: 112



Попробуй после
Menu.Popup(100, 100);
добавить
Application.ProcessMessages;




--------------------
С уважением, г-н Посол.
PM   Вверх
_hunter
Дата 22.7.2004, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 15
Всего: 98



вот теперь оно smile.gif
спасибо


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Illusion Dolphin
Дата 22.7.2004, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 36
Всего: 63



Если я не ошибаюсь, то справка гласит, что нужно сначала вызвать Release, а потом уже разрушать объект, т.е.:

Код

Код  
try
  Menu := TPopupMenu.Create(Self);
  Menu.Items.Add(TMenuItem.Create(Self));
  Menu.Items[0].Caption := 'sdf';
  Menu.Popup(100, 100);
finally
  Menu.Release; //!
  FreeAndNil(Menu);
end;



Если я не прав - поправьте...


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Петрович
Дата 22.7.2004, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 25
Всего: 55



Цитата
Если я не ошибаюсь, то справка гласит, что нужно сначала вызвать Release, а потом уже разрушать объект, т.е.:

А с каких пор у tPopupMenu есть метод Release ?
И вообще, что-бы он мог делать, если-бы даже был?


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Illusion Dolphin
Дата 22.7.2004, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 36
Всего: 63



Петрович ты сказал верно на 100%...

Код

finally
 Menu.FreeOnRelease;
 Menu:=nil;
end;


Я просто не очень дружелюбно отношусь к Application.ProcessMessages... Так, как я теперь написал - верно?


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Петрович
Дата 23.7.2004, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 25
Всего: 55



Цитата
Я просто не очень дружелюбно отношусь к Application.ProcessMessages

И я тоже.
Цитата
Так, как я теперь написал - верно?

Нет. smile.gif FreeOnRelease может быть полезен лишь для тех объектов, которые связаны с COM-объектами. А Menu:=nil; не уничтожает объект!
А чем просто FreeAndNil(Menu); не подходит?


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Girder
Дата 23.7.2004, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй 2
***


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

Репутация: 31
Всего: 155



Menu:=nil - это присвоению указателю значение ноль. И если var Menu:TPopupMenu определенно не глобально(или данный указатель не проверяется ни где на ноль, т.е if Menu<>nil then...), то достаточно Menu.Free


--------------------
Как слышим, так и пишим.
Истина где-то там...
PM   Вверх
Illusion Dolphin
Дата 23.7.2004, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 36
Всего: 63



Действительно что-то тут непонятно...
Код

 _popupmenu:=Tpopupmenu.Create(nil);
 _popupmenu.Images:=DBKernel.imageList; //задаю изображения
 AddDBContMenu(_popupmenu.items,finfo); //добавляю пункты и события
 _popupmenu.Popup(x,y);
а)  _popupmenu.FreeOnRelease;
б)  _popupmenu.Free;
 _popupmenu:=nil;


Это так я в своей программе реализую своё меню. Оно создаётся прямо на лету вместе с назначением событий (это параметр finfo, но это не важно). Самое интересное то, что если оставить толко пункт а), то всё работает, хотя возникает ощущение, что объект действительно не разрушается (но всё работает!). Однако же если оставить пункт б), то тогда при клике на пункт меню не обрабатывается событие, назначенное этому пункту!!! Значит Free - это не совсем верное уничтожение меню... А Application.ProcessMessages - с ним я уже однажды столько наловился ошибок, что теперь не хочу его использовать, т.к. не совсем понятно что в этой строчке будет выполняться...


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Girder
Дата 23.7.2004, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй 2
***


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

Репутация: 31
Всего: 155



Цитата
то тогда при клике на пункт меню не обрабатывается событие, назначенное этому пункту!!! Значит Free - это не совсем верное уничтожение меню..
sad.gif Так ведь не кому обработать сообщение, ты его раньше разрушил, чем обработал сообщение.


--------------------
Как слышим, так и пишим.
Истина где-то там...
PM   Вверх
Петрович
Дата 23.7.2004, 18:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 25
Всего: 55



Цитата
Так ведь не кому обработать сообщение, ты его раньше разрушил, чем обработал сообщение.

Да. Есть такая фича.
По мне так странно, но в виндах реализованно так - когда вы вызываете _popupmenu.Popup(...), то после клика по пункту меню, винды "закладывают" в очередь сообщение WM_COMMAND. Причем, именно "закладывают", т.е. делают PostMessage а не SendMessage. Запуск-же обработчика клика на пункт меню делается именно по WM_COMMAND. Поэтому, возврат из _popupmenu.Popup(...) происходит до обработки WM_COMMAND. Обработанно оно будет лишь после того как дело дойдет до цикла обработки сообщений.
Если-же сделать _popupmenu.Free сразу за _popupmenu.Popup(...) то, когда будет обрабатываться WM_COMMAND, пункта меню по которому кликнули уже не будет существовать!.
Если-же не делать _popupmenu.Free (вар. a), то объект меню и его пункты не будут уничтожены, и соответственно, будет нормально вызван обработчик клика. Даже не смотря на _popupmenu:=nil - ссылка на кликнутый пункт передается в самом WM_COMMAND.
Вызов Application.ProcessMessages перед _popupmenu.Free решает эту проблему, хотя согласен, далеко не лучшим образом.


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Illusion Dolphin
Дата 23.7.2004, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 36
Всего: 63



Цитата
Вызов Application.ProcessMessages перед _popupmenu.Free решает эту проблему, хотя согласен, далеко не лучшим образом.

А есть ли лучший способ? Меня это уже давно интересует... А то строку Application.ProcessMessages в коде я обычно читаю как "выполни, пожалуйста что-нибудь то, что сейчас находится в очереди, а я при этом буду молиться, что это именно то, что мне надо" wink.gif...


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Girder
Дата 23.7.2004, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй 2
***


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

Репутация: 31
Всего: 155



Ну т.к. ты все равно не сможеш отобразить два всплывающих меню, то можно Menu:TPopupMenu объявить глобально, ну а далее так:
Код
unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, Menus;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   Button3: TButton;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
   procedure Button3Click(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
   procedure ShowPopup();
 end;

var
 Form1: TForm1;
 pMenu:TPopupMenu=nil;

implementation

{$R *.dfm}

procedure TForm1.ShowPopup();
begin
try
 pMenu.Free;
except
end;
pMenu := TPopupMenu.Create(Self);
pMenu.Items.Add(TMenuItem.Create(Self));
pMenu.Items.Add(TMenuItem.Create(Self));
pMenu.Items[0].Caption:='Button2';
pMenu.Items[0].OnClick:=Button2Click;
pMenu.Items[1].Caption:='Button3';
pMenu.Items[1].OnClick:=Button3Click;
pMenu.Popup(300, 300);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ShowPopup;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Caption:='XXX';
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
Caption:='Form1';
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
try
 pMenu.Free;
except
end;
end;

end.



--------------------
Как слышим, так и пишим.
Истина где-то там...
PM   Вверх
Петрович
Дата 23.7.2004, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 25
Всего: 55



Цитата
А то строку Application.ProcessMessages в коде я обычно читаю как "выполни, пожалуйста что-нибудь то, что сейчас находится в очереди, а я при этом буду молиться, что это именно то, что мне надо"

adv/72.gif adv/party.gif adv/65.gif
Отлично! Лучше трудно сказать!
Цитата
А есть ли лучший способ?

Ну вообщем, хотел предложить делать _popupmenu.Free из обработчика клика. Но, вариант Girder мне понравился больше. Только, я-бы сделал чуть-чуть иначе:
Код
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Menus;

type
TForm1 = class(TForm)
  Button1: TButton;
  Button2: TButton;
  Button3: TButton;
  procedure Button1Click(Sender: TObject);
  procedure Button2Click(Sender: TObject);
  procedure Button3Click(Sender: TObject);
  procedure FormCreate(Sender: TObject);
private
  { Private declarations }
  pMenu :TPopupMenu;
public
  { Public declarations }
  procedure ShowPopup();
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 pMenu := TPopupMenu.Create(Self);
end;

procedure TForm1.ShowPopup();
begin
 pMenu.Items.Clear;
 pMenu.Items.Add(TMenuItem.Create(Self));
 pMenu.Items.Add(TMenuItem.Create(Self));
 pMenu.Items[0].Caption:='Button2';
 pMenu.Items[0].OnClick:=Button2Click;
 pMenu.Items[1].Caption:='Button3';
 pMenu.Items[1].OnClick:=Button3Click;
 pMenu.Popup(300, 300);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 ShowPopup;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 Caption:='XXX';
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
 Caption:='Form1';
end;

end.

Делать pMenu.Free в таком случае вообще не надо. Поскольку его владельцем является tForm1, то pMenu будет уничтожен автоматически при уничтожении формы.



--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
p0s0l
Дата 25.7.2004, 03:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 58
Всего: 112



Может в таком случае легче будет вытащить на форму PopupMenu ?... А перед деланьем pMenu.Popup(...) забивать в него нужные итемы...



--------------------
С уважением, г-н Посол.
PM   Вверх
_hunter
Дата 25.7.2004, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 15
Всего: 98



вот вот -- при этом весь смысл динамического создания теряется sad.gif
а мне именно динамически хочется


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Петрович
Дата 25.7.2004, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 25
Всего: 55



Цитата
вот вот -- при этом весь смысл динамического создания теряется

На сколько я понимаю, главный смысл, динамически создавать итемы а не меню.
Если-же смущает что после первого отображения меню (ShowPopup) в нем останутся не уничтоженные итемы до следующего вызова ShowPopup, то это решабельно. Достаточно в конец текста каждого обработчика выбора итема (Button2Click,Button3Click) добавить pMenu.Items.Clear. Тогда, в промежутках между вызовами ShowPopup не будут расходоваться лишние ресурсы для итемов. А само меню, почти ничего не стоит smile.gif.


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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