简体   繁体   English

为什么快捷方式在我的 Delphi 程序中不起作用?

[英]Why the shortcut doesn't work in my Delphi program?

I've written a program in Delphi 10.4.我用 Delphi 10.4 编写了一个程序。 The main part of the UI is just a TMemo. UI 的主要部分只是一个 TMemo。 When the user types something in it, the app will automatically copy the text in the TMemo to clipboard.当用户在其中输入内容时,应用程序会自动将 TMemo 中的文本复制到剪贴板。 It looks like this:它看起来像这样:

在此处输入图片说明

This auto copy part works well.这个自动复制部分运行良好。 However, I also want to let the user change dark theme or light theme by a shortcut.但是,我也想让用户通过快捷方式更改深色主题或浅色主题。 I enabled a dark theme and a light theme.我启用了深色主题和浅色主题。

在此处输入图片说明

The code looks like this:代码如下所示:

unit Unit1;

interface

uses
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
    System.Classes, Vcl.Graphics,
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Clipbrd, System.Actions,
    Vcl.ActnList, Vcl.Themes;

type
    TForm1 = class(TForm)
        txt: TMemo;
        ActionList1: TActionList;
        act_change_theme: TAction;
        procedure txtChange(Sender: TObject);
        procedure act_change_themeExecute(Sender: TObject);
        procedure FormCreate(Sender: TObject);
    private
        { Private declarations }
    public
        { Public declarations }
    end;

var
    Form1: TForm1;

var
    is_dark: Boolean;

implementation

{$R *.dfm}

function ShortCut(Key: Word; Shift: TShiftState): TShortCut;
begin
    Result := 0;
    if HiByte(Key) <> 0 then
        Exit; // if Key is national character then it can't be used as shortcut
    Result := Key;
    if ssShift in Shift then
        Inc(Result, scShift); // this is identical to "+" scShift
    if ssCtrl in Shift then
        Inc(Result, scCtrl);
    if ssAlt in Shift then
        Inc(Result, scAlt);
end;

procedure TForm1.act_change_themeExecute(Sender: TObject);
begin
    if is_dark then
    begin
        TStyleManager.TrySetStyle('Windows', false);
        is_dark := false;
    end
    else
    begin
        TStyleManager.TrySetStyle('Carbon', false);
        is_dark := true;
    end;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    is_dark := false;
    act_change_theme.ShortCut := ShortCut(Word('d'), [ssCtrl]);
end;

procedure TForm1.txtChange(Sender: TObject);
begin
    try
        Clipboard.AsText := txt.Lines.GetText;
    except
        on E: Exception do
    end;

end;

end.

However, when I press ctrl+d , nothing happened.但是,当我按ctrl+d 时,什么也没发生。 I tried to debug it and I found that ctrl+d never triggers the action's shortcut.我尝试调试它,发现ctrl+d永远不会触发操作的快捷方式。 Why this happened?为什么会这样? How to fix it?如何解决? I've used the shortcut function in the past and it worked.我过去使用过快捷功能并且它有效。

Try Word('D') , or the constant vkD , instead of Word('d') .尝试Word('D')或常量vkD ,而不是Word('d') Shortcuts use virtual key codes, and letters are represented as virtual keys using their capital values.快捷方式使用虚拟键代码,字母使用它们的大写值表示为虚拟键。 Typing an Uppercase or Lowercase letter into an edit control uses the same virtual key, it is the current shift state that determines the case of the letter when they key is translated into a text character.将大写或小写字母输入到编辑控件中使用相同的虚拟键,当前的移位状态决定了将键转换为文本字符时字母的大小写。

Also note that the VCL has its own ShortCut() function (and also TextToShortCut() ) for creating TShortCut values, so you don't need to write your own function.另请注意,VCL 有自己的ShortCut()函数(还有TextToShortCut() )用于创建TShortCut值,因此您无需编写自己的函数。

See Representing Keys and Shortcuts , especially Representing Shortcuts as Instances of TShortCut .请参阅表示键和快捷方式,尤其是将快捷方式表示为 TShortCut 的实例

Also, your TAction is clearly placed on the Form at design-time, so you should simply assign its ShortCut using the Object Inspector, rather than in code.此外,您的TAction在设计时明确放置在 Form 上,因此您应该使用 Object Inspector 简单地分配它的ShortCut ,而不是在代码中。 Then these details would be handled for you automatically by the framework.然后框架会自动为您处理这些细节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM