如何在自己的按钮控件中加入快捷键!!如ctrl-a???(50分)

  • 主题发起人 主题发起人 wangwei200208
  • 开始时间 开始时间
//看一下可不可以再改进.
unit HotKeyBtns;

interface

uses
Windows, Messages, SysUtils, Classes, Controls, StdCtrls, ComCtrls, Menus;

type
THotKeyBtn = class(TButton)
private
{ Private declarations }
FHotKey : TShortCut;
protected
{ Protected declarations }
public
{ Public declarations }
procedure WMHOTKEY(var Message : TMessage); message WM_HOTKEY;
procedure WMDESTROY(var Message : TMessage); message WM_DESTROY;
procedure Loaded;override;
constructor Create(AOwner: TComponent); override;
published
{ Published declarations }
property HotKey : TShortCut read FHotKey write FHotKey;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Samples', [THotKeyBtn]);
end;

{ THotKeyBtn }

constructor THotKeyBtn.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FHotKey := 0;
end;

procedure THotKeyBtn.Loaded;
var
Key: Word;
Shift: TShiftState;
Const
ShiftKeys : array[0..2] of Integer=(MOD_SHIFT, MOD_ALT, MOD_CONTROL);
begin
inherited;
if not (csDesigning in ComponentState) and (FHotKey <> 0) then
begin
ShortCutToKey(FHotKey, Key, Shift);
if Shift = [ssShift] then
RegisterHotKey(Handle, IDHOT_SNAPWINDOW, MOD_SHIFT, Key)
else
if Shift = [ssAlt] then
RegisterHotKey(Handle, IDHOT_SNAPWINDOW, MOD_ALT, Key)
else
if Shift = [ssCtrl] then
RegisterHotKey(Handle, IDHOT_SNAPWINDOW, MOD_CONTROL, Key);
end;
end;

procedure THotKeyBtn.WMDESTROY(var Message: TMessage);
begin
if not (csDesigning in ComponentState) then
UnregisterHotKey(Handle, IDHOT_SNAPWINDOW);
inherited;
end;

procedure THotKeyBtn.WMHOTKEY(var Message: TMessage);
var
Key: Word;
Shift: TShiftState;
function GetPWnd : THandle;
begin
Result := Handle;
repeat
Result := Windows.GetParent(Result);
until not IsWindow(Windows.GetParent(Result));
end;
begin
ShortCutToKey(FHotKey, Key, Shift);
if (GetActiveWindow = GetPWnd) and (Message.WParam = IDHOT_SNAPWINDOW) and
(Message.LParamHi = Key) and
((Message.LParamLo = MOD_CONTROL) and (Shift = [ssCtrl]) or
(Message.LParamLo = MOD_ALT) and (Shift = [ssAlt]) or
(Message.LParamLo = MOD_SHIFT) and (Shift = [ssShift])) and Enabled then Click
end;

end.
 
if (GetActiveWindow = GetPWnd)
如果把按钮放在一个PANEL上,快捷键就不管用!!
 
你试过吗?
function GetPWnd : THandle;
begin
Result := Handle;
repeat
Result := Windows.GetParent(Result);
until not IsWindow(Windows.GetParent(Result));
end;
这个函数是找窗口.应该是可以的.
 
试过,不管用
 
//修正一下:
unit HotKeyBtns;

interface

uses
Windows, Messages, SysUtils, Classes, Controls, StdCtrls, ComCtrls, Menus;

type
THotKeyBtn = class(TButton)
private
{ Private declarations }
FHotKey : TShortCut;
procedure SetHotKey(Value : TShortCut);
protected
{ Protected declarations }
procedure SetParent(AParent: TWinControl); override;
public
{ Public declarations }
procedure WMHOTKEY(var Message : TMessage); message WM_HOTKEY;
procedure WMDESTROY(var Message : TMessage); message WM_DESTROY;
procedure LoadHotKey;
constructor Create(AOwner: TComponent); override;
published
{ Published declarations }
property HotKey : TShortCut read FHotKey write SetHotKey;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Samples', [THotKeyBtn]);
end;

{ THotKeyBtn }

constructor THotKeyBtn.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FHotKey := 0;
end;

procedure THotKeyBtn.LoadHotKey;
var
Key: Word;
Shift: TShiftState;
begin
inherited;
if not (csDesigning in ComponentState) and (FHotKey <> 0) and Assigned(Parent) then
begin
ShortCutToKey(FHotKey, Key, Shift);
if Shift = [ssShift] then
RegisterHotKey(Handle, IDHOT_SNAPWINDOW, MOD_SHIFT, Key)
else
if Shift = [ssAlt] then
RegisterHotKey(Handle, IDHOT_SNAPWINDOW, MOD_ALT, Key)
else
if Shift = [ssCtrl] then
RegisterHotKey(Handle, IDHOT_SNAPWINDOW, MOD_CONTROL, Key);
end;
end;

procedure THotKeyBtn.SetHotKey(Value: TShortCut);
begin
if Value <> FHotKey then
begin
if not (csDesigning in ComponentState) and (FHotKey <> 0) then
UnregisterHotKey(Handle, IDHOT_SNAPWINDOW);
FHotKey := Value;
LoadHotKey;
end;
end;

procedure THotKeyBtn.SetParent(AParent: TWinControl);
begin
inherited;
LoadHotKey;
end;

procedure THotKeyBtn.WMDESTROY(var Message: TMessage);
begin
if not (csDesigning in ComponentState) then
UnregisterHotKey(Handle, IDHOT_SNAPWINDOW);
inherited;
end;

procedure THotKeyBtn.WMHOTKEY(var Message: TMessage);
var
Key: Word;
Shift: TShiftState;
function GetPWnd : THandle;
begin
Result := Handle;
repeat
Result := Windows.GetParent(Result);
until not IsWindow(Windows.GetParent(Result));
end;
begin
ShortCutToKey(FHotKey, Key, Shift);
if (GetActiveWindow = GetPWnd) and (Message.WParam = IDHOT_SNAPWINDOW) and
(Message.LParamHi = Key) and
((Message.LParamLo = MOD_CONTROL) and (Shift = [ssCtrl]) or
(Message.LParamLo = MOD_ALT) and (Shift = [ssAlt]) or
(Message.LParamLo = MOD_SHIFT) and (Shift = [ssShift])) and Visible and Enabled then Click
end;

end.
 
我测试过了,没问题,只是在我以前做的一个程序中不管用,请帮我分析一下好吗?哪方面会出问题???
 
要重新build
删除所有的dcu文件再build或Project -> Build All Projects
 
不管用,太奇怪了!!!主窗口的快捷键管用,再打开的就不管用,新建工程测试也没问题!!会是那的事呢????
 
檢查一下HotKey有沒有設置,因為Create時FHotKey=0
 
我去掉控件中(GetActiveWindow = GetPWnd) 就可以用了,但是热键会冲突
感觉问题出在这里,但是新建工程中测试,没有问题!!真是很烦!!
 
to amli:
我把控件,发给你,帮忙看一下,控件有什么问题吗?可以吗???
 
my_netbox@hotmail.com
 
to amli:
收到了吗???
 
收到了,我看一下.
 
to amli:
msn message注册了吗?我加你可以吗????
 
可以,你的程序是不是MID的中
 
錯了:
RegisterHotKey(Handle, IDHOT_SNAPWINDOW, MOD_SHIFT + MOD_CONTROL, Ord(TheKey))

->

RegisterHotKey(Handle, IDHOT_SNAPWINDOW, MOD_SHIFT or MOD_CONTROL, TheKey)
 
还是不行
 
你先改成這樣
procedure THotKeyBtn.WMHOTKEY(var Message: TMessage);
var
Key: Word;
Shift: TShiftState;
function GetPWnd : THandle;
begin
Result := Handle;
repeat
Result := Windows.GetParent(Result);
until not IsWindow(Windows.GetParent(Result));
end;
begin
ShortCutToKey(FHotKey, Key, Shift);
if (Screen.ActiveCustomForm.Handle = GetPWnd) and (Message.WParam = IDHOT_SNAPWINDOW) and
(Message.LParamHi = Key) and
((Message.LParamLo = MOD_CONTROL) and (Shift = [ssCtrl]) or
(Message.LParamLo = MOD_ALT) and (Shift = [ssAlt]) or
(Message.LParamLo = MOD_SHIFT) and (Shift = [ssShift])) and Visible and Enabled then Click;
end;
 
后退
顶部