unit HotKey2_San;interface uses windows,sysutils,messages,classes,forms; type TKeyEvent_San=procedure (Sender: TObject; var Key: Word; Shift: TShiftState) of object; THotKey2Rec=class private protected public Enabled:boolean; Sync:boolean; Shift:TShiftState; Key:Word; MethodProc:TNotifyevent; constructor Create(AShift:TshiftState;AKey:Word;AMethodProc:TNotifyEvent;ASync:boolean); end;/////////////// THotKey2_san=class private OldProc:TKeyEvent_san; protected List:TList; procedure DeleteAll; function FindItem(AShift:TShiftState;AKey:Word):THotKey2Rec; ////////////// // procedure OnFormKeyPress(Sender:TObject;var Key:char); procedure OnFormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); public procedure EnableHotKey(AShift:TShiftState;AKey:Word); procedure DisableHotKey(AShift:TShiftState;AKey:Word); procedure DeleteHotKey(AShift:TshiftState;AKey:Word); function AddHotKey(AShift:TshiftState;AKey:Word;AMethodProc:TNotifyEvent;ASync:boolean=true;AEnabled:boolean=true):THotKey2Rec; ////////// constructor Create(AForm:TForm); Destructor Destroy;override; end;implementation{ THotKey2_san }function THotKey2_san.AddHotKey(AShift: TshiftState; AKey: Word;AMethodProc:TNotifyEvent;ASync:boolean;AEnabled:boolean):THotKey2Rec; var t:thotkey2rec; begin t:=thotkey2rec.Create(ashift,akey,amethodproc,async); t.enabled:=aenabled; list.Add(t); result:=t; end;constructor THotKey2_san.Create(AForm:TForm); begin inherited create; aform.KeyPreview:=true; oldproc:=aform.OnKeyDown; aform.OnKeyDown:=OnFormKeyDown; //aform.OnKeyPress:=self.OnFormKeyPress; /////// list:=tlist.Create; end;procedure THotKey2_san.DeleteAll; var t:thotkey2rec; begin while list.Count>0 do begin t:=thotkey2rec(list.Items[0]); try list.Delete(list.IndexOf(t)); finally t.Free; t:=nil; end; end; end;procedure THotKey2_san.DeleteHotKey(AShift: TshiftState; AKey: Word); var t:thotkey2rec; begin t:=finditem(ashift,akey); if t=nil then exit; try list.Delete(list.IndexOf(t)); finally t.Free; t:=nil; end; end;destructor THotKey2_san.Destroy; begin try deleteall; list.Free; finally inherited; end; end;procedure THotKey2_san.DisableHotKey(AShift: TShiftState; AKey: Word); var t:thotkey2rec; begin t:=finditem(ashift,akey); if t<>nil then t.enabled:=false; end;procedure THotKey2_san.EnableHotKey(AShift: TShiftState; AKey: Word); var t:thotkey2rec; begin t:=finditem(ashift,akey); if t<>nil then t.enabled:=true; end;function THotKey2_san.FindItem(AShift: TShiftState; AKey: Word): THotKey2Rec; var i:integer; t:thotkey2rec; begin result:=nil; for i:=0 to list.Count-1 do begin t:=thotkey2rec(list.Items[i]); if (t.Shift=ashift) and(t.Key=akey) then begin result:=t; break; end; end; end;procedure THotKey2_san.OnFormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var t:thotkey2rec; setted:boolean; begin setted:=false; t:=finditem(shift,key); try if (t<>nil)and(t.enabled) then begin if t.Sync then begin t.enabled:=false; setted:=true; end; t.MethodProc(t); if setted then begin t.enabled:=true; end; end; finally if assigned(oldproc) then oldproc(sender,key,shift); //inherited; end; end;{ THotKey2Rec }constructor THotKey2Rec.Create(AShift: TshiftState; AKey: Word; AMethodProc: TNotifyEvent;ASync:boolean); begin enabled:=true; /////////// sync:=async; shift:=ashift; key:=akey; methodproc:=amethodproc; end;end.
//我还有个全局热键的类: unit HotKey_San;interface uses windows,sysutils,classes,messages,controls;type //TOnHotKeyEvent =procedure of object; THotKeyRec=class public GStr:string; ID:integer; //////////// Succeed:boolean; Enabled:boolean; //////////// Modifiers:Cardinal; Key:Cardinal; //////////// Sync:boolean; Handled:boolean; //////////// ExtData:pointer; ExtFigure:real; //////////// OnHotKey:TNotifyEvent; //////////// constructor Create(AModifiers,AKey:Cardinal;AHandleProc:TNotifyEvent); end; //////////////////////////////////////////////////////////////// THotKey_San=class(TWinControl) private protected List:TList; ///////////////// function UnRegisterAHotKey(HKRec:THotKeyRec):boolean; function RegisterAHotKey(HKRec:THotKeyRec;AEnable:boolean=true):boolean; function FindItem(AModifiers,AKey:Cardinal):THotKeyRec; ///////////////// procedure OnGetHotKey(var msg:tmessage);message wm_hotkey; public /////////////// procedure SetEnabled(AEnabled:boolean); function GetHotKeyCount:integer; procedure DeleteAll; function GetHotKeyHandleProc(AModifiers,AKey:Cardinal):TNotifyEvent; function AddHotKey(AModifiers,AKey:Cardinal;AHandleProc:TNotifyEvent;AEnable:boolean=true):THotKeyRec; procedure DeleteHotKey(AModifiers,AKey:Cardinal); procedure EnableHotKey(AModifiers,AKey:Cardinal); procedure DisableHotKey(AModifiers,AKey:Cardinal); ////////// constructor Create(AWinControl: TWinControl); destructor Destroy;override;end;implementation{ THotKey_San }
function THotKey_San.AddHotKey(AModifiers, AKey: Cardinal;AHandleProc:TNotifyEvent;AEnable:boolean=true): THotKeyRec; var t:thotkeyrec; begin t:=thotkeyrec.Create(amodifiers,akey,Ahandleproc); if not registerahotkey(t) then begin t.Free; t:=nil; end else list.Add(t); ///////////// result:=t; end;constructor THotKey_San.Create(AWinControl:TWinControl); begin inherited create(awincontrol); self.Parent:=awincontrol; self.Visible:=false; list:=tlist.Create; end; procedure THotKey_San.DeleteAll; var t:thotkeyrec; begin while list.Count>0 do begin t:=thotkeyrec(list.Items[0]); unregisterahotkey(t); t.Free; list.Delete(0); end; end;procedure THotKey_San.DeleteHotKey(AModifiers, AKey: Cardinal); var t:thotkeyrec; begin t:=finditem(amodifiers,akey); if t<>nil then begin unregisterahotkey(t); list.Delete(list.IndexOf(t)); t.Free; t:=nil; end; end;destructor THotKey_San.Destroy; var t:thotkeyrec; i:integer; begin for i:=0 to list.Count-1 do begin t:=thotkeyrec(list.Items[i]); unregisterahotkey(t); t.Free; end; list.Free; inherited; end;procedure THotKey_San.DisableHotKey(AModifiers,AKey:Cardinal); var t:thotkeyrec; begin t:=finditem(amodifiers,akey); if t<>nil then t.Enabled:=false; end;procedure THotKey_San.EnableHotKey(AModifiers,AKey:Cardinal); var t:thotkeyrec; begin t:=finditem(amodifiers,akey); if t<>nil then t.Enabled:=true; end;function THotKey_San.FindItem(AModifiers, AKey: Cardinal): THotKeyRec; var i:integer; t:thotkeyrec; begin result:=nil; for i:=0 to list.Count-1 do begin t:=thotkeyrec(list.Items[i]); if (t.Modifiers=amodifiers) and(t.Key=akey) then begin result:=t; exit; end; end; end;function THotKey_San.GetHotKeyCount: integer; begin result:=list.Count; end;function THotKey_San.GetHotKeyHandleProc(AModifiers, AKey: Cardinal): TNotifyEvent; var t:thotkeyrec; begin result:=nil; t:=finditem(amodifiers,akey) ; if t<>nil then result:=t.onhotkey; end;procedure THotKey_San.OnGetHotKey(var msg:tmessage); var t:thotkeyrec; setted:boolean; begin //setted:=false; if not self.Enabled then exit;
t:=finditem(msg.LParamLo,msg.LParamHi); // if t=nil then beep; if (t<>nil)and(t.Succeed)and(t.Enabled) then begin setted:=t.Sync; if setted then t.Enabled:=false; t.onhotkey(t); if t.Handled then msg.Result:=1; if setted then t.Enabled:=true; end; end;function THotKey_San.RegisterAHotKey(HKRec:THotKeyRec;AEnable:boolean=true): boolean; var i:cardinal; begin result:=false; ////////// i:=list.Count; hkrec.gstr:=classname+':'+hkrec.ClassName+'_'+inttostr(i); while GlobalFindAtom(pchar(hkrec.gstr))<>0 do begin hkrec.gstr:=ClassName+':'+hkrec.ClassName+'_'+inttostr(i); inc(i); end; ////////// hkrec.id:=GlobalAddAtom(pchar(hkrec.gstr)); result:=registerhotkey(handle,hkrec.id,hkrec.modifiers,hkrec.key); hkrec.succeed:=result; hkrec.Enabled:=aenable; end;procedure THotKey_San.SetEnabled(AEnabled: boolean); begin enabled:=aenabled; end;function THotKey_San.UnRegisterAHotKey(HKRec:THotKeyRec): boolean; begin result:=UnRegisterHotKey(handle,hkrec.id) and (GlobalDeleteAtom(hkrec.id)=0); end;{ THotKeyRec }constructor THotKeyRec.Create(AModifiers,AKey:Cardinal;AHandleProc:TNotifyEvent); begin self.ID:=0; self.Enabled:=false; self.Succeed:=false; self.GStr:=''; self.Modifiers:=amodifiers; self.Key:=akey; self.onhotkey:=ahandleproc; //////////// handled:=false; extdata:=nil; extfigure:=0; /////////// self.Sync:=true; end;end.
Windows系统都会给你的应用程序发送一个消息WM_HOTKEY,不管你的应用程序是否为当前活动的。其中WM_HOTKEY消息的格式为: idHotKey = (int) wParam; // 该参数在设置系统级的敏感键有用,一般不予使用 fuModifiers = (UINT) LOWORD(lParam); //敏感键的辅助按键 uVirtKey = (UINT) HIWORD(lParam); //敏感键的键值 ---- 因为Windows系统只是把一个WM_HotKey的消息发送给应用程序,要完成具体的事情需要一个消息处理程序,也就是上面Private段里的procedure WMhotkeyhandle(var msg:Tmessage); message wm_hotkey; 过程, 它的代码如下(这里只是简单地把窗口最前面显示) procedure TForm1.Wmhotkeyhandle (var msg:Tmessage); begin if (msg.LParamHi=$41) and (msg.lparamLo=MOD_CONTROL or mod_Alt) then begin msg.Result:=1; //该消息已经处理 Close; //把窗口最前面显示 end; end; 三、敏感键的释放 ---- 在应用程序退出来之前应当把你所设置的敏感键释放掉,以释放其所占有的系统资源,这里需要调用两个Windows API函数UNREGISTERHOTKEY,它的调用格式如下: BOOL UNREGISTERHOTKEY( HWND HWND, //与敏感键关联的窗口句柄 INT ID //敏感键的标示符 ); 也就是说只要在FormClose事件中加入如下代码 … unregisterhotkey(handle,hotkeyid); DeleteAtom(HotKeyID);
uses
windows,sysutils,messages,classes,forms;
type
TKeyEvent_San=procedure (Sender: TObject; var Key: Word; Shift: TShiftState) of object;
THotKey2Rec=class
private
protected public
Enabled:boolean;
Sync:boolean;
Shift:TShiftState;
Key:Word;
MethodProc:TNotifyevent;
constructor Create(AShift:TshiftState;AKey:Word;AMethodProc:TNotifyEvent;ASync:boolean); end;///////////////
THotKey2_san=class
private
OldProc:TKeyEvent_san;
protected
List:TList;
procedure DeleteAll;
function FindItem(AShift:TShiftState;AKey:Word):THotKey2Rec;
//////////////
// procedure OnFormKeyPress(Sender:TObject;var Key:char);
procedure OnFormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
public
procedure EnableHotKey(AShift:TShiftState;AKey:Word);
procedure DisableHotKey(AShift:TShiftState;AKey:Word);
procedure DeleteHotKey(AShift:TshiftState;AKey:Word);
function AddHotKey(AShift:TshiftState;AKey:Word;AMethodProc:TNotifyEvent;ASync:boolean=true;AEnabled:boolean=true):THotKey2Rec;
//////////
constructor Create(AForm:TForm);
Destructor Destroy;override;
end;implementation{ THotKey2_san }function THotKey2_san.AddHotKey(AShift: TshiftState; AKey: Word;AMethodProc:TNotifyEvent;ASync:boolean;AEnabled:boolean):THotKey2Rec;
var
t:thotkey2rec;
begin
t:=thotkey2rec.Create(ashift,akey,amethodproc,async);
t.enabled:=aenabled;
list.Add(t);
result:=t;
end;constructor THotKey2_san.Create(AForm:TForm);
begin
inherited create;
aform.KeyPreview:=true;
oldproc:=aform.OnKeyDown;
aform.OnKeyDown:=OnFormKeyDown;
//aform.OnKeyPress:=self.OnFormKeyPress;
///////
list:=tlist.Create;
end;procedure THotKey2_san.DeleteAll;
var
t:thotkey2rec;
begin
while list.Count>0 do
begin
t:=thotkey2rec(list.Items[0]);
try
list.Delete(list.IndexOf(t));
finally
t.Free;
t:=nil;
end;
end;
end;procedure THotKey2_san.DeleteHotKey(AShift: TshiftState; AKey: Word);
var
t:thotkey2rec;
begin
t:=finditem(ashift,akey);
if t=nil then exit;
try
list.Delete(list.IndexOf(t));
finally
t.Free;
t:=nil;
end;
end;destructor THotKey2_san.Destroy;
begin
try
deleteall;
list.Free;
finally
inherited;
end;
end;procedure THotKey2_san.DisableHotKey(AShift: TShiftState; AKey: Word);
var
t:thotkey2rec;
begin
t:=finditem(ashift,akey);
if t<>nil then
t.enabled:=false;
end;procedure THotKey2_san.EnableHotKey(AShift: TShiftState; AKey: Word);
var
t:thotkey2rec;
begin
t:=finditem(ashift,akey);
if t<>nil then
t.enabled:=true;
end;function THotKey2_san.FindItem(AShift: TShiftState;
AKey: Word): THotKey2Rec;
var
i:integer;
t:thotkey2rec;
begin
result:=nil;
for i:=0 to list.Count-1 do
begin
t:=thotkey2rec(list.Items[i]);
if (t.Shift=ashift) and(t.Key=akey) then
begin
result:=t;
break;
end;
end;
end;procedure THotKey2_san.OnFormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
t:thotkey2rec;
setted:boolean;
begin
setted:=false;
t:=finditem(shift,key);
try
if (t<>nil)and(t.enabled) then
begin
if t.Sync then
begin
t.enabled:=false;
setted:=true;
end;
t.MethodProc(t);
if setted then
begin
t.enabled:=true;
end;
end;
finally if assigned(oldproc) then
oldproc(sender,key,shift);
//inherited;
end;
end;{ THotKey2Rec }constructor THotKey2Rec.Create(AShift: TshiftState; AKey: Word;
AMethodProc: TNotifyEvent;ASync:boolean);
begin
enabled:=true;
///////////
sync:=async;
shift:=ashift;
key:=akey;
methodproc:=amethodproc;
end;end.
FormCreate的时候建立这个实例。
然后add热键以及modifiers还有就是消息处理函数就可以了很方便对了消息处理函数的sender参数就是Thotkey2rec类型的。formclose的时候free掉就行了,很简单。
unit HotKey_San;interface
uses
windows,sysutils,classes,messages,controls;type
//TOnHotKeyEvent =procedure of object;
THotKeyRec=class
public
GStr:string;
ID:integer;
////////////
Succeed:boolean;
Enabled:boolean;
////////////
Modifiers:Cardinal;
Key:Cardinal;
////////////
Sync:boolean;
Handled:boolean;
////////////
ExtData:pointer;
ExtFigure:real;
////////////
OnHotKey:TNotifyEvent;
////////////
constructor Create(AModifiers,AKey:Cardinal;AHandleProc:TNotifyEvent);
end;
////////////////////////////////////////////////////////////////
THotKey_San=class(TWinControl)
private
protected List:TList;
///////////////// function UnRegisterAHotKey(HKRec:THotKeyRec):boolean;
function RegisterAHotKey(HKRec:THotKeyRec;AEnable:boolean=true):boolean;
function FindItem(AModifiers,AKey:Cardinal):THotKeyRec;
/////////////////
procedure OnGetHotKey(var msg:tmessage);message wm_hotkey;
public ///////////////
procedure SetEnabled(AEnabled:boolean);
function GetHotKeyCount:integer;
procedure DeleteAll;
function GetHotKeyHandleProc(AModifiers,AKey:Cardinal):TNotifyEvent;
function AddHotKey(AModifiers,AKey:Cardinal;AHandleProc:TNotifyEvent;AEnable:boolean=true):THotKeyRec;
procedure DeleteHotKey(AModifiers,AKey:Cardinal);
procedure EnableHotKey(AModifiers,AKey:Cardinal);
procedure DisableHotKey(AModifiers,AKey:Cardinal);
//////////
constructor Create(AWinControl: TWinControl);
destructor Destroy;override;end;implementation{ THotKey_San }
function THotKey_San.AddHotKey(AModifiers, AKey: Cardinal;AHandleProc:TNotifyEvent;AEnable:boolean=true): THotKeyRec;
var
t:thotkeyrec;
begin
t:=thotkeyrec.Create(amodifiers,akey,Ahandleproc);
if not registerahotkey(t) then
begin
t.Free;
t:=nil;
end
else
list.Add(t);
/////////////
result:=t;
end;constructor THotKey_San.Create(AWinControl:TWinControl);
begin
inherited create(awincontrol);
self.Parent:=awincontrol;
self.Visible:=false;
list:=tlist.Create;
end;
procedure THotKey_San.DeleteAll;
var
t:thotkeyrec;
begin
while list.Count>0 do
begin
t:=thotkeyrec(list.Items[0]);
unregisterahotkey(t);
t.Free;
list.Delete(0);
end;
end;procedure THotKey_San.DeleteHotKey(AModifiers, AKey: Cardinal);
var
t:thotkeyrec;
begin
t:=finditem(amodifiers,akey);
if t<>nil then
begin
unregisterahotkey(t);
list.Delete(list.IndexOf(t));
t.Free;
t:=nil;
end;
end;destructor THotKey_San.Destroy;
var
t:thotkeyrec;
i:integer;
begin
for i:=0 to list.Count-1 do
begin
t:=thotkeyrec(list.Items[i]);
unregisterahotkey(t);
t.Free;
end;
list.Free;
inherited;
end;procedure THotKey_San.DisableHotKey(AModifiers,AKey:Cardinal);
var
t:thotkeyrec;
begin
t:=finditem(amodifiers,akey);
if t<>nil then
t.Enabled:=false;
end;procedure THotKey_San.EnableHotKey(AModifiers,AKey:Cardinal);
var
t:thotkeyrec;
begin
t:=finditem(amodifiers,akey);
if t<>nil then
t.Enabled:=true;
end;function THotKey_San.FindItem(AModifiers, AKey: Cardinal): THotKeyRec;
var
i:integer;
t:thotkeyrec;
begin
result:=nil;
for i:=0 to list.Count-1 do
begin
t:=thotkeyrec(list.Items[i]);
if (t.Modifiers=amodifiers) and(t.Key=akey) then
begin
result:=t;
exit;
end;
end;
end;function THotKey_San.GetHotKeyCount: integer;
begin
result:=list.Count;
end;function THotKey_San.GetHotKeyHandleProc(AModifiers, AKey: Cardinal): TNotifyEvent;
var
t:thotkeyrec;
begin
result:=nil;
t:=finditem(amodifiers,akey) ;
if t<>nil then
result:=t.onhotkey;
end;procedure THotKey_San.OnGetHotKey(var msg:tmessage);
var
t:thotkeyrec;
setted:boolean;
begin
//setted:=false;
if not self.Enabled then exit;
t:=finditem(msg.LParamLo,msg.LParamHi);
// if t=nil then beep;
if (t<>nil)and(t.Succeed)and(t.Enabled) then
begin
setted:=t.Sync;
if setted then t.Enabled:=false;
t.onhotkey(t);
if t.Handled then msg.Result:=1;
if setted then t.Enabled:=true; end; end;function THotKey_San.RegisterAHotKey(HKRec:THotKeyRec;AEnable:boolean=true): boolean;
var
i:cardinal;
begin
result:=false;
////////// i:=list.Count; hkrec.gstr:=classname+':'+hkrec.ClassName+'_'+inttostr(i);
while GlobalFindAtom(pchar(hkrec.gstr))<>0 do
begin
hkrec.gstr:=ClassName+':'+hkrec.ClassName+'_'+inttostr(i);
inc(i);
end;
//////////
hkrec.id:=GlobalAddAtom(pchar(hkrec.gstr));
result:=registerhotkey(handle,hkrec.id,hkrec.modifiers,hkrec.key);
hkrec.succeed:=result;
hkrec.Enabled:=aenable;
end;procedure THotKey_San.SetEnabled(AEnabled: boolean);
begin
enabled:=aenabled;
end;function THotKey_San.UnRegisterAHotKey(HKRec:THotKeyRec): boolean;
begin
result:=UnRegisterHotKey(handle,hkrec.id) and (GlobalDeleteAtom(hkrec.id)=0);
end;{ THotKeyRec }constructor THotKeyRec.Create(AModifiers,AKey:Cardinal;AHandleProc:TNotifyEvent);
begin
self.ID:=0;
self.Enabled:=false;
self.Succeed:=false;
self.GStr:='';
self.Modifiers:=amodifiers;
self.Key:=akey;
self.onhotkey:=ahandleproc;
////////////
handled:=false;
extdata:=nil;
extfigure:=0;
///////////
self.Sync:=true;
end;end.
// 该参数在设置系统级的敏感键有用,一般不予使用
fuModifiers = (UINT) LOWORD(lParam);
//敏感键的辅助按键
uVirtKey = (UINT) HIWORD(lParam);
//敏感键的键值
---- 因为Windows系统只是把一个WM_HotKey的消息发送给应用程序,要完成具体的事情需要一个消息处理程序,也就是上面Private段里的procedure WMhotkeyhandle(var msg:Tmessage); message wm_hotkey; 过程, 它的代码如下(这里只是简单地把窗口最前面显示) procedure TForm1.Wmhotkeyhandle
(var msg:Tmessage);
begin
if (msg.LParamHi=$41) and
(msg.lparamLo=MOD_CONTROL or mod_Alt) then
begin
msg.Result:=1; //该消息已经处理
Close;
//把窗口最前面显示
end;
end;
三、敏感键的释放 ---- 在应用程序退出来之前应当把你所设置的敏感键释放掉,以释放其所占有的系统资源,这里需要调用两个Windows API函数UNREGISTERHOTKEY,它的调用格式如下: BOOL UNREGISTERHOTKEY(
HWND HWND, //与敏感键关联的窗口句柄
INT ID //敏感键的标示符
);
也就是说只要在FormClose事件中加入如下代码
…
unregisterhotkey(handle,hotkeyid);
DeleteAtom(HotKeyID);