關於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中的實現spa

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

 

可知,他會向全局廣播這個快捷消息,全部的控件都會得到這個消息,此時誰先得到,攔截處理以後,消息就再也不繼續。而後俺們看看SpeedButton的此消息處理過程blog

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;

再去使用,則觸發正常it

相關文章
相關標籤/搜索