Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.04.01;
Скачать: CL | DM;

Вниз

определение произошедшего события   Найти похожие ветки 

 
f2d ©   (2007-03-11 22:57) [0]

есть:

procedure BtnProc(Sender:TObject);
begin
....
end;

procedure form1.xxx
var
b:TButton;
begin
...
b.onClick:=BtnProc;
end;


можно ли как-нибудь абстрагировать метод BtnProc чтобы он работал не только для события onClick, но и для других событий кнопки? Мною задумано так, что BtnProc будет загружать и выполнять скрипт.
то есть на нужное нам событие(onClick, onMouseMove,...) мы назначаем BtnProc, а далее, при выполнении процедуры BtnProc она по параметрам, или каким-либо другим образом(свойствам sender"a) определяет что за событие её вызвало и производит соответствующие действия. например если нажали на Button1 то BtnProc должна вызвать скрипт с именем Button1.onClick.scr, если навели на Button2, Button2.onMouseMove.scr.
не могу понять как определить в следствии какого события была вызвана процедура. первое что пришло в голову это то что надо как-то переопределять метод обработки сообщений. поскажите как? или где можно про это почитать.
заранее спасибо.


 
Knight ©   (2007-03-11 23:03) [1]

Имхо.. нельзя.. типы процедур разные...
Самое простое, сделать общую процедуру, в которую отправлять Сендера и условный код операции.


 
f2d ©   (2007-03-11 23:17) [2]

проблема в том что кнопки создаются динамически и создавать все события которыми может обладать кнопка вручную не совсем удобно.
кусок кода
b.onClick:=BtnProc;
я тоже хочу засунуть в отдельный скрипт, чтобы при создании кнопки этот скрипт выполнялся, а уже в нем было бы определено какие события этой кнопки нам нужны. если это батон1, то на него нам нужно только кликать, и в скрипте будет только

begin
button1.onClick:=BtnProc;
end.

если это батон2, то только наводить

begin
button2.onMouseMove:=BtnProc;
end.

и тд...


 
f2d ©   (2007-03-11 23:18) [3]

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


 
Palladin ©   (2007-03-11 23:22) [4]


> f2d ©   (11.03.07 22:57)

Да подожди ты до понедельника :) протрезвею напишу :)


 
Palladin ©   (2007-03-11 23:23) [5]


> f2d ©   (11.03.07 23:18) [3]

до когда тебе это вообще нужно?


 
Knight ©   (2007-03-11 23:26) [6]

А почему бы не сделать два обработчика
ButtonsOnClick(...) и ButtonsOnMouseMove(...;...;...)
И присваивать нужным кнопкам... А в них вызывать BtnProc или разбить BtnProc на пару частей, если они объединены искуственно...

Или подождать Паладина и он что-нить придумает :)


 
Юрий Зотов ©   (2007-03-11 23:27) [7]

> f2d ©   (11.03.07 23:17) [2]

Обработчики событий OnClick и OnMouseMove имеют разные наборы параметров.

Каким образом Вы собираетесь написать один метод с двумя разными наборами параметров?


 
f2d ©   (2007-03-11 23:29) [8]


> Юрий Зотов ©  

к тому я и спрашиваю - "можно ли как-нибудь абстрагировать метод BtnProc чтобы он работал не только для события onClick, но и для других событий кнопки?"


> Palladin ©  

горит блин) не могу сидеть и ничего не делать :)


 
DrPass ©   (2007-03-11 23:36) [9]


> f2d ©   (11.03.07 23:29) [8]

Сказали ж уже - нельзя.


 
Palladin ©   (2007-03-11 23:39) [10]


> Юрий Зотов ©   (11.03.07 23:27) [7]

:) очень просто, нырнуть в исходники RemObjects Pascal Script и разнюхать


> f2d ©   (11.03.07 23:29) [8]

короче есть два путя:

либо как я уже сказал нырнуть туда и разнюхать, бо он позволяет в скрипте создавать объекты и устанавливать свойства-методы, это долгий путь, врядли тебе в короткие сроки удасться

либо регистрировать существующие объекты движку через SetVarInstance и "дописывать" программно скрипт кодом назначения этим объектам свойств


 
Knight ©   (2007-03-11 23:39) [11]


> [8] f2d ©   (11.03.07 23:29)
> к тому я и спрашиваю - "можно ли как-нибудь абстрагировать
> метод BtnProc

Можно... написать свой компонент баттон у которого будет на все события один единственный обработчик :)


 
Юрий Зотов ©   (2007-03-11 23:48) [12]

> f2d ©   (11.03.07 23:29) [8]

> "можно ли как-нибудь абстрагировать метод BtnProc чтобы он работал не
> только для события onClick, но и для других событий кнопки?"

Для событий с одинаковыми параметрами - легко. Просто назначить.

Для событий с разными параметрами - еще раз: каким образом Вы собираетесь написать один метод с двумя разными наборами параметров?

Вот напишите его прямо здесь.

type
 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   procedure FormCreate(Sender: TObject);
 public
   procedure ButtonHandler(Sender: TObject); overload;
   procedure ButtonHandler(Sender: TObject; Shift: TShiftState; X, Y: Integer); overload;
 end;

procedure TForm1.ButtonHandler(Sender: TObject);
begin
 ShowMessage("")
end;

procedure TForm1.ButtonHandler(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
 ShowMessage("")
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Button1.OnClick := ButtonHandler;
 Button2.OnMouseMove := ButtonHandler;
end;

Этот код работает. Но, как видите, в нем не один, а два метода. Хотя и с одинаковыми именами, но все равно два.

Вы же собираетесь запихнуть два разных набора параметров в один метод. Спрашивается - каким образом?

Допустим, что компилятор такой умный, что пропустит и нормально скомпилирует любой заголовок метода. Но попробуйте его вообще написать. Вот прямо здесь и сейчас.


 
Юрий Зотов ©   (2007-03-12 00:05) [13]

Попробовал заюзать дефолтные параметры:

procedure TForm1.ButtonHandler(Sender: TObject; Shift: TShiftState = []; X: Integer = 0; Y: Integer = 0);

Не пущает, ругается (D7).


 
Knight ©   (2007-03-12 00:14) [14]

И прикола я чё-то всё-равно не понял... почему нельзя всем onClick назначить обработчик из которого вызывать скрипт обработки клика.. а из общего обработчика OnMouseMove вызывать скрипт обработки мува... и т.д... %(


 
f2d ©   (2007-03-12 00:18) [15]


> либо регистрировать существующие объекты движку через SetVarInstance
> и "дописывать" программно скрипт кодом назначения этим объектам
> свойств

мне придётся какому-либо событию присваивать процедуру которая будет это событие обрабатывать. эта процедура должна находиться в основном коде программы либо она может находиться в скрипте?

скорее всего пойду по первому пути, то есть создавать объекты тоже буду в скрипте. думаю так будет проще потому как реализовать эту "технологию" нужно будет не только для кнопок, но и для других компонентов, которые могут быть созданы динамечески. Panel, Memo,... например.

сейчас буду пробовать


 
Palladin ©   (2007-03-12 00:22) [16]


> f2d ©   (12.03.07 00:18) [15]

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


 
f2d ©   (2007-03-12 00:31) [17]


> Юрий Зотов ©   (12.03.07 00:05) [13]

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


> Palladin ©   (12.03.07 00:22) [16]

хорошо, не буду гадать)


 
Юрий Зотов ©   (2007-03-12 01:05) [18]

> f2d ©   (12.03.07 00:31) [17]

> я полагал что можно перехватить событие на более низком уровне.

Можно. На уровне WndProc. Но не все, конечно, а только те, что через WndProc вообще проходят. Мышиные - проходят.


 
Нуб   (2007-03-12 15:09) [19]


//***********************************************************
function TCalc.btnName(Sender: TObject) : TButton;       // return name of the button
begin
  result := btnOne;
  if (Sender as TButton) = btnOne then result := btnOne;
  if (Sender as TButton) = btnTwo then result := btnTwo;
  if (Sender as TButton) = btnThree then result := btnThree;
  if (Sender as TButton) = btnFour then result := btnFour;
  if (Sender as TButton) = btnFive then result := btnFive;
  if (Sender as TButton) = btnSix then result := btnSix;
  if (Sender as TButton) = btnSeven then result := btnSeven;
  if (Sender as TButton) = btnEight then result := btnEight;
  if (Sender as TButton) = btnNine then result := btnNine;
  if (Sender as TButton) = btnPlus then result := btnPlus;   // for result on onSummaMinusClick
  if (Sender as TButton) = btnMinus then result := btnMinus;
end;
//***********************************************************


вот так вот можно все сделать у меня есть 10 кнопок при нажатии на которые срабатывает одна функция и в зависимости от нажатой кнопки возвращает нэймбатон и все чудесно
а вот здесь вот ее юзаю , очень удобно сам попробуй


//***********************************************************
procedure TCalc.onbtnClick(Sender : TObject);
var btn : TButton;
begin
  if bolonSummaMinusClick then begin
     Edit1.Text := "";
     bolonSummaMinusClick := false;
  end;
  btn := btnName(Sender);
  if (Sender as TButton) = btnZero  then begin
     if Trim(Edit1.Text) = "0" then
        Edit1.Text := "0"
     else begin
              Edit1.Text := Edit1.Text + "0";
              Label1.Caption := Label1.Caption + "0";
          end;
  end else
  if (Sender as TButton) = btn then  begin
     if Edit1.Text <> "0" then begin
         Edit1.Text := Edit1.Text + btn.Caption;
         Label1.Caption := Label1.Caption + btn.Caption;
     end
     else begin Edit1.Text := btn.Caption;
           Label1.Caption := Label1.Caption + btn.Caption;
     end;
  end;
end;
//***********************************************************


 
Джо ©   (2007-03-12 15:16) [20]

[19] Нуб  
Ужас какой. И зачем такое советовать?


 
Нуб   (2007-03-12 15:22) [21]


> Джо


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


 
Джо ©   (2007-03-12 15:32) [22]

> [21] Нуб   (12.03.07 15:22)
>
> > Джо
>
>
> за то работает чудесно все , конечно код корявый , пусть
> разберается, может поймет чего-то

Какой вообще смысл в методе btnName?


 
f2d ©   (2007-03-12 15:55) [23]


> Нуб   (12.03.07 15:22) [21]

спасибо, но подобное у меня уже реализовано в BtnProc. в зависимости от название нажатой кнопки загружается соответствущий скрипт.

...
PS.Script.LoadFromFile(ExtractFilePath(ParamStr(0))+"\scripts\"+TComponent(Sender).Name+".scr");
...
PS.Execute;
...

это конечно подходит когда нужно реализовать один и тот же метод для многих одинаковых объектов. но... у меня вопрос стоит в том, что для батона1 может быть нужен onClick, а для батона2 он нафиг не нужен. для батона2 нас интересует, например, onMouseMove.


> Юрий Зотов ©   (12.03.07 01:05) [18]

вот вот туда я и глядел. мне как раз мышиные и нужны. только я не представляю как это реализовать.


 
Knight ©   (2007-03-12 16:33) [24]


>  [21] Нуб   (12.03.07 15:22)

Тогда уж лучше Тэги заюзать + кэйс по ним.


 
Юрий Зотов ©   (2007-03-12 17:24) [25]

> Нуб   (12.03.07 15:09) [19]

А если бы было 100 кнопок? Или 100 тыс?

function TCalc.btnName(Sender: TObject) : TButton;  
begin
 if Sender is TButton then
   result := TButton(Sender)
 else
   result := nil
end;

Только смысла нет и в этой функции тоже. Не нужны такие функции.


 
Юрий Зотов ©   (2007-03-12 17:29) [26]

> f2d ©   (12.03.07 15:55) [23]

> мышиные и нужны. только я не представляю как это реализовать.

Что-то типа этого в Application.OnMessage:

if Message.msg in [WM_MOUSEFIRST..WM_MOUSELAST] then
begin
 ... // Здесь анализируем, что за сообщение и какому окну оно послано.
 ... // В зависимости от результата делаем то, что нужно.
end;


 
RASkov   (2007-03-12 17:40) [27]

> у меня вопрос стоит в том, что для батона1 может быть нужен
> onClick, а для батона2 он нафиг не нужен. для батона2 нас
> интересует, например, onMouseMove.

Что-то вообще не понятно, что надо, а что нет....
Не проще ли определенным кнопкам при создании добовлять только нужные им обработчики?
Может я неправильно понял вопрос....


 
Нуб   (2007-03-12 17:54) [28]


> >
> А если бы было 100 кнопок? Или 100 тыс?
>
> function TCalc.btnName(Sender: TObject) : TButton;  
> begin
>  if Sender is TButton then
>    result := TButton(Sender)
>  else
>    result := nil
> end;
>
> Только смысла нет и в этой функции тоже. Не нужны такие
> функции.

> Юрий Зотов

а где меньше строк здесь
                               //

if (Sender as TButton) = btn then  begin
     if Edit1.Text <> "0" then begin
         Edit1.Text := Edit1.Text + btn.Caption;
         Label1.Caption := Label1.Caption + btn.Caption;
     end
     else begin Edit1.Text := btn.Caption;
           Label1.Caption := Label1.Caption + btn.Caption;
     end;
  end;


или


if (Sender as TButton) = btnOne then  begin
     if Edit1.Text <> "0" then begin
         Edit1.Text := Edit1.Text + btnOne.Caption;
         Label1.Caption := Label1.Caption + btnOne.Caption;
     end
     else begin Edit1.Text := btnOne.Caption;
           Label1.Caption := Label1.Caption + btnOne.Caption;
     end;
  end else
  if (Sender as TButton) = btnTwo then  begin
     if Edit1.Text <> "0" then begin
         Edit1.Text := Edit1.Text + btnTwo.Caption;
         Label1.Caption := Label1.Caption + btnTwoCaption;
     end
     else begin Edit1.Text := btnOne.Caption;
           Label1.Caption := Label1.Caption + btnTwo.Caption;
     end;
  end else
  ... и так дальше аж  раз до btnNine в сумме 81 строка



так что Уважаемый Юрий Зотов мне это просто было необходимо сделать , Вы же не знаете для чего я ту функцию юзал и что в дальнейшем с ее помощью я хотел осуществить, я же всего лишь выше привел фрагмент программы, я знаю Ваш опыт и мой это небо и земля, по - этому я учту в дальнейшем, то что вы мне написали


 
f2d ©   (2007-03-12 17:59) [29]


> RASkov   (12.03.07 17:40) [27]



> f2d ©   (11.03.07 23:17) [2]
> проблема в том что кнопки создаются динамически и создавать
> все события которыми может обладать кнопка вручную не совсем
> удобно.


для большей понятности опишу саму задачу:
в файле описаны объекты, которые должны присутствовать на форме. способ описания объектов пока произвольный. потом будет хмл.
пока что у меня в файле записано так

name=Panel class=TPanel top=5 left=5 parent=self
name=Button class=TButton top=5 left=5 parent=panel ev=onClick
name=Button2 class=TButton top=30 left=5 parent=panel ev=onMouseMove
name=Button3 class=TButton top=55 left=5 parent=panel ev=onMouseMove,onClick

при запуске, приложение читает файл и создают объекты которые в нём описаны.
когда мы создаем Button мы должны назначить обработчик только на onClick, когда Button3, то и на onClick и на onMouseMove.

постарался объяснить максимально понятно :)


 
Нуб   (2007-03-12 18:10) [30]

это будет, эсли конечно же будет :),  что-то нереальное :)


 
RASkov   (2007-03-12 18:11) [31]

> [29] f2d ©   (12.03.07 17:59)

Ну так у тебя же они(обработчики) объекта перечисленны в файле, вот и добавляей создаваемому объекты обработчики из списка....
Реализация должна присутствовать в любом случаее...
Т.е. твой хмл и модуль где реализованы обработчики должны быть согласованы. (типа API)...
Или ты хочешь обработчик некоего нового события, не реализованного в модуле программы, описать в своем хмл и чтобы объект на него реогировал?


 
Юрий Зотов ©   (2007-03-12 18:16) [32]

> Нуб   (12.03.07 17:54) [28]

> а где меньше строк здесь... или...

Меньше всего - здесь:

with TButton(Sender) do
 if Edit1.Text <> "0" then  begin
   Edit1.Text := Edit1.Text + Caption;
   Label1.Caption := Label1.Caption + Caption;
 end
 else begin
   Edit1.Text := Caption;
   Label1.Caption := Caption;
 end;

И не нужны никакие бессмысленные функции (тем более, с многогоэтажными if).

И даже не нужно знать "для чего я ту функцию юзал и что в дальнейшем с ее помощью я хотел осуществить".

:o)

Тем более, что в коде [19] есть ошибка: после вызова
btn := btnName(Sender);
проверка
(Sender as TButton) = btn
всегда даст true. Поэтому ветка else в последнем if недостижима, а сам этот if, соответственно, оказывается лишним. Вряд ли это именно то, что Вы хотели получить.


 
Юрий Зотов ©   (2007-03-12 18:28) [33]

> f2d ©   (12.03.07 17:59) [29]

1. А почему не использовать штатную сериализацию?

2. Можно писать в XML и имя обработчика:

name=Button class=TButton top=5 left=5 parent=panel onClick=ButtonClick

name=Button2 class=TButton top=30 left=5 parent=panel onMouseMove=ButtonMouseMove

name=Button3 class=TButton top=55 left=5 parent=panel onMouseMove=ButtonMouseMove, onClick=ButtonClick


 
f2d ©   (2007-03-13 21:55) [34]

если кому-то интересно, то решение пришло в следующем виде:
при открытии, программа считывает из файла список объектов для создания, создаёт их, после чего вызывается скрипт который дописывает необходимые обработчики для объектов. выглядит скрипт так:

procedure onButtonClick(Sender:TObject);
begin
self.caption:="blablbalbalballba";
button.caption:=self.caption;
end;

procedure onPanelClick(Sender:TObject);
begin
panel.caption:="";
end;

procedure onEditChange(Sender:TObject);
begin
self.caption:=edit.text;
end;

begin
panel.parent:=self;
button.parent:=panel;
edit.parent:=panel;
panel.onClick:=@onPanelClick;
button.onClick:=@onButtonClick;
edit.onChange:=@onEditChange;
application.mainform.show;
while not application.terminated do
 application.handlemessage;
end.

списибо всем кто откликнулся, отдельное спабо Palladin"у :)



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

Текущий архив: 2007.04.01;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.039 c
2-1173466376
Riply
2007-03-09 21:52
2007.04.01
FindFirstFile и чтение из файла.


2-1173293266
Ezorcist
2007-03-07 21:47
2007.04.01
вывести текст на image сожержащий jpeg?


3-1168210408
Lamer666
2007-01-08 01:53
2007.04.01
Подскажите можно ли из DBGrid-а узнать какую таблицу он отражает?


2-1173673766
купт
2007-03-12 07:29
2007.04.01
Как свернуть окно программы после запуска


2-1173852902
Alex_C
2007-03-14 09:15
2007.04.01
Общие функции - как лучше