L
linzhengqqun
Unregistered / Unconfirmed
GUEST, unregistred user!
下面是我的代码(很简单的)
TWindHotKey = class(TComponent)
private
FHandle:THandle;
FActive: Boolean;
FKeyID: Integer;
FHotKey: TShortCut;
FonHotKeyEvent:TNotifyEvent;
procedure SetKeyID(AValue:Integer);
procedure SetHotKey(Value: TShortCut);
procedure SetActive(AValue:Boolean);
function ShiftStateToWord(Shift: TShiftState): Word;
protected
procedure HotKeyProc(var Msg:TMessage);
public
constructor Create(AOwner:TComponent);override;
destructor destroy;override;
published
property KeyID:Integer read FKeyID write SetKeyID default 0;
property Active :Boolean read FActive write SetActive;
property HotKey:TShortCut read FHotKey write SetHotKey default $0041;
property onHotKeyEvent:TNotifyEvent read FonHotKeyEvent write FonHotKeyEvent;
end;
implementation
{ TWindHotKey }
//初始化热键
constructor TWindHotKey.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
FHotKey := $0041;
FHandle:=AllocateHWnd(HotKeyProc);
end;
//析构,结束一些设置
destructor TWindHotKey.destroy;
begin
SetActive(False);
DeallocateHWnd(FHandle);
inherited;
end;
//设置热键
procedure TWindHotKey.SetActive(AValue: Boolean);
var vKey: Word;
vShift: TShiftState;
begin
if AValue<>FActive then
begin
if not (csDesigning in ComponentState) then
begin
if AValue then
begin
ShortCutToKey(FHotKey, vKey, vShift);
if not RegisterHotKey(FHandle,FKeyID, ShiftStateToWord(vShift), vKey) then
raise Exception.Create('热键设置失败,可能有冲突,请重新设置KeyID!');
end
else begin
UnregisterHotKey(FHandle, FKeyID);
end;
end;
FActive:=AValue;
end;
end;
//将Shitf状态转换为整数
function TWindHotKey.ShiftStateToWord(Shift: TShiftState): Word;
begin
Result := 0;
if ssShift in Shift then Result := Result or MOD_SHIFT;
if ssCtrl in Shift then Result := Result or MOD_CONTROL;
if ssAlt in Shift then Result := Result or MOD_ALT;
end;
//设置热键
procedure TWindHotKey.SetHotKey(Value: TShortCut);
begin
if FHotKey<>Value then
FHotKey:=Value;
end;
//设置热键ID
procedure TWindHotKey.SetKeyID(AValue: Integer);
begin
if AValue<>FKeyID then
FKeyID:=AValue;
end;
//热键处理过程
procedure TWindHotKey.HotKeyProc(var Msg: TMessage);
begin
if Msg.Msg=WM_HOTKEY then
if TWMHotKey(Msg).HotKey=FKeyID then
if Assigned(FonHotKeyEvent) then
FonHotKeyEvent(self);
end;
----------------------------------
现在有两个问题:
1。属性property HotKey:TShortcut 在对象察看器中是一个Edit(需要输入整数),而不是像THotKey控件的HotKey属性一样是一个下拉框(可以选择热键),在TMenuItem中的Shortcut属性也一样是一个下拉框。
请问他们同样是TShortCut属性,为什么我的HotKey属性不是下拉框呢。
2。当我的FonHotKeyEvent(self);触发时,我在事件里写一个ShowMessage,却不会显示。
而却可以明显感觉这个事件触了。
TWindHotKey = class(TComponent)
private
FHandle:THandle;
FActive: Boolean;
FKeyID: Integer;
FHotKey: TShortCut;
FonHotKeyEvent:TNotifyEvent;
procedure SetKeyID(AValue:Integer);
procedure SetHotKey(Value: TShortCut);
procedure SetActive(AValue:Boolean);
function ShiftStateToWord(Shift: TShiftState): Word;
protected
procedure HotKeyProc(var Msg:TMessage);
public
constructor Create(AOwner:TComponent);override;
destructor destroy;override;
published
property KeyID:Integer read FKeyID write SetKeyID default 0;
property Active :Boolean read FActive write SetActive;
property HotKey:TShortCut read FHotKey write SetHotKey default $0041;
property onHotKeyEvent:TNotifyEvent read FonHotKeyEvent write FonHotKeyEvent;
end;
implementation
{ TWindHotKey }
//初始化热键
constructor TWindHotKey.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
FHotKey := $0041;
FHandle:=AllocateHWnd(HotKeyProc);
end;
//析构,结束一些设置
destructor TWindHotKey.destroy;
begin
SetActive(False);
DeallocateHWnd(FHandle);
inherited;
end;
//设置热键
procedure TWindHotKey.SetActive(AValue: Boolean);
var vKey: Word;
vShift: TShiftState;
begin
if AValue<>FActive then
begin
if not (csDesigning in ComponentState) then
begin
if AValue then
begin
ShortCutToKey(FHotKey, vKey, vShift);
if not RegisterHotKey(FHandle,FKeyID, ShiftStateToWord(vShift), vKey) then
raise Exception.Create('热键设置失败,可能有冲突,请重新设置KeyID!');
end
else begin
UnregisterHotKey(FHandle, FKeyID);
end;
end;
FActive:=AValue;
end;
end;
//将Shitf状态转换为整数
function TWindHotKey.ShiftStateToWord(Shift: TShiftState): Word;
begin
Result := 0;
if ssShift in Shift then Result := Result or MOD_SHIFT;
if ssCtrl in Shift then Result := Result or MOD_CONTROL;
if ssAlt in Shift then Result := Result or MOD_ALT;
end;
//设置热键
procedure TWindHotKey.SetHotKey(Value: TShortCut);
begin
if FHotKey<>Value then
FHotKey:=Value;
end;
//设置热键ID
procedure TWindHotKey.SetKeyID(AValue: Integer);
begin
if AValue<>FKeyID then
FKeyID:=AValue;
end;
//热键处理过程
procedure TWindHotKey.HotKeyProc(var Msg: TMessage);
begin
if Msg.Msg=WM_HOTKEY then
if TWMHotKey(Msg).HotKey=FKeyID then
if Assigned(FonHotKeyEvent) then
FonHotKeyEvent(self);
end;
----------------------------------
现在有两个问题:
1。属性property HotKey:TShortcut 在对象察看器中是一个Edit(需要输入整数),而不是像THotKey控件的HotKey属性一样是一个下拉框(可以选择热键),在TMenuItem中的Shortcut属性也一样是一个下拉框。
请问他们同样是TShortCut属性,为什么我的HotKey属性不是下拉框呢。
2。当我的FonHotKeyEvent(self);触发时,我在事件里写一个ShowMessage,却不会显示。
而却可以明显感觉这个事件触了。