plumothy 0 Posted November 9, 2022 In the Object Inspector, if you double-click the OnHint event of a TAction then you get a procedure like this: procedure TForm1.Action1Hint(var HintStr: string; var CanShow: Boolean); There is no Sender parameter (like most other events have) so how can I tell which TAction made the call if several TActions share this event? Share this post Link to post
Remy Lebeau 1436 Posted November 9, 2022 (edited) On 11/9/2022 at 12:49 AM, plumothy said: how can I tell which TAction made the call if several TActions share this event? Unfortunately, you can't, at least not from the event itself, anyway. You will have to instead use a different event handler for each action, making them call a common method if they need to share code, eg: procedure TForm1.Action1Hint(var HintStr: string; var CanShow: Boolean); begin DoActionHint(Action1, HintStr, CanShow); end; procedure TForm1.Action2Hint(var HintStr: string; var CanShow: Boolean); begin DoActionHint(Action2, HintStr, CanShow); end; procedure TForm1.DoActionHint(Sender: TObject; var HintStr: string; var CanShow: Boolean); begin ... end; . Edited November 10, 2022 by Remy Lebeau 1 Share this post Link to post
plumothy 0 Posted November 10, 2022 Thanks Remy - I suspected as much. I wonder why they did it that way? Just about every other event I have ever used has a Sender parameter. I actually want to use OnHint for my Dataset Actions so I can customise the Hints depending on which dataset the Action is working on. Then the Hint can be more meaningful - eg "Delete order item" rather than a generic "Delete record". Your suggestion will work of course, but I might investigate creating my own descendant Dataset Action. Share this post Link to post
Remy Lebeau 1436 Posted November 10, 2022 There is another possibility. If you don't mind assigning the OnHint events in code at runtime (or at least looping through the actions at runtime to update their OnHint handlers that are assigned at design-time), then you can use the TMethod record to alter the event handler's Self pointer to point at each TAction object instead of the TForm object. Then you can just type-cast the Self pointer inside the handler. For example: procedure TForm1.FormCreate(Sender: TObject); var Evt: THintEvent; begin ... Evt := Action1.OnHint; // or: Evt := @ActionHint; TMethod(Evt).Data := Action1; // instead of Form1 Action1.OnHint := Evt; ... // repeat for all TAction objects that share ActionHint()... end; procedure TForm1.ActionHint(var HintStr: string; var CanShow: Boolean); begin // use TAction(Self) as needed... end; 1 Share this post Link to post
plumothy 0 Posted November 10, 2022 Remy - thank you. That looks interesting - I will try it. Share this post Link to post
Anders Melander 1815 Posted November 11, 2022 21 hours ago, plumothy said: That looks interesting When, in a few years, you or someone else comes across that code, "interesting" will not be the word used to describe it. 1 Share this post Link to post
plumothy 0 Posted November 11, 2022 Anders, I don't understand. Please explain what you mean by that. Share this post Link to post
Anders Melander 1815 Posted November 12, 2022 It's a hack. Go for the pragmatic solution instead; It's easier to maintain. For something as simple as this it's simply not worth it to use an obscure hack that requires a 20 line comment explaining to your future self what the hell is going on and why it was necessary. Share this post Link to post
plumothy 0 Posted November 12, 2022 Anders, Thanks for clarifying. Yes you’re right, it’s a hack - but that is exactly what makes it interesting to me. (Although I think a single line of comments would be enough to explain it - “hack to get at sending Action in OnHint event”.) I really enjoy discovering how things work and what is “under the hood” (whether it’s how to build a Delphi application or how to build a house). I now have 3 possible answers to my original question and I will try them all (not just the hack) and then decide which to deploy in my project. Share this post Link to post