关于SpeedButton中使用下划线快捷键不响应的问题

简介:

  在Windows应用程序,很多都有快捷键功能,这个Delphi也有,就是一个按钮上面有一个比如剪切(&X),这个时候剪切的快捷键就是Alt+X,这个功能有时候还是挺好用的,最近,公司中有同事,好些使用了SpeedButton,然后使用本方式整的快捷键,都不能用,于是问我,这个是神马问题,实际上确切的说,也不是不能用,而是在某些情况下不能用,比如说使用PageControl等一类控件,然后再TabSheet下面再放一个Panel,然后再Panel上放SpeedButton,这个时候,使用快捷键就会导致响应有问题,比如说TabSheet1中直接就有一个SpeedButton就在TabSheet1上,TabSheet2上的SpeedButton在Panel上,两个TabSheet的SpeedButton的快捷键都是Alt+A,此时按道理来说,应该快捷键,哪个TabSheet是激活状态,就应该响应那个TabSheet上的SpeedButton的快捷键事件,可是实际上,只要有Panel的那个SpeedButton页面激活过之后,就会一直响应那个页面的SpeedButton的快捷键激活。而且会导致混乱。

   针对这个问题,啥办法呢,自然不能盲目的去整,Delphi比较好的一点就是VCL源码都带了,所以直接去VCL中去找答案就行了,通过跟踪发现Alt+X这类快捷键模式实际上是响应的Delphi的CM_DIALOGCHAR这个消息,然后查看TwinControl中的实现

procedure TWinControl.CMDialogChar(var Message: TCMDialogChar);
begin
  Broadcast(Message);
end;

 

可知,他会向全局广播这个快捷消息,所有的控件都会获得这个消息,此时谁先获得,拦截处理之后,消息就不再继续。然后俺们看看SpeedButton的此消息处理过程

复制代码
procedure TSpeedButton.CMDialogChar(var Message: TCMDialogChar);
begin
  with Message do
    if IsAccel(CharCode, Caption) and Enabled and Visible and
      (Parent <> nil) and Parent.Showing then
    begin
      Click;
      Result := 1;
    end else
      inherited;
end;
复制代码

IsAccel函数,实际上就是根据Caption来判定是否和快捷键匹配的,如果匹配,并且Enabled并且可视,并且Parent可视,那么就会触发了,于是问题根源找到了,就是这个parent可视,因为TabSheet上的Parent一直是可视的,所以这个就会触发,但是Parent的TabSheet确实隐藏了,所以,就导致了这个乱了。既然找到问题所在,那么针对此消息

过程进行拦截处理就行了。实现过程如下:

复制代码
TSpeedButton = class(Buttons.TSpeedButton)
  protected
    procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;
  end;

procedure TSpeedButton.CMDialogChar(var Message: TCMDialogChar);
var
  p: TWinControl;
  CanDlgChar: Boolean;
begin
  CanDlgChar := False;
  p := Parent;
  while P <> nil do
  begin
    CanDlgChar := IsWindowVisible(P.Handle);
    if not CanDlgChar then
      Break;
    p := p.Parent;
  end;

  if CanDlgChar then
  with Message do
    if IsAccel(CharCode, Caption) and Enabled and Visible and
      (Parent <> nil) and IsWindowVisible(Parent.Handle) and Parent.Showing then
    begin
      Click;
      Result := 1;
    end else
      inherited;
end;
复制代码


相关文章
|
8月前
解决“word空格后面下划线自动消失”问题
解决“word空格后面下划线自动消失”问题
|
10月前
【Word】关闭段落/表格等首字母大写功能
【Word】关闭段落/表格等首字母大写功能
101 0
|
11月前
|
Unix C语言 C++
正确理解回车与换行
回车 \r 本义是光标重新回到本行开头 换行 \n 本义是光标往下一行(不一定到下一行行首)
115 0
|
人工智能 小程序 算法
小程序弹出半角遮罩层
小程序弹出半角遮罩层
164 0
小程序弹出半角遮罩层
|
Android开发
安卓资源字串中加全角空格、半角空格、换行、@%等特殊字符
安卓资源字串中加全角空格、半角空格、换行、@%等特殊字符
242 0
|
C#
实现:C#窗体中的文本框只能输入中文汉字,其他输入无效。问:正则表达式怎么用?
原文:实现:C#窗体中的文本框只能输入中文汉字,其他输入无效。问:正则表达式怎么用? private void textBox1_KeyPress(object sender, KeyPressEventArgs e...
1484 0