Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Events vergleichen


Martok - Do 30.08.07 19:38
Titel: Events vergleichen
Hallo!

Ich habe folgendes Problem: Es gibt mehrere MenuItems, und ich möchte nur mit denen etwas machen die ein bestimmtes OnClick-Ereignis haben.
Erster Versuch:

Delphi-Quelltext
1:
if mi.Parent.Items[i].OnClick = MenuSelectHL then                    

Geht logischerweise nicht,
Zitat:
Nicht genügend wirkliche Parameter
.

Dann habe ich mit verschiedenen @ und Klammern probiert, aber irgendwie will das nicht.

Wie macht man das richtig? Und sagt nicht, 'nimm den Tag', den brauch ich noch für was anderes.

mfg,
Martok

PS: Ich bin mir ziemlich sicher, dass das die falsche Sparte ist, aber in die anderen passts auch nicht viel mehr. Und in Sonstiges wollte ichs nicht setzen... :roll:


Martok - Fr 31.08.07 15:46

Ich weiß, es sind noch keine 24h rum... aber trotzdem schieb ich mal.

*schieb*

Das Problem stört mich nämlich doch irgendwie...


Martok - Sa 01.09.07 19:11

*schieb weiter*

Hm... weiß etwa keiner wieso mich Delphi nicht testen lassen will ob ein Methodenzeiger auf eine Methode zeigt?


jakobwenzel - Sa 01.09.07 21:10

So könnte es vllt klappen:


Delphi-Quelltext
1:
2:
3:
4:
5:
var
  foo:TNotifyEvent;
begin
  foo:=MenuSelectHL;
  if mi.Parent.Items[i].OnClick = foo then


Martok - Sa 01.09.07 21:16

Ne, immer noch nicht. Er meint jetzt bei der linken Seite 'Nicht genug wirkl. Parameter'.

Also auf der OnClick-Seite... *idee* Schade...


Delphi-Quelltext
1:
2:
    foo2:= mi.Parent.Items[i].OnClick;
    if (foo2 = foo) then

bringt auch nix... er beschwert sich immer im if... Wird doch wohl kein Compiler-Bug sein...


jaenicke - Sa 01.09.07 22:02

Nun ja, du willst ja nicht die Funktionen miteinander vergleichen sondern deren Adressen. ;-) :idea:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure TForm71.Button1Click(Sender: TObject);
begin
  ShowMessage('aa');
end;

procedure TForm71.Button2Click(Sender: TObject);
begin
  ShowMessage('bb');
end;

procedure TForm71.Button3Click(Sender: TObject);
begin
  if @Button1.OnClick <> @Button2.OnClick then
  begin
    Button2.OnClick := Button1.OnClick;
    ShowMessage('ungleich');
  end
  else
    ShowMessage('gleich');
end;

Zwei Testknöpfe und einer, der, wenn das zweite OnClick noch nicht gleich dem ersten ist, es auf dieses setzt...


Martok - So 02.09.07 00:34

Warum kannst du das so aufrufen und ich nicht?

Naja. Mit kombinierten Variablen und @-Operator gehts jetzt. Auch wenn ich Delphis ursprüngliches Problem nicht verstehe... Was ist an

Delphi-Quelltext
1:
 if @Button1.OnClick <> @Button2.OnClick then                    

anders als

Delphi-Quelltext
1:
if @mi.Parent.Items[i].OnClick = @MenuSelectHL then                    

:?:


dummzeuch - So 02.09.07 14:22

Hi,

user profile iconMartok hat folgendes geschrieben:
Was ist an

Delphi-Quelltext
1:
 if @Button1.OnClick <> @Button2.OnClick then                    

anders als

Delphi-Quelltext
1:
if @mi.Parent.Items[i].OnClick = @MenuSelectHL then                    

:?:

Koennte ein Scope-Problem sein: Woher soll der Compiler wissen, auf welchen Ausdruck sich das @ bezieht?

In einem solchen Fall helfen eigentlich immer Klammern:

Delphi-Quelltext
1:
if @(mi.Parent.Items[i].OnClick) = @MenuSelectHL then                    


twm


Martok - So 02.09.07 14:27

Das ging auch nicht. War gleich das erste was ich probiert hatte. Deswegen wundere ich mich ja so ;)


dummzeuch - So 02.09.07 15:55

Hi,

user profile iconMartok hat folgendes geschrieben:
Das ging auch nicht. War gleich das erste was ich probiert hatte. Deswegen wundere ich mich ja so ;)


Hm, ich haette geschworen es geht.

Definitiv funktionieren tut dies:


Delphi-Quelltext
1:
2:
if (TMethod(mi.Parent.Items[i].OnClick).Code = TForm1.MenuSelectHL) and
(TMethod(mi.Parent.Items[i].OnClick).Data = self) then


Wenn Du sicher bist, dass Du immer nur eine Instanz der Klasse TForm1 hast, kannst Du auch die zweite Ueberpruefung weglassen. Aber Vorsicht, damit bin ich schonmal heftig auf die Nase geflogen. Borland hatte naemlich Code in der VCL, die auch nur .code ueberprueft hatte (ich glaube das war in TAction.SetOnExecute) und ich hatte dieselbe Methode einer anderen Instanz der gleichen Klasse zugewiesen. Und ich wunderte mich dann, dass immernoch die alte Methode aufgerufen wurde.

twm

edit: zweiter Check sollte natuerlich auf .data gehen


Martok - So 02.09.07 16:33

Interessant... auf TMethod gecastet hatte ich auch mal... wusste dann aber nicht was ich damit machen soll. Naja, ist ja jetzt auch wurscht ;)