德尔福应用程序外的动作事件

时间:2010-11-07 14:29:56

标签: delphi

  

可能重复:
  How can I handle a keyboard shortcut when my program isn't active?

你好 我需要创建一个delphi程序,创建一个在delphi应用程序之外工作的快捷键。例如:当我按ctrl + 1时,它会粘贴某个文本。当我按ctrl + 2,另一个文本,依此类推。这真的有助于我的工作。我设法制作一个delphi应用程序来做到这一点,但它只适用于该应用程序。只要我的应用程序打开(并最小化),我希望它在所有Windows应用程序中工作。谁能帮我吗?我在德尔福很新,我正在努力学习。

我尝试过这个代码,有人向我推荐但它不起作用。它什么都不做。我做错了什么?

unit Unit3;  

interface  

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

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');  
     Clipboard.AsText := 'This is my own text!';  

  end  
  else   
  if Msg.HotKey = HotKey2 then  
  begin  
    ShowMessage('Ctrl + 2 was pressed');  
     Clipboard.AsText := 'This is my own text!';  

  end;  
end;  

end.     

2 个答案:

答案 0 :(得分:2)

您需要使用Win32 API中的RegisterHotKeyUnregisterHotKey,它们非常简单易用。

此外,您可能会发现有用的ShortCutToKey(),它返回Delphi快捷键的键控代码和移位状态。

PS:不要忘记检查RegisterHotKey()的返回值,因为如果热键已经被其他应用程序注册,它将失败。

编辑:抱歉,我认为您使用的是另一个WM_MESSAGE,因为首先您将代码发布为纯文本,我只是通过它进行扫描...

我认为您的代码存在的问题是您使用GlobalAddAtom作为ID密钥,但您只需在应用内使用唯一ID(该函数的文档说您需要使用GlobalAddAtom 仅适用于共享DLL )。尝试使用这个:

const
  ID_HOTKEY1=0;
  ID_HOTKEY2=1;

procedure TYourForm.FormCreate(Sender: TObject);
begin
  if not RegisterHotKey(Handle,ID_HOTKEY1,MOD_CONTROL,Ord('1'))
    then Application.MessageBox('Error registering hot key 1','Error',MB_ICONERROR);
  if not RegisterHotKey(Handle,ID_HOTKEY2,MOD_CONTROL,Ord('2'))
    then Application.MessageBox('Error registering hot key 2','Error',MB_ICONERROR);
end;

procedure TYourForm.FormDestroy(Sender: TObject);
begin
  UnregisterHotKey(Handle,ID_HOTKEY1);
  UnregisterHotKey(Handle,ID_HOTKEY2);
end;

procedure TYourForm.WMHotKey(var Msg: TWMHotKey);
begin
  Application.MessageBox(PChar(IntToStr(Msg.HotKey)),'Hotkey ID',MB_OK);
end;

此外,MOD_CONTROL及相关常量已由Delphi定义,您无需重新定义它们。

答案 1 :(得分:1)

andrei,检查此示例代码,使用热键将文本粘贴到外部应用程序中。

代码显示两个选项

1)将 Ctrl + V 组合发送到焦点窗口

2)发送WM_PASTE消息

function GetFocusedHandle: THandle;
var
   ActiveHWND      : THandle;
   FocusedThread   : DWORD;
begin
  Result:=0;
  ActiveHWND    := GetForegroundWindow;
  FocusedThread := GetWindowThreadProcessID(ActiveHWND, nil) ;
  try
    if AttachThreadInput(GetCurrentThreadID, FocusedThread, true) then
      Result := GetFocus;
  finally
    AttachThreadInput(GetCurrentThreadID, FocusedThread, false) ;
  end;
end;

procedure TForm17.WMHotKey(var Msg: TWMHotKey);
var
  FocusWindowHwnd : THandle;
begin
  if Msg.HotKey = HotKey1 then //option 1
  begin
    Clipboard.AsText := 'Text from Ctrl + 1 Hotkey';//Assign the text to the clipboard
    //send the Ctrl + V combination to the current focused window
    keybd_event(VK_CONTROL, 0, 0, 0);
    keybd_event(Ord('V'), 0, 0, 0);
  end
  else
  if Msg.HotKey = HotKey2 then //option 2 
  begin
    FocusWindowHwnd:=GetFocusedHandle; //get the handle to the focused window
    if FocusWindowHwnd<>0 then
    begin
      Clipboard.AsText := 'Text from Ctrl + 2 Hotkey';//Assign the text to the clipboard
      SendMessage(FocusWindowHwnd,WM_PASTE,0,0);//send the WM_PASTE message 
    end;
  end;
end;