This was exactly the problem! I wanted to do what you suggest: Use one method from several buttons called. After having put those buttons into a frame, they did not "know their names any more". They said the name of the frame instead of their own.
That is because you redesigned your UI but did not pay attention to your new hierarchy or to what the new
Self actually points at. You are not asking for the name of the button at all. You are asking for the name of the Frame instead.
Self is a hidden pointer inside of a class method. It points at an instance of the class which owns that method.
SpeedButton_TagesberichtErstellenClick() is a method of the
TFrame_BerichteF class, and therefore its
Self pointer always points at an instance of
TFrame_BerichteF. It does not matter what kind of object event
SpeedButton_TagesberichtErstellenClick() is assigned to. Its
Self will always point at the owning
TFrame_BerichteF object.
That's why events have a
Sender parameter, to point at the object which is triggering the event.
This flexibility is what allows multiple object events to be assigned a shared event handler, eg:
SpeedButton1.OnClick := SpeedButton_TagesberichtErstellenClick;
SpeedButton2.OnClick := SpeedButton_TagesberichtErstellenClick;
...
Or for multiple objects to assign their own handler to a shared event, eg:
if SomeCondition then
SpeedButton1.OnClick := Frame1.SpeedButton_TagesberichtErstellenClick
else if SomeOtherCondition then
SpeedButton1.OnClick := Frame2.SpeedButton_TagesberichtErstellenClick
else ...
After fuzzing around, they "knew more": they said, they were "SpeedButtons", - but not which one!
Sender is a pointer. It points at the object which triggered the event. You can use that pointer to access members of that object, eg:
procedure TFrame_BerichteF.SpeedButton_TagesberichtErstellenClick(Sender: TObject);
begin
ShowMessage(TSpeedButton(Sender).Name);
end;
Or even to just compare it to object pointers directly, eg:
procedure TFrame_BerichteF.SpeedButton_TagesberichtErstellenClick(Sender: TObject);
begin
if Sender = SpeedButton1 then
...
else if Sender = SpeedButton2 then
...
end;
All the ideas suggested in this thread I have tried before, because they sound logic. They did not work.
Yes, they do work. You are just not applying them correctly to your situation.
Why can't I see in the watch-list the sender's value?
Because the
Sender is itself just a raw
TObject pointer, so all you can see from it is a memory address and no properties. To see anything more meaningful, you have to type-cast it to the correct derived type in order to access its properties.
I always program through actions when writing a user interface and that does not work: Sender is TAction, not TSpeedButton.
Then cast the
Sender to
TAction and use its
ActionComponent property to know which component triggered the action.