shenhotkeys.pas
来自「向程序发送热键的单元源程序」· PAS 代码 · 共 732 行 · 第 1/2 页
PAS
732 行
{-----------------------------------------------------------------------------
Unit Name: ShenHotKeys
Author: slq (沈龙强)
E-Mail: Chinbo@eyou.com
Homepage: http://shenloqi.delphibbs.com
http://www.shen.h58.net
Purpose: 系统级的热键控件,可以运行于Win98,Win2000,WinXP。
直接支持TShortcut。
还有一部分键值没有包括进去。
安排热键超过10个的时候将会出现小问题,但是可以手工调整,暂时不修正。
History:
-----------------------------------------------------------------------------}
unit ShenHotKeys;
interface
uses
Classes, Windows, {$IFDEF VER140}designintf, vcleditors,
designeditors{$ELSE}DsgnIntf{$ENDIF}, Messages, Forms, ComCtrls;
type
//辅助键类别
TShenShiftState = set of (ssShift, ssAlt, ssCtrl);
//前置声明
TShenHotKeys = class;
//热键项目
TShenHotKeyItem = class(TCollectionItem)
private
FHotKeyId: Integer;
FOnHotKey: TNotifyEvent;
FName: string;
FHotKey: Integer;
FShiftState: TShenShiftState;
procedure SetShiftState(State: TShenShiftState);
function GetHotKey: string;
procedure SetHotKey(Key: string);
function GetManager: TShenHotKeys;
protected
function GetDisplayName: string; override;
procedure RegisterHotKey;
procedure UnRegisterHotKey;
property HotKeyId: Integer read FHotKeyId;
property Manager: TShenHotKeys read GetManager;
public
function GetNamePath: string; override;
function ShortcuttoHotkeys(Shortcut: tshortcut): Boolean;
procedure Assign(Item: TPersistent); override;
published
property Name: string read FName write FName;
property ShiftState: TShenShiftState read FShiftState write SetShiftState;
property HotKey: string read GetHotKey write SetHotKey;
property OnHotKeyActivation: TNotifyEvent read FOnHotKey write FOnHotKey;
end;
//聚集类
THotKeyCollection = class(TCollection)
private
FOwner: TShenHotKeys;
function GetItem(Idx: Integer): TShenHotKeyItem;
procedure SetItem(Idx: Integer; Item: TShenHotKeyItem);
protected
function GetOwner: TPersistent; override;
public
constructor Create(Manager: TShenHotKeys);
property Items[Idx: Integer]: TShenHotKeyItem read GetItem write SetItem;
default;
end;
//
TShenHotKeys = class(TComponent)
private
FHotKeys: THotKeyCollection;
procedure SetHotKeys(HotKeys: THotKeyCollection);
function WMHotKey(var Msg: TMessage): Boolean;
protected
procedure Loaded; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function HotKeyByName(const Name: string): TShenHotKeyItem;
published
property HotKeys: THotKeyCollection read FHotKeys write SetHotKeys;
end;
procedure Register;
implementation
uses SysUtils, TypInfo;
const
//这次采用了与ShenCpls不同的方法
KeyCodes: array[0..77] of Integer =
(0, Ord('A'), Ord('B'), Ord('C'), Ord('D'), Ord('E'), Ord('F'), Ord('G'),
Ord('H'), Ord('I'), Ord('J'), Ord('K'), Ord('L'), Ord('M'), Ord('N'),
Ord('O'), Ord('P'), Ord('Q'), Ord('R'), Ord('S'), Ord('T'), Ord('U'),
Ord('V'), Ord('W'), Ord('X'), Ord('Y'), Ord('Z'), Ord('1'), Ord('2'),
Ord('3'), Ord('4'), Ord('5'), Ord('6'), Ord('7'), Ord('8'), Ord('9'),
Ord('0'), VK_F1, VK_F2, VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9,
VK_F10, VK_F11, VK_F12, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_ESCAPE, VK_TAB,
VK_INSERT, VK_DELETE, VK_HOME, VK_END, VK_PRIOR, VK_NEXT, VK_NumPad0,
VK_NumPad1, VK_NumPad2, VK_NumPad3, VK_NumPad4, VK_NumPad5, VK_NumPad6,
VK_NumPad7, VK_NumPad8, VK_NumPad9, VK_ADD, VK_SUBTRACT, VK_MULTIPLY,
VK_DIVIDE, VK_DECIMAL, VK_NUMLOCK, VK_SCROLL);
KeyLabels: array[0..77] of string =
('', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5',
'6', '7', '8', '9', '0', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9',
'F10', 'F11', 'F12', 'Up', 'Down', 'Left', 'Right', 'Echap', 'Tab', 'Insert',
'Delete', 'Home', 'End', 'Page up', 'Page down', 'NumPad 0', 'NumPad 1',
'NumPad 2', 'NumPad 3', 'NumPad 4', 'NumPad 5', 'NumPad 6', 'NumPad 7',
'NumPad 8', 'NumPad 9', 'NumPad +', 'NumPad -', 'NumPad *', 'NumPad /',
'NumPad .', 'NumLock', 'ScrollLock');
{-----------------------------------------------------------------------------
Procedure: TShenHotKeys.Create
Author: slq
Date: 08-三月-2002
Arguments: AOwner: TComponent
Result: None
Purpose: 构造函数,判断是否处于设计期
-----------------------------------------------------------------------------}
constructor TShenHotKeys.Create(AOwner: TComponent);
begin
FHotKeys := THotKeyCollection.Create(Self);
inherited Create(AOwner);
if not (csDesigning in ComponentState) then
Application.HookMainWindow(WMHotKey);
end;
{-----------------------------------------------------------------------------
Procedure: TShenHotKeys.Destroy
Author: slq
Date: 08-三月-2002
Arguments: None
Result: None
Purpose: 析构函数
-----------------------------------------------------------------------------}
destructor TShenHotKeys.Destroy;
var i: Integer;
begin
if not (csDesigning in ComponentState) then
Application.UnHookMainWindow(WMHotKey);
for i := 0 to HotKeys.Count - 1 do
HotKeys[i].UnRegisterHotKey;
FHotKeys.Free; FHotKeys := nil;
inherited Destroy;
end;
{-----------------------------------------------------------------------------
Procedure: TShenHotKeys.WMHotKey
Author: slq
Date: 08-三月-2002
Arguments: var Msg: TMessage
Result: Boolean
Purpose: 激活热键触发事件
-----------------------------------------------------------------------------}
function TShenHotKeys.WMHotKey(var Msg: TMessage): Boolean;
var i: Integer;
begin
if Msg.Msg = WM_HOTKEY then
begin
for i := 0 to HotKeys.Count - 1 do
if Msg.wParam = HotKeys[i].HotKeyId then
begin
Result := True;
if Assigned(HotKeys[i].OnHotKeyActivation) then
HotKeys[i].OnHotKeyActivation(HotKeys[i]);
Exit;
end;
end;
Result := False;
end;
{-----------------------------------------------------------------------------
Procedure: TShenHotKeys.Loaded
Author: slq
Date: 08-三月-2002
Arguments: None
Result: None
Purpose: 重载Tcomponent的Loaded函数。
-----------------------------------------------------------------------------}
procedure TShenHotKeys.Loaded;
var i: Integer;
begin
inherited Loaded;
if not (csDesigning in ComponentState) then
for i := 0 to HotKeys.Count - 1 do
HotKeys[i].RegisterHotKey;
end;
{-----------------------------------------------------------------------------
Procedure: TShenHotKeys.HotKeyByName
Author: slq
Date: 08-三月-2002
Arguments: const Name: string
Result: TShenHotKeyItem
Purpose: 解析
-----------------------------------------------------------------------------}
function TShenHotKeys.HotKeyByName(const Name: string): TShenHotKeyItem;
var i: Integer;
begin
for i := 0 to HotKeys.Count - 1 do
if CompareText(Name, HotKeys[i].Name) = 0 then
begin
Result := HotKeys[i];
Exit;
end;
Result := nil;
end;
{-----------------------------------------------------------------------------
Procedure: TShenHotKeys.SetHotKeys
Author: slq
Date: 08-三月-2002
Arguments: HotKeys: THotKeyCollection
Result: None
Purpose: assign
-----------------------------------------------------------------------------}
procedure TShenHotKeys.SetHotKeys(HotKeys: THotKeyCollection);
begin
FHotKeys.Assign(HotKeys);
end;
{ THotKeyCollection }
{-----------------------------------------------------------------------------
Procedure: THotKeyCollection.Create
Author: slq
Date: 08-三月-2002
Arguments: Manager: TShenHotKeys
Result: None
Purpose: 构造函数
-----------------------------------------------------------------------------}
constructor THotKeyCollection.Create(Manager: TShenHotKeys);
begin
FOwner := Manager;
inherited Create(TShenHotKeyItem);
end;
{-----------------------------------------------------------------------------
Procedure: THotKeyCollection.GetItem
Author: slq
Date: 08-三月-2002
Arguments: Idx: Integer
Result: TShenHotKeyItem
Purpose:
-----------------------------------------------------------------------------}
function THotKeyCollection.GetItem(Idx: Integer): TShenHotKeyItem;
begin
Result := TShenHotKeyItem(inherited Items[Idx]);
end;
{-----------------------------------------------------------------------------
Procedure: THotKeyCollection.GetOwner
Author: slq
Date: 08-三月-2002
Arguments: None
Result: TPersistent
Purpose:
-----------------------------------------------------------------------------}
function THotKeyCollection.GetOwner: TPersistent;
begin
Result := FOwner;
end;
{-----------------------------------------------------------------------------
Procedure: THotKeyCollection.SetItem
Author: slq
Date: 08-三月-2002
Arguments: Idx: Integer; Item: TShenHotKeyItem
Result: None
Purpose:
-----------------------------------------------------------------------------}
procedure THotKeyCollection.SetItem(Idx: Integer; Item: TShenHotKeyItem);
begin
inherited Items[Idx] := Item;
end;
{ THotKeyItem }
{-----------------------------------------------------------------------------
Procedure: TShenHotKeyItem.RegisterHotKey
Author: slq
Date: 08-三月-2002
Arguments: None
Result: None
Purpose: 向系统注册
-----------------------------------------------------------------------------}
procedure TShenHotKeyItem.RegisterHotKey;
var Shift: Integer;
Key: Integer;
begin
if FHotKeyId <> 0 then
UnRegisterHotKey;
if FHotKey <> 0 then
begin
Shift := 0;
if ssAlt in ShiftState then
Shift := Shift + MOD_ALT;
if ssCtrl in ShiftState then
Shift := Shift + MOD_CONTROL;
if ssShift in ShiftState then
Shift := Shift + MOD_SHIFT;
Key := KeyCodes[FHotKey];
FHotKeyId := $A000 + ID;
Windows.RegisterHotKey(Application.Handle, FHotKeyId, Shift, Key);
end;
end;
{-----------------------------------------------------------------------------
Procedure: TShenHotKeyItem.UnRegisterHotKey
Author: slq
Date: 08-三月-2002
Arguments: None
Result: None
Purpose: 取消系统中的注册
-----------------------------------------------------------------------------}
procedure TShenHotKeyItem.UnRegisterHotKey;
begin
if FHotKeyId <> 0 then
begin
Windows.UnRegisterHotKey(Application.Handle, FHotKeyId);
FHotKeyId := 0;
end;
end;
{-----------------------------------------------------------------------------
Procedure: TShenHotKeyItem.ShortcuttoHotkeys
Author: slq
Date: 08-三月-2002
Arguments: Shortcut:TShortcut
Result: Boolean
Purpose: 转换TShortcut与热键,采用的也是一种笨方法:)
-----------------------------------------------------------------------------}
function TShenHotKeyItem.ShortcuttoHotkeys(Shortcut: TShortcut): Boolean;
var
tempshift, tempshiftold: TShenShiftState;
temphotkey, temphotkeyold: string;
W: Word;
begin
tempshiftold := ShiftState;
temphotkeyold := hotkey;
try
tempshift := [];
if Shortcut and scShift <> 0 then tempshift := tempshift + [ssShift];
if Shortcut and scCtrl <> 0 then tempshift := tempshift + [ssctrl];
if Shortcut and scAlt <> 0 then tempshift := tempshift + [ssAlt];
W := Shortcut and not (scShift + scCtrl + scAlt);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?