Вопрос

Я использую Delpho 2006.Сценарий:

В модуле данных у меня есть список действий.Одно из действий имеет сочетание клавиш Ctrl + F4, и я хочу иметь дополнительное сочетание клавиш Ctrl + W.Я перепробовал все следующие действия:

Добавляем Ctrl + W в список actions SecondaryShortcut в IDE.

Добавляем его в процедуру DataModuleCreate, используя либо

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

или

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

Используя оба этих метода в процедуре Create или FormShow формы, в которой он будет использоваться.

Основной ярлык всегда работает, но не вторичный.

Когда я помещаю список действий в основную форму вместо модуля данных, он работает, просто добавив Ctrl + W в IDE.Что я делаю не так?

Это было полезно?

Решение

Самое элегантное решение, найденное на данный момент, заключается в следующем:

В форме, которую вы хотите обработать SecondaryShortCut, добавьте это в событие OnShortCut:

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

Альтернатива:

(Это не реальное решение, а обходной путь.)

Поместите список действий в форму, действие которой идентично действию в модуле данных.В своих событиях выполнения и обновления он только пересылает события в действие модуля данных.Меню в форме используют локальное действие.

В этом случае достаточно добавить Ctrl + W к свойству SecondaryShortCuts с помощью IDE.

Очевидно, что когда изменяется действие над модулем данных, я также должен изменить все локальные действия.

Другие советы

Это не реальное решение, но если вы создадите datamodule из основной формы, это сработает:

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;

Я думаю, что ярлыки обрабатываются формой, которая имеет текущий фокус.Так что вы, вероятно, столкнетесь с теми же проблемами, если будете использовать их в другой форме.

Краткий Ответ:Действия, сокращающие путь, не автоматически запускайте по формам и модулям данных.

Если вы будете следовать инструкциям, приведенным в вопросе, вы обнаружите, что даже первичный короткий путь не срабатывает.Это связано с тем, что в инструкциях был упущен ключевой шаг.Тот, который послужит объяснением того, почему ОП испытал первичный короткий выстрел, а не вторичный.

Если вы включите дополнительные шаги:

  • Добавьте меню в форму.
  • И привяжите пункт меню к действию.

Тогда основной короткий путь сможет запустить действие.Это происходит потому, что компонент Action переносит свои настройки в пункт меню (включая ShortCut собственность).Однако, TMenuItem не реализует концепцию вторичных сокращений.Вот почему одно работает, а другое нет.


Сделайте паузу, чтобы рассмотреть приложение со множеством форм и модулей данных;и последствия того, что короткие пути действий могут затронуть все из них.Должно быть совершенно очевидно, что они не должны быть способны автоматически запускайте без явного кода, разрешающего это.Вы бы не хотели, чтобы фоновая форма выполняла кучу действий, потому что ее настроенные короткие клавиши случайно нажимаются в контексте другой несвязанной работы.

Тот Самый Документация указывает на преимущество размещения списков действий в модулях данных.Но, похоже, не дает никаких объяснений, как использовать actions с короткими стрижками в модуле обработки данных правильно.Конечно, ничего не упоминается в ожидаемых местах, а именно: Короткий путь и Второстепенные короткие нарезки.(Я был бы разочарован, но мои ожидания относительно достойной документации оказались довольно низкими.)

Итак...

Что следует что нужно сделать, чтобы получить действия с сокращениями, работающие с формами и модулями данных?

Я провел небольшое расследование и нашел несколько вариантов.Как всегда, оцените компромисс относительно того, чего вы пытаетесь достичь.

  • Когда вы помещаете список действий в (неосновную) форму, все короткие пути работают так, как ожидалось.Это наиболее распространенный сценарий, который применяется, когда действия являются локальными и зависят от конкретной формы.

  • Когда вы добавляете список действий в основную форму, все эти короткие пути смогут выполняться из любой другой формы.Это отлично подходит для укороченных операций широкого применения, таких как вскрытие других форм.

ПРИМЕЧАНИЕ: Существует последовательность расстановки приоритетов относительно того, где в первую очередь тестируется короткий путь.Таким образом, если в активной форме есть сокращенный вариант, соответствующий сокращенному варианту в основной форме, этот сокращенный вариант будет обработан локально.И основная форма, по понятным причинам, этого не получит.

  • Когда форма тестируется, чтобы увидеть, справляется ли она с сокращением, все принадлежащие компоненты также проверяются.(На самом деле, именно поэтому работают первые два приведенных выше варианта.) Это означает, что простая установка Owner соответствующая настройка вашего модуля данных позволит применить его сокращенные варианты к выбранной вами форме.

То есть.Вместо того, чтобы:

Application.CreateForm(TDataModule1, DataModule1);

Вы можете использовать следующее:

DataModule1 := TDataModule1.Create(LocalForm);

Однако, поскольку каждый экземпляр модуля данных может иметь только одного владельца:вам пришлось бы создать несколько экземпляров, чтобы позволить нескольким формам совместно использовать сокращенные варианты.Возможен ли такой вариант, зависит от ваших обстоятельств.Однако вы также могли бы сделать основную форму владельцем вашего модуля данных, что было бы в некоторой степени эквивалентно второму варианту выше.

  • Последний вариант, который обеспечивает наибольший контроль, - это собственный ответ 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;

Действие поглощается формой ... Если вы хотите, чтобы вторичная форма / фрейм / datamodule обрабатывала действие...Сначала вы должны отключить список действий из основного...

Form1.ActionList1.State:= Утверждено;

DataModule1.ActionList1.Состояние: = Как нормальное;

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top