2011-03-14 154 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