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

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.042 c
11-1152300569
Maloric
2006-07-07 23:29
2007.04.01
Label - WordWrap с вертикальным выравниванием


4-1163174628
SkySpeed
2006-11-10 19:03
2007.04.01
Как можно отлавливать запускаемые процессы?


2-1173684582
smaller
2007-03-12 10:29
2007.04.01
Как определить длинну строки в пикселах ?


15-1173177660
Novice
2007-03-06 13:41
2007.04.01
Что в имени тебе моем? (Опрос железа)


15-1173109716
muhh
2007-03-05 18:48
2007.04.01
Работа с реестром





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский