action event outside delphi app [duplicate]
Possible Duplicate:
How can I handle a keyboard shortcut when my program isn't active?
hello guys i need to make a delphi program that creates a short cut key that works outside the delphi app. for example: when i press ctrl+1 it pastes a certain text. When i press ctrl+2, another text, and so on. It really helps my work. I managed to make a delphi application that does that, but it only works inside that app. i want it to work in all windows applications as long as my app is open ( and minimized). Can anyone help me out? I'm pretty new at delphi, i'm trying to learn.
I tried this code which someone recommended to me but it doesn't work. it does nothing. what did i do wrong?
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.
You need to use RegisterHotKey and UnregisterHotKey from the Win32 API, they are very straightforward to use.
Also, you may find useful ShortCutToKey(), which returns the key code and shift state of a Delphi shortcut.
PS: Don't forget to check the return value of RegisterHotKey(), since it will fail if the hotkey is already registered by other application.
Edit: sorry, I though that you were using another WM_MESSAGE, since first you posted the code as plain text and I only scanned through it...
I think that the problem with your code is that your are using GlobalAddAtom for the ID key, but you only need to use an unique ID inside your app (the docs for the function say that you need to use GlobalAddAtom only for a shared DLL). Try using just this:
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;
Also, the MOD_CONTROL and related constants are already defined by Delphi, you don't need to redefine them.
andrei, check this sample code to paste a text in a external application using a hotkey.
the code show two options
1) sending the Ctrl+V combination to the focused window
2) sending a WM_PASTE
message
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;
精彩评论