1

In Delphi XE2, I have a Data Module in my Application, and an Action Manager inside that Data Module. I've assigned Keyboard Shortcuts to each action, but when I try to use these shortcuts in the app, it does not catch them.

I'm creating the data module inside the application's initialization (which is moved to a different unit due to IDE distorting code in the project's main file)...

unit AppInit;

interface

uses
  Vcl.Forms,
  Vcl.Themes,
  Vcl.Styles,
  uMain,
  uDataModule
  ;

procedure RunApp;

implementation

procedure RunApp;
begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.Title := 'My App';
  TStyleManager.TrySetStyle('Carbon');
  DM:= TDM.Create(nil);
  try
    Application.CreateForm(TfrmMain, frmMain);
    Application.Run;
  finally
    DM.Free;
  end;
end;

end.

The reason for creating the Data Module like this is so all the various forms of the application are able to use the components within it, specifically the Action Manager. It has to be created before the main form is created.

How can I make the keyboard shortcuts of action items work when the action manager is in a data module?

Jerry Dodge
  • 26,858
  • 31
  • 155
  • 327
  • Have you read [Setting up application wide hot key (keyboard short cut)](http://delphi.about.com/od/adptips2004/a/bltip0904_3.htm)? – LU RD Dec 31 '12 at 09:45
  • No I haven't, but I know about that method, and I'm trying to implement the Action Manager's built-in capabilities. – Jerry Dodge Dec 31 '12 at 09:46
  • The designer won't let me add action lists or action managers to a data module. This is an XY question. You don't actually care about using data modules. Your problem is other than that. – David Heffernan Dec 31 '12 at 10:00
  • @DavidHeffernan Refer to my prior question: http://stackoverflow.com/questions/14097246/delphi-xe2-data-module-expects-only-database-components – Jerry Dodge Dec 31 '12 at 10:12
  • 2
    @Jerry OK, I understand now. I added what I feel to be a better answer to that question! – David Heffernan Dec 31 '12 at 10:19
  • Surely you are going to need to put the actions on a form that is active. – David Heffernan Dec 31 '12 at 10:30
  • @David: I'd hope just the controls? I have always had action lists and actions on data modules. The forms just have the controls hooked up to those actions. I have avoided the action manager as it used to be a quite picky on how you organised things, would have thought that had been addressed by now. – Marjan Venema Dec 31 '12 at 11:19
  • @Marjan My guess is that Jerry doesn't have any controls associated with the actions. But it's a guess. Question looks like an XY. – David Heffernan Dec 31 '12 at 11:25
  • I do have controls using the actions, and the `uses` declaration of the data module's unit is under the `implementation` in each form/unit which needs to reference the actions. Each action is available in any other form in the object inspector. – Jerry Dodge Dec 31 '12 at 11:26
  • @David: like an XY question? You have lost me ... – Marjan Venema Dec 31 '12 at 11:28
  • @MarjanVenema http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – David Heffernan Dec 31 '12 at 12:11
  • 1
    @Jerry You really should try to make the question about your underlying problem. I think that your real problem is that you want have an action manager that is shared between different forms/controls in your app. Ask about that. Data modules may or may not be the solution. You are asking about your solution rather than asking about the problem. – David Heffernan Dec 31 '12 at 12:14
  • @David: Ah, didn't know it by that term... – Marjan Venema Dec 31 '12 at 12:24
  • I also see no reason to create the data module like that – David Heffernan Dec 31 '12 at 15:21
  • Actually there's tons of reason, because it has to be created before the forms which need to use it, including the main form. For example, buttons in the main form are linked to actions in this datamodule. – Jerry Dodge Dec 31 '12 at 15:39
  • @Jerry No, there are not tons of reasons. The statement you make in that comment is easily demonstrated to be false. The data module can be created after the main form. And the main form's actions are still connected up to the data module once the main form is created. It's all done by the magic in Classes.pas. – David Heffernan Dec 31 '12 at 16:18
  • @DavidHeffernan I said "tons of reason" not "reasons". And how else am I supposed to avoid the Access Violation when a button tries to get the text/icon/etc. of its corresponding action item if the action item is not created yet? – Jerry Dodge Dec 31 '12 at 16:49
  • @Jerry As I said it is simple for you to verify that what I am saying is correct. Create a VCL forms app. Create a data module. Add actions to the data module. Connect those actions to controls on the main form. Note that the main form is created first. Note also that the action link references are resolved even though the form is created first. It's easy for you to check this. I did. You can do it too. – David Heffernan Dec 31 '12 at 16:53
  • Note that I am also calling `Show` inside `FormCreate` which forces the form to show before it's finished creating (takes time to load so this makes it visible during creation). I have my reasons, and I'm not asking "is it proper to create a data module within the `DPR` file?" – Jerry Dodge Dec 31 '12 at 16:56
  • Well, I just wanted to make it clear that there's normally no reason to support that part of your question. – David Heffernan Dec 31 '12 at 17:15
  • It might not be the action manager that is the reason the data module must be created before the main form (and destroyed after it). But the easy way to ensure this is in Project>Options>Forms to make sure the data module is first in the list of Auto-create forms. (Remove and then re-add the other forms.) – Ian Goldby Jun 25 '13 at 09:09
  • Jerry, are you comfortable with making this question a duplicate of [this recent question](http://stackoverflow.com/q/27083261/757830)? – NGLN Nov 22 '14 at 22:47

1 Answers1

5

TDataModule is not a descendant of TCustomForm, but rather of TComponent. So a data module does not have a window handle to receive messages, and has no handling for shortcuts like TCustomForm.

function TCustomForm.IsShortCut(var Message: TWMKey): Boolean;

  function DispatchShortCut(const Owner: TComponent) : Boolean;
  .....
  .....
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
bummi
  • 27,123
  • 14
  • 62
  • 101