2016-03-01 18 views
2

我有一個嵌入滾動框內的窗體。我實現滾動的滾動框,如下所示:抑制特定控件上的鼠標滾動事件,但不抑制它們的父級?

procedure TfrmPO.sbItemsMouseWheelDown(Sender: TObject; Shift: TShiftState; 
    MousePos: TPoint; var Handled: Boolean); 
begin 
    sbItems.Perform(WM_VSCROLL, SB_PAGEDOWN, 0); 
end; 

procedure TfrmPO.sbItemsMouseWheelUp(Sender: TObject; Shift: TShiftState; 
    MousePos: TPoint; var Handled: Boolean); 
begin 
    sbItems.Perform(WM_VSCROLL, SB_PAGEUP, 0); 
end; 

該做的伎倆就好了,但是也有這種形式中的多個組合框控件。如果焦點在其中之一,它也將滾動該組合框內的項目。所以我需要禁用這種效果。

我已經嘗試了兩種解決方案,實際上可以工作,但是這兩種解決方案也引入了一個新問題:父滾動框永遠不會收到消息,因此不會根據需要進行滾動。如果焦點位於另一個控件中,父級會滾動,但如果焦點位於組合框中,則不會滾動。

嘗試1:

procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState; 
    WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); 
begin 
    if Screen.ActiveControl is TComboBox then Handled := True; 
end; 

嘗試2:

type 
    TComboBox = class(Vcl.StdCtrls.TComboBox) 
    protected 
    function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; override; 
    end; 

..... 

{ TComboBox } 

function TComboBox.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; 
    MousePos: TPoint): Boolean; 
begin 
    Result:= True; 
end; 

如何禁用特定的控制鼠標滾輪滾動而不禁用它在它的父?

回答

3

將鼠標滾輪消息傳播到接收它們的控件的父鏈,直到它處理爲。因此,在滾動框中將Handled設置爲真正處理它們的位置。不要在其他地方放置任何消息處理程序,以便將消息發送給父級。

procedure TfrmPO.sbItemsMouseWheelDown(Sender: TObject; Shift: TShiftState; 
    MousePos: TPoint; var Handled: Boolean); 
begin 
    Handled := True; 
    sbItems.Perform(WM_VSCROLL, SB_PAGEDOWN, 0); 
end; 
+0

我假設實際的滾動動作直到傳播完成後才執行,而不是在收到消息的那一刻。正確? –

+0

@Jerry這是正確的,只有在沒有人處理集合時才調用默認處理程序。您可以在TControl.WMMouseWheel的最後一行中看到,如果接收控件或父鏈中的一個*處理消息,則Message.Result爲1。 –