How can I handle a keyboard shortcut when my progr

2019-02-14 15:15发布

Is it ok if i use it like this..for multiple events?

unit Unit4;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Clipbrd;

type
  TForm4 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure WMHotkey(var Message: TWMHotKey); message WM_HOTKEY;
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form4: TForm4;

implementation

const
  MY_ID = 123;
  MY_ID1 = 123;
  MY_ID2 = 123;

{$R *.dfm}

procedure TForm4.FormCreate(Sender: TObject);
begin
  RegisterHotKey(Handle, MY_ID, MOD_CONTROL, ord('1'));
   RegisterHotKey(Handle, MY_ID1, MOD_CONTROL, ord('2'));
    RegisterHotKey(Handle, MY_ID2, MOD_CONTROL, ord('3'));
end;

procedure TForm4.FormDestroy(Sender: TObject);
begin
  UnregisterHotKey(Handle, MY_ID);
  UnregisterHotKey(Handle, MY_ID1);
  UnregisterHotKey(Handle, MY_ID2);
end;

procedure TForm4.WMHotkey(var Message: TWMHotKey);
begin
  if Message.HotKey = MY_ID then
  begin

    if not AttachThreadInput(GetCurrentThreadId, GetWindowThreadProcessId(GetForegroundWindow), true) then
      RaiseLastOSError;

    try
      Clipboard.AsText := 'text1';
      SendMessage(GetFocus, WM_PASTE, 0, 0);
    finally
      AttachThreadInput(GetCurrentThreadId, GetWindowThreadProcessId(GetForegroundWindow), false);
    end;

    if Message.HotKey = MY_ID1 then
  begin

    if not AttachThreadInput(GetCurrentThreadId, GetWindowThreadProcessId(GetForegroundWindow), true) then
      RaiseLastOSError;

    try
      Clipboard.AsText := 'text2';
      SendMessage(GetFocus, WM_PASTE, 0, 0);
    finally
      AttachThreadInput(GetCurrentThreadId, GetWindowThreadProcessId(GetForegroundWindow), false);
    end;

  if Message.HotKey = MY_ID2 then
  begin

    if not AttachThreadInput(GetCurrentThreadId, GetWindowThreadProcessId(GetForegroundWindow), true) then
      RaiseLastOSError;

    try
      Clipboard.AsText := 'text3';
      SendMessage(GetFocus, WM_PASTE, 0, 0);
    finally
      AttachThreadInput(GetCurrentThreadId, GetWindowThreadProcessId(GetForegroundWindow), false);
    end;

  end;
end;

end;
end;
end.

3条回答
你好瞎i
2楼-- · 2019-02-14 15:59

to complement the Andreas answer you can use the RegisterHotKey function in combination with the WM_HOTKEY windows message.

try this code

type
  TForm17 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    HotKey1 : Integer;
    HotKey2 : Integer;
    procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;
  public
    { Public declarations }
  end;

var
  Form17: TForm17;

implementation

{$R *.dfm}

{ TForm17 }

procedure TForm17.FormCreate(Sender: TObject);
const
  MOD_CONTROL = $0002;//0x0002
begin
  // Register Ctrl + 1 hotkey
  HotKey1 := GlobalAddAtom('Hotkey1');
  RegisterHotKey(Handle, HotKey1, MOD_CONTROL, Ord('1'));
  // Register  Ctrl + 2 hotkey
  HotKey2 := GlobalAddAtom('Hotkey2');
  RegisterHotKey(Handle, HotKey2, MOD_CONTROL, Ord('2'));
end;

procedure TForm17.FormDestroy(Sender: TObject);
begin
  //unregister the hotkeys
  UnRegisterHotKey(Handle, HotKey1);
  GlobalDeleteAtom(HotKey1);
  UnRegisterHotKey(Handle, HotKey2);
  GlobalDeleteAtom(HotKey2);
end;

procedure TForm17.WMHotKey(var Msg: TWMHotKey); 
begin
  if Msg.HotKey = HotKey1 then
  begin
    ShowMessage('Ctrl + 1 was pressed');
    //do your stuff
  end
  else
  if Msg.HotKey = HotKey2 then
  begin
    ShowMessage('Ctrl + 2 was pressed');
    //do your stuff
  end;
end;
查看更多
可以哭但决不认输i
3楼-- · 2019-02-14 16:00

As others suggested, it's RegisterHotKey function. However, proper implementation of the application that you want to design requires keyboard hook and DLL injection into the application.

I would recommend that you take a look at TypePilot application. It lets you type or copy/paste any text with certain shortcuts that you type. Eg. you can type "thnk " and this will be replaced with "thank you" by the application.

查看更多
Juvenile、少年°
4楼-- · 2019-02-14 16:14

Use the RegisterHotKey function. If you want the application to be invisible, you might want all the details in my answer to a similar question.

Try this:

unit Unit4;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Clipbrd;

type
  TForm4 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure WMHotkey(var Message: TWMHotKey); message WM_HOTKEY;
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form4: TForm4;

implementation

const
  MY_ID = 123;

{$R *.dfm}

procedure TForm4.FormCreate(Sender: TObject);
begin
  RegisterHotKey(Handle, MY_ID, MOD_CONTROL, ord('1'));
end;

procedure TForm4.FormDestroy(Sender: TObject);
begin
  UnregisterHotKey(Handle, MY_ID);
end;

procedure TForm4.WMHotkey(var Message: TWMHotKey);
begin
  if Message.HotKey = MY_ID then
  begin

    if not AttachThreadInput(GetCurrentThreadId, GetWindowThreadProcessId(GetForegroundWindow), true) then
      RaiseLastOSError;

    try
      Clipboard.AsText := 'This is my own text!';
      SendMessage(GetFocus, WM_PASTE, 0, 0);
    finally
      AttachThreadInput(GetCurrentThreadId, GetWindowThreadProcessId(GetForegroundWindow), false);
    end;

  end;
end;

end.

Of course, you will need to use this approach and modify it so it suits your particular case. (That is, you probably want something more than an application that prints "This is my own text!" on Ctrl+1, but nothing else.)

查看更多
登录 后发表回答