Проблема: В приложении на Delphi открывается немодальная форма из основной формы, на которой находится TMemo. В меню основной формы используется "пробел" как ускоритель. При вводе пробела в TMemo на немодальной форме срабатывает событие ускорителя на основной форме, что нежелательно. Попытка установить MainForm.KeyPreview := false не решает проблему.
Решение: Отключать и включать пункт меню на основной форме при получении и потере фокуса TMemo на немодальной форме. Это можно сделать в событиях TMemo.OnEnter и TMemo.OnExit.
procedure TOtherForm.Memo1Enter(Sender: TObject);
begin
if Application.MainForm is TYourMainForm then
TYourMainForm(Application.MainForm).MenuItemWithSpace.Enabled := False;
end;
procedure TOtherForm.Memo1Exit(Sender: TObject);
begin
if Application.MainForm is TYourMainForm then
TYourMainForm(Application.MainForm).MenuItemWithSpace.Enabled := True;
end;
Примечание: Использование Application.MainForm и приведение типов предотвращает жесткую привязку к имени переменной формы в дочерней форме.
Альтернативное решение: Установить обработчик TMemo.OnShortCut и перехватить ускорение до того, как оно дойдет до основной формы.
procedure TOtherForm.Memo1ShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
Handled := True;
Self.DefaultHandler(Msg);
end;
Примечание: Это решение может не подойти, если в немодальной форме есть свои ускорения.
Другое альтернативное решение: Создать функцию для чтения, сохранения и восстановления всех ускорений в основной форме в методах FormActivate() и FormDeactivate().
var sstore : TStrings;
procedure Tmain_form.FormActivate(Sender: TObject);
begin
if (sstore <> NIL) then tratta_shortcuts_menu(main_menu, {read_shortcuts}FALSE, sstore)
end;
procedure Tmain_form.FormDeactivate(Sender: TObject);
begin
tratta_shortcuts_menu(main_menu, {read_shortcuts}TRUE, sstore)
end;
procedure tratta_shortcuts_menu(menu : TMainMenu;bo_read_shortcuts : boolean;var sstore : TStrings);
begin
// Если BO_READ_SHORTCUTS, то 1) читать ускорения, 2) сохранять их в SSTORE, 3) удалять их из меню.
// В противном случае восстанавливать все ускорения из SSTORE.
end;
procedure sostituisci(im : TMenuItem);
begin
if bo_read_shortcuts then begin
if (im.ShortCut <> 0) then begin
sstore.Add(im.name);
sstore.Add(INDICATORE_SHORTCUT + menus.ShortCutToText(im.ShortCut));
im.ShortCut := 0
end
end
else begin
var i : smallint := sstore.indexof(im.Name);
if (i <> -1) then begin
im.ShortCut := menus.TextToShortCut(copy(sstore[i + 1], length(INDICATORE_SHORTCUT) + 1, MAXINT))
end
end
end;
procedure tratta(im : TMenuItem);
begin
sostituisci(im);
for var i : smallint := 0 to im.Count-1 do tratta(im.Items[i])
end;
begin
if (menu = NIL) then exit;
if bo_read_shortcuts then begin if (sstore = NIL) then sstore := TStringList.Create else sstore.Clear end;
for var i : smallint := 0 to menu.Items.Count-1 do tratta(menu.Items[i]);
if NOT bo_read_shortcuts then begin sstore.Free;sstore := NIL end
end;
Примечание: Это решение может быть сложным, если у вас много пунктов меню или контролов.
В приложении на Delphi, при вводе пробела в TMemo на немодальной форме срабатывает событие ускорителя на основной форме, что нежелательно. Необходимо найти решение, чтобы предотвратить это поведение.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS