Форум: "Начинающим";
Текущий архив: 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