2011-03-14 188 views
5

我在表單中有一個TListView組件。這是相當長的,我希望用戶能夠滾動它,如果鼠標在組件和滾輪滾動。對於TListView對象,我找不到任何OnMouseWheel,OnMouseWheelDown或OnMouseWheelUp事件。我怎樣才能做到這一點?TListView和鼠標滾輪滾動

問候, evilone

回答

6

這裏是我的代碼來做到這一點:

type 
    TMyListView = class(TListView) 
    protected 
    function DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; override; 
    function DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; override; 
    end; 

type  
    TMouseWheelDirection = (mwdUp, mwdDown); 

function GenericMouseWheel(Handle: HWND; Shift: TShiftState; WheelDirection: TMouseWheelDirection): Boolean; 
var 
    i, ScrollCount, Direction: Integer; 
    Paging: Boolean; 
begin 
    Result := ModifierKeyState(Shift)=[];//only respond to un-modified wheel actions 
    if Result then begin 
    Paging := DWORD(Mouse.WheelScrollLines)=WHEEL_PAGESCROLL; 
    ScrollCount := Mouse.WheelScrollLines; 
    case WheelDirection of 
    mwdUp: 
     if Paging then begin 
     Direction := SB_PAGEUP; 
     ScrollCount := 1; 
     end else begin 
     Direction := SB_LINEUP; 
     end; 
    mwdDown: 
     if Paging then begin 
     Direction := SB_PAGEDOWN; 
     ScrollCount := 1; 
     end else begin 
     Direction := SB_LINEDOWN; 
     end; 
    end; 
    for i := 1 to ScrollCount do begin 
     SendMessage(Handle, WM_VSCROLL, Direction, 0); 
    end; 
    end; 
end; 

function TMyListView.DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; 
begin 
    //don't call inherited 
    Result := GenericMouseWheel(Handle, Shift, mwdDown); 
end; 

function TMyListView.DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; 
begin 
    //don't call inherited 
    Result := GenericMouseWheel(Handle, Shift, mwdUp); 
end; 

GenericMouseWheel是相當漂亮。它適用於具有垂直滾動條的任何控件。我將它與樹形視圖,列表視圖,列表視圖,列表框,備忘錄,豐富的編輯等結合使用。

您會錯過我的ModifierKeyState例程,但您可以使用自己的方法來檢查wheel事件是否未修改。你想這樣做的原因是,例如,CTRL +鼠標滾輪意味着縮放而不是滾動。

對於它的價值,它看起來像這樣:

type 
    TModifierKey = ssShift..ssCtrl; 
    TModifierKeyState = set of TModifierKey; 

function ModifierKeyState(Shift: TShiftState): TModifierKeyState; 
const 
    AllModifierKeys = [low(TModifierKey)..high(TModifierKey)]; 
begin 
    Result := AllModifierKeys*Shift; 
end; 
+1

是否已足夠?我認爲輪盤信息並不總是進入光標下的窗口,而是進入頂層窗口(Delphi窗體);所以列表視圖並不總是接收它們。我知道我必須爲Frame中需要輪子消息的項目帽子做很多消息轉發。 – 2011-03-14 10:24:31

+0

@Cosmin是的,這就夠了! – 2011-03-14 10:26:17

+1

@David,在我的項目中,我試圖直接處理WM_MOUSEHWHEEL,並且消息沒有正確流動(我有時會在框架上,有時在窗體上,有時在框架和窗體上)。我花了5分鐘找出其他人面臨這個問題,另外花了5分鐘來發展我的黑客。現在閱讀'TControl.WndProc()'中的代碼,我終於明白了:輪子消息不是必需的WM_MOUSEWHEEL(因爲WM_MOUSEWHEEL等於WM_MOUSELAST)。這就是爲什麼(a)我並不總是收到信息,(b)我有時收到了兩次的信息。感謝和+1。 – 2011-03-14 10:46:57