Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2007.02.04;
Скачать: [xml.tar.bz2];

Вниз

Обьединить события   Найти похожие ветки 

 
Krants   (2006-11-28 14:35) [0]

В ран-тайме компоненту назначаю определенное событие. Применяя проц. SetMethodProp, но если код события был уже задан, он разумеется заменяется новым.
Имеются ли процедуры или какие-нибудь методы обьединения событий?


 
MBo ©   (2006-11-28 14:44) [1]

можно сохранить старый обработчик, и вызывать его при необходимости


 
Krants   (2006-11-28 14:53) [2]


> можно сохранить старый обработчик, и вызывать его при необходимости

неудобно, да и не очень то подходит.


 
MBo ©   (2006-11-28 14:58) [3]

в Дельфи нет цепочек обработчиков, как в С#, если о чем-то подобном речь идет.


 
Krants   (2006-11-28 15:33) [4]


> можно сохранить старый обработчик, и вызывать его при необходимости


а как можно это сделать?


 
guav ©   (2006-11-28 16:02) [5]

можно посмотреть на TApplicationEvents, он позволяет обрабатывать события TApplication в нескольких экзнмплярах себя.


 
DimaBr   (2006-11-28 16:29) [6]

Предположим что ваш компонент Панель с кнопкой, и на нажатие кнопки вы прописали некое действие, а также хотите вывести обработку события нажатия кнопки на поверхность компонента. Тогда пишем так.

procedure TMyComponent.DoButtonClick(Sender: TObject);
begin
//  DoOldButtonClick;
 if Assigned(OnButtonClick) then OnButtonClick(self);
end;


Можно например запоминать предыдущее событие

property OnClick: TNotifyEvent read fOnClick write SetOnClick;
end;

procedure TMyComponent.SetOnClick(const Value: TNotifyEvent);
begin
 if Value = fOnClick then Exit;
 fOldOnClick := fOnClick;
 fOnClick := Value;
end;

procedure TMyComponent.DoButtonClick(Sender: TObject);
begin
 if Assigned(fOldOnClick) then fOldOnClick(self);
 if Assigned(OnClick) then OnClick(self);
end;


 
Krants   (2006-11-29 11:07) [7]

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


> Modif_Unit.MakeActionListBox(ListBox1);


разумеется это не критичная задача, и я не ищу оптимальных решений, просто интересно разобраться...


 
Krants   (2006-11-29 11:09) [8]


> DimaBr   (28.11.06 16:29) [6]

Задача скорее состоит в не обьединении а добавлении событий. см. [7]


 
Бурундук ©   (2006-11-29 13:28) [9]

Такая вот дурацкая идея пришла в голову:


type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
   procedure FormCreate(Sender: TObject);
 private
   procedure Button1Click2(Sender: TObject);
   procedure Button1Click3(Sender: TObject);
   procedure Button1Click4(Sender: TObject);
 public
   { Public declarations }
 end;

 TNotifyEventRepeater = class(TComponent)
 private
   FHandlers: array of TNotifyEvent;
   function IndexOf(Handler: TNotifyEvent): Integer;
 public
   procedure Add(Handler: TNotifyEvent);
   procedure Remove(Handler: TNotifyEvent);
   procedure Call(Sender: TObject);
 end;

procedure AddMethodProp(Instance: TComponent; const PropName: string; Value: TNotifyEvent);

var Form1: TForm1;

implementation

{$R *.dfm}

procedure AddMethodProp(Instance: TComponent; const PropName: string; Value: TNotifyEvent);
var oldValue, newValue: TMethod;
   repeater: TNotifyEventRepeater;
begin
 oldValue := GetMethodProp(Instance, PropName);
 if TObject(oldValue.Data) is TNotifyEventRepeater then
   TNotifyEventRepeater(oldValue.Data).Add(Value)
 else
 begin
   repeater := TNotifyEventRepeater.Create(Instance);
   repeater.Add(TNotifyEvent(oldValue));
   repeater.Add(TNotifyEvent(Value));

   TNotifyEvent(newValue) := repeater.Call;
   SetMethodProp(Instance, PropName, newValue);
 end;
end;

//procedure RemoveMethodProp(Instance: TComponent; const PropName: string; Value: TNotifyEvent);

{-------------------------- TNotifyEventRepeater ------------------------------}

function TNotifyEventRepeater.IndexOf(Handler: TNotifyEvent): Integer;
var i: Integer;
begin
 Result := -1;
 for i := 0 to Length(FHandlers)-1 do
   if @FHandlers[i] = @Handler then
   begin
     Result := i;
     Break;
   end;
end;

procedure TNotifyEventRepeater.Add(Handler: TNotifyEvent);
var L: Integer;
begin
 if IndexOf(Handler) > -1 then Exit;
 L := Length(FHandlers);
 SetLength(FHandlers, L+1);
 FHandlers[L] := Handler;
end;

procedure TNotifyEventRepeater.Remove(Handler: TNotifyEvent);
var i: Integer;
begin
 i := IndexOf(Handler);
 if i > -1 then FHandlers[i] := nil; // Влом удалять
end;

procedure TNotifyEventRepeater.Call(Sender: TObject);
var i: Integer;
begin
 for i := 0 to Length(FHandlers)-1 do
   if Assigned(FHandlers[i]) then
     FHandlers[i](Sender);
end;

{------------------------------------------------------------------------------}

procedure TForm1.FormCreate(Sender: TObject);
begin
 //!!! Назначать события ТОЛЬКО через AddMethodProp
 AddMethodProp(Button1, "OnClick", Button1Click2);
 AddMethodProp(Button1, "OnClick", Button1Click2);
 AddMethodProp(Button1, "OnClick", Button1Click3);
 AddMethodProp(Button1, "OnClick", Button1Click4);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 Caption := Caption + " Original";
end;

procedure TForm1.Button1Click2(Sender: TObject);
begin
 Caption := Caption + "2";
end;

procedure TForm1.Button1Click3(Sender: TObject);
begin
 Caption := Caption + "3";
end;

procedure TForm1.Button1Click4(Sender: TObject);
begin
 Caption := Caption + "4";
end;


 
Krants   (2006-11-29 16:37) [10]

FHandlers: array of TNotifyEvent; - гениально
спасибо, реально хорошее решение!


 
ors_archangel ©   (2006-12-10 13:03) [11]

Слышали, в C#2 уже анонимные методы сделали, а я вот в Delphi7 сижу и никак не радуюсь...



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2007.02.04;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.043 c
2-1168964455
-John-Doe-
2007-01-16 19:20
2007.02.04
Маленький image у каждой вкладки PageControl в заголовке?


2-1168969622
Jimmy
2007-01-16 20:47
2007.02.04
Сделать активным модальное окно


2-1168850478
wander
2007-01-15 11:41
2007.02.04
Как использовать прогрес-бар для РичЕдит


2-1169022767
sergeyst
2007-01-17 11:32
2007.02.04
StringGrid


15-1168861524
Alex_ey
2007-01-15 14:45
2007.02.04
знание компьютера





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский