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

  • 主题发起人 主题发起人 wangwei200208
  • 开始时间 开始时间
W

wangwei200208

Unregistered / Unconfirmed
GUEST, unregistred user!
如何在自己的按钮控件中加入快捷键!!如ctrl-a???
请注意我不要用Action!!不要告诉我&Caption之类的!!
 
这个对你用没有用呢???
应用程序敏感键的实现 应用程序敏感键的实现
浙江巨化集团公司物资装备分公司
胡小文
---- 在一个应用程序内部菜单、部件都可以设置敏感键。如在菜单中一般用
Alt+F进入“文件”之类的子菜单。另外我们在桌面上设置的快捷方式里的快捷
键,无论你任何时候按下你所设置的快捷键就会启动相应的应用程序。在多个正
在运行的应用程序中如何利用一个按键动作迅速地回到你所需要的应用程序
呢?这就需要利用敏感键(HOTKEY)的技术来实现。本文利用Delphi3.0开发工
具来阐述该技术在应用程序的实现方法。
一、敏感键的设置
---- 在windows Api中有一个函数RegisterHotKey用于设置敏感键,它的调用
方式如下:
BOOL RegisterHotKey(
HWND hWnd, //响应该敏感键的窗口句柄
Int id, //该敏感键的唯一标示符
UINT fsModifiers, //该敏感键的辅助按键
UINT vk //该敏感键的键值
);
---- 其中敏感键的唯一标示符在Window中规定应用程序的取值范围为0x0000到0xBFFF
之间,动态链接库的取值范围为0xC000到0xFFFF之间。为了保证其唯一性建议使用
GlobalAddAtom函数来设置敏感键的唯一标示符。需要注意的是GlobalAddAtom还回的值
是在0xC000到0xFFFF范围之间,为满足RegisterHotKey的调用要求,如果是在应用程序
中设置敏感键可以利用GlobalAddAtom还回值减去0xC000。
---- 敏感键的辅助按键包括Mod_Ctrl 、Mod_Alt、Mod_Shift,对于Windows兼
容键盘还支持Windows键,即其键面上有Windows标志的那个键,其值为
Mod_win。
---- 在Delphi中建立一个“New Application”,在Tform1中的Private段中
加入如下代码
private
{ Private declarations }
hotkeyid :integer;
procedure WMhotkeyhandle(var msg:Tmessage);
message wm_hotkey; //响应敏感键按键消息
在FormCreate事件中加入如下代码

hotkeyid:=GlobalAddAtom(pchar
("UserDefineHotKey"))-$C000;
//减去$C000是为了保证取值范围的限制
registerhotkey(handle,hotkeyid,
MOD_CONTROL or mod_Altt,$41);
//敏感键为ctrl+Alt+A

二、敏感键的响应
---- 一旦敏感键设置成功,在程序应用过程中如果有相应敏感键被按下,
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; //该消息已经处理
application.BringToFront;
//把窗口最前面显示
end;
end;
三、敏感键的释放
---- 在应用程序退出来之前应当把你所设置的敏感键释放掉,以释放其所占有
的系统资源,这里需要调用两个Windows API函数UNREGISTERHOTKEY,它的调用
格式如下:
BOOL UNREGISTERHOTKEY(
HWND HWND, //与敏感键关联的窗口句柄
INT ID //敏感键的标示符
);
也就是说只要在FormClose事件中加入如下代码

unregisterhotkey(handle,hotkeyid);
DeleteAtom(HotKeyID);

---- 到这里为止,你应当对敏感键技术有了全面的了解, 以上的例子相当简单同时也没有提
供必要的调用成功检测,可以根据具体情况加以完善,希望对你的开发过程会有所帮助.

 
可在form的onkeydown事件中加入
if Shift=[ssCtrl] then
if key=65 then Button1Click(Sender); //Ctrl+A
并把form的keypreview设为true.
各个按键的键值是多少,可以任意可见控件的onkeydown里用如下语句测试:
showmessage(inttostr(key));
 
button1.caption='确定(&A)'
 
app2001的是全局热键, 任何情况都可以, 但未必符合你的要求;
HunterTeam 的会被 相同的 热键取代,而且人家是要求在控件上,每个放有这个控件的都要在form写代码,不符合逻辑。

请看看 menu 的shortCut 的写法。你会达到启示。
 
to xuxiaohan
看过MENU!没有找到关于快捷键的设定方法!能帮助看看吗?
 
好的,我这就看看,其他的shortCut也可以参考
 
property shortCut: TshotCut read FshortCut write SetShortCut;

var
yourCtrl: TyourControl;
function TyourControl.IsShortCut (var Message: TWMKey): Boolean;
var
ShortCut: TShortCut;
ShiftState: TShiftState;
begin
result:=false;
ShiftState := KeyDataToShiftState(Message.KeyData);
ShortCut := Menus.ShortCut(Message.CharCode, ShiftState);
if enabled and (Menus.ShortCutToText(ShortCut)='Ctrl+A') then
begin
click;//或其他你的shortCut执行的方法;
showmessage('you press sgortCut ctrl+A');
Result:=true;
end;
end;

class function TyourControl..MainWindowHook (var Message: TMessage): Boolean;
begin
if (Message.Msg = CM_APPKEYDOWN) then
begin
if aggigned(yourCtrl) and yourCtrl.IsShortCut(TWMKey(Message)) then
begin
Message.Result := 1;
Result := True;
end;
end;
end;

procedure TYourControl.SetMainWindowHook;
begin
youCtrl:=self;
if not (csDesigning in ComponentState) then
Application.HookMainWindow (MainWindowHook)
end;

在适当的位置加入SetMainWindowHook, 例如在 constructor create; 或在 setShortCut 里面;这样Application就可以处理你的shortCut啦,你试一试!

刚刚改了下,测试通过!!!
 
测试通过。
你可以将shortCut作为属性,具体方法相信你明白!
 
强烈建议您看看VCl的源码,在里面有说明关于Shortcut的属性设置方法。
 
我想楼上几位也许把楼主的问题实现得太过于复杂,本人常用的方法是TActionList控件,增加一个Standard Action就可以设置Action的Caption, ShortCut属性了,然后把按钮的Action设为新增的Action1即可。

需要注意的是,好像必须要实现该Action的Execute事件,否则按钮将不可用。
 
我就是不想用Action
 
我看了标准的控件的ShortCut都是这样做的,我测试过没有问题,你试试看!
 
to xuxiaohan

property shortCut: TshotCut read FshortCut write SetShortCut;

var
yourCtrl: TyourControl;
function TyourControl.IsShortCut (var Message: TWMKey): Boolean;
var
ShortCut: TShortCut;
ShiftState: TShiftState;
begin
result:=false;
ShiftState := KeyDataToShiftState(Message.KeyData);
ShortCut := Menus.ShortCut(Message.CharCode, ShiftState);
if enabled and (Menus.ShortCutToText(ShortCut)='Ctrl+A') then
begin
click;//或其他你的shortCut执行的方法;
showmessage('you press sgortCut ctrl+A');
Result:=true;
end;
end;

class function TyourControl..MainWindowHook (var Message: TMessage): Boolean;
begin
if (Message.Msg = CM_APPKEYDOWN) then
begin
if aggigned(yourCtrl) and yourCtrl.IsShortCut(TWMKey(Message)) then
assigned???如果改成assigned报错!!
这里的yourCtrl写什么?实在不明白!!
begin
Message.Result := 1;
Result := True;
end;
end;
end;

procedure TYourControl.SetMainWindowHook;
begin
youCtrl:=self; <-----什么意思???
if not (csDesigning in ComponentState) then
Application.HookMainWindow (MainWindowHook)
end;
 
用 TActionList 不就可以了
 
sorry, 是yourCtrl,不是youCtrl;
youtCtrl是你的 控件的实例
前面有定义,yourCtrl: TYourControl;
你也可以在下面给yourCtrl赋值;
constructor create(AOwner: TComponent);
begin
yourCtrl:=self;
end;
 
to xuxiaohan

class function TyourControl..MainWindowHook (var Message: TMessage): Boolean;
begin
if (Message.Msg = CM_APPKEYDOWN) then
begin
if aggigned(yourCtrl) and yourCtrl.IsShortCut(TWMKey(Message)) then
assigned???如果改成assigned报错!!
这里的yourCtrl写什么?实在不明白!!
begin
Message.Result := 1;
Result := True;
end;
end;
end;
 

Similar threads

回复
0
查看
820
不得闲
S
回复
0
查看
695
SUNSTONE的Delphi笔记
S
S
回复
0
查看
783
SUNSTONE的Delphi笔记
S
后退
顶部