3

Delpho 2006 を使用しています。シナリオ:

データ モジュールには、ActionList があります。アクションの 1 つにショートカット Ctrl+F4 があり、セカンダリ ショートカット Ctrl+W が必要です。私は次のすべてを試しました:

IDE のアクションの [SecondaryShortcut] リストに Ctrl+W を追加します。

いずれかを使用して DataModuleCreate プロシージャに追加します。

ActFileCloseFile.SecondaryShortCuts.Add('Ctrl+W');

また

ActFileCloseFile.SecondaryShortCuts.AddObject('Ctrl+W',
  TObject(Menus.ShortCut(87, [ssCtrl])));

これらのメソッドを使用するフォームの Create または FormShow プロシージャで両方のメソッドを使用します。

プライマリ ショートカットは常に機能しますが、セカンダリ ショートカットは機能しません。

ActionList をデータ モジュールではなくメイン フォームに配置すると、IDE で Ctrl+W を追加するだけで機能します。私は何を間違っていますか?

4

4 に答える 4

3

これまでに見つかった最もエレガントなソリューションは次のとおりです。

SecondaryShortCutを処理するフォームで、これをOnShortCutイベントに追加します。

procedure TMyForm.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
  Handled := dmDataModule.ActionList1.IsShortCut(Msg);
end;

別:

(これは実際の解決策ではありませんが、回避策です。)

データモジュールのアクションと同じアクションを持つアクションリストをフォームに配置します。実行イベントと更新イベントでは、イベントをデータモジュールアクションに転送するだけです。フォームのメニューはローカルアクションを使用します。

この場合、IDEを使用してSecondaryShortCutsプロパティにCtrl+Wを追加するだけで十分です。

もちろん、データモジュールのアクションが変更されると、すべてのローカルアクションも変更する必要があります。

于 2009-05-12T07:36:11.347 に答える
1

本当の解決策ではありませんが、メインフォーム内からデータモジュールを作成すると機能します:

procedure TMainForm.FormCreate(Sender: TObject);
begin
  FDataModule := TMyDataModule.Create(self);
  TMyButton.Action := FDataModule.TheAction;
end;


procedure TMyDataModule.DataModuleCreate(Sender: TObject);
begin
  TheAction.SecondaryShortCuts.Add('Ctrl+W');
end;

ショートカットは、現在フォーカスのあるフォームによって処理されると思います。したがって、別の形式でそれらを使用している場合、おそらく同じ問題が発生します。

于 2009-05-12T07:21:13.023 に答える
1

簡単な回答: アクションのショートカットは、フォームとデータ モジュール全体で自動的に起動しません。

質問の指示に従うと、主要なショートカットでさえ起動しないことがわかります。これは、重要な手順が説明から除外されているためです。OPが二次的なショートカット発火ではなく一次的なショートカット発火を経験した理由を説明するのに役立つもの。

追加の手順を含める場合:

  • フォームにメニューを追加します。
  • メニュー項目をアクションにリンクします。

次に、プライマリ ショートカットがアクションを起動できるようになります。これは、アクション コンポーネントがその設定をメニュー項目 (ShortCutプロパティを含む) にプッシュするためです。ただし、TMenuItemセカンダリ ショートカットの概念は実装されていません。これが、一方が機能し、他方が機能しない理由です。


多くのフォームとデータモジュールを含むアプリケーションを検討するために一時停止します。アクションのショートカットがそれらすべてで発生する可能性があるかどうかの意味。許可する明示的なコードがなければ、自動的に起動できないことは明らかです。構成されたショートカット キーが他の無関係な作業のコンテキストで押されることがあるからです。

ドキュメントは、アクション リストをデータ モジュールに配置する利点を指摘しています。しかし、データモジュールでショートカットを使用してアクションを正しく使用する方法については、何の説明も提供していないようです。確かに、期待される場所、つまりShortCutおよびSecondaryShortcutsには何も言及されていません。(がっかりするかもしれませんが、まともなドキュメントに対する期待はかなり低くなりました。)

そう...

フォームとデータモジュール全体で動作するショートカットでアクションを取得するにはどうすればよいですか?

私は少し調査を行い、いくつかのオプションを見つけました。いつものように、達成しようとしているものとの相対的なトレードオフを評価してください。

  • (メイン以外の) フォームにアクション リストをドロップすると、すべてのショートカットが期待どおりに機能します。これは最も一般的なシナリオであり、アクションがローカルでフォーム固有の場合に適用されます。

  • アクション リストをメイン フォームにドロップすると、これらすべてのショートカットが他のフォームから起動できるようになります。これは、他のフォームを開くなど、アプリケーション全体のショートカットに最適です。

注:ショートカットが最初にテストされる場所に関しては、優先順位付けの順序があります。そのため、アクティブ フォームにメイン フォームのショートカットと一致するショートカットがある場合、ショートカットはローカルで処理されます。そして、当然のことながら、メインフォームはそれを取得しません。

  • ショートカットを処理するかどうかを確認するためにフォームがテストされると、所有されているすべてのコンポーネントも確認されます。(実際、これが上記の最初の 2 つが機能する理由です。) つまりOwner、データ モジュールの を適切に設定するだけで、そのショートカットを選択したフォームに適用できるようになります。

つまり、代わりに:

Application.CreateForm(TDataModule1, DataModule1);

以下を使用できます。

DataModule1 := TDataModule1.Create(LocalForm);

ただし、データ モジュールの各インスタンスは所有者を 1 人しか持てないため、複数のフォームでショートカットを共有するには、複数のインスタンスを作成する必要があります。これがオプションであるかどうかは、状況によって異なります。ただし、メインフォームをデータモジュールの所有者にすることもできます。これは、上記の2番目のオプションと多少同等です。

  • ほとんどの制御を提供する最後のオプションは、OP 自身の答えです。つまり、「外部ショートカット」をサポートする必要があるフォームは、次のコードで OnShortCut イベントを処理できます。

コード サンプルでわかるように、選択した優先度に従って、さまざまな場所にある複数のアクション リストに委任できます。

procedure TMyForm.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
  Handled := DataModule1.ActionList3.IsShortCut(Msg);
  Handled := Handled or DataModule2.ActionList1.IsShortCut(Msg);
  Handled := Handled or DataModule1.ActionList1.IsShortCut(Msg);
end;
于 2014-08-09T15:55:22.003 に答える
0

アクションがフォームに飲み込まれています...セカンダリフォーム/フレーム/データモジュールでアクションを処理する場合...最初にプライマリからアクションリストを無効にする必要があります...

Form1.ActionList1.State:= asSuspended;

DataModule1.ActionList1.State:= asNormal;

于 2009-05-13T13:36:38.627 に答える