如何防止主窗体在另一个非模态窗体上的 TMemo 中捕获击键?

发布于 2024-08-29 19:44:30 字数 216 浏览 10 评论 0原文

我有一个可以从主窗体打开非模式窗体的应用程序。非模态形式上有一个 TMemo。主窗体菜单使用“空格”作为其加速器字符之一。

当非模态表单打开并且备忘录具有焦点时,每次我尝试在非模态表单上的备忘录中输入空格时,“空格”快捷方式的主表单事件都会触发!

我尝试过将 MainForm.KeyPreview := false 打开,而另一个表单已打开但没有骰子。

有什么想法吗?

I have an app that opens a non-modal form from the main form. The non-modal form has a TMemo on it. The main form menu uses "space" as one of its accelerator characters.

When the non-modal form is open and the memo has focus, every time I try to enter a space into the memo on the non-modal form, the main form event for the "space" shortcut fires!

I have tried turning MainForm.KeyPreview := false while the other form is open but no dice.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦纸 2024-09-05 19:44:30

当备忘录具有焦点时禁用主窗体上的菜单项,并在备忘录失去焦点时重新启用它。您可以通过 TMemo.OnEnterTMemo.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 和类型转换是为了防止在子表单中对表单变量名称进行硬编码。

Disable the menu item on the main form while the memo has focus, and re-enable it when the memo loses it. You can do this from the TMemo.OnEnter and TMemo.OnExit events.

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;

The use of Application.MainForm and the typecast are to prevent hard-coding in a form variable name in the child form.

菊凝晚露 2024-09-05 19:44:30

这可能是一个老话题,但我刚才遇到了同样的问题并寻找合适的解决方案。您的主题提出了,但没有提供我想要使用的解决方案。

我的问题是:我有一个带有很多快捷键(退格键、删除键等)的主窗体和带有编辑框的第二个窗体。编辑框没有任何关键操作,这些操作由主窗体快捷方式处理。

我的解决方案:将子窗体设置为 OnShortCut,它将在主窗体解释它们之前捕获快捷方式:

procedure ChildForm.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
  Handled := True;
  Self.DefaultHandler(Msg);
end;

这对我来说很有效,子窗体捕获快捷方式并将它们作为常用关键消息处理。编辑框可以按预期使用。

This may be an old topic, but i had the same issue a moment ago and searched for a suitable solution. Your topic came up but not with a solution i would want to use.

My problem was: I have a main form with a lot of shortcuts (Backspace, Delete, etc) and a second form with an edit box. The edit box didn't get any key actions, which are handled by the main form shortcuts.

My solution: Set the child forms OnShortCut, wich will catch the shortcuts before they get interpreted by the main form with:

procedure ChildForm.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
  Handled := True;
  Self.DefaultHandler(Msg);
end;

That did the trick for me, the child form catches the shortcuts and handles them as common key messages. The edit box can be used as intended.

ぺ禁宫浮华殁 2024-09-05 19:44:30

如果您有许多菜单项或许多控件,则可能很难解决每个菜单项或控件的问题。
相反,您可以在主窗口的 F​​ormActivate() 和 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);
{ if BO_READ_SHORTCUTS then 1) read shortcuts 2) save them on SSTORE (Shortcuts STORE) 3) delete them from menu;
ELSE restore all shortcuts from SSTORE  }

procedure sostituisci(im : TMenuItem);
const INDICATORE_SHORTCUT = '~ ';
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;

If you have many menu items, or many controls, could be very difficult to threat the problem for each of them.
Instead, you could use a function in FormActivate() and FormDeActivate() methods of main window in order to clean and restore all shortcuts in a easy and simple way:

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);
{ if BO_READ_SHORTCUTS then 1) read shortcuts 2) save them on SSTORE (Shortcuts STORE) 3) delete them from menu;
ELSE restore all shortcuts from SSTORE  }

procedure sostituisci(im : TMenuItem);
const INDICATORE_SHORTCUT = '~ ';
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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文