5
我在表單中有一個TListView組件。這是相當長的,我希望用戶能夠滾動它,如果鼠標在組件和滾輪滾動。對於TListView對象,我找不到任何OnMouseWheel,OnMouseWheelDown或OnMouseWheelUp事件。我怎樣才能做到這一點?TListView和鼠標滾輪滾動
問候, evilone
我在表單中有一個TListView組件。這是相當長的,我希望用戶能夠滾動它,如果鼠標在組件和滾輪滾動。對於TListView對象,我找不到任何OnMouseWheel,OnMouseWheelDown或OnMouseWheelUp事件。我怎樣才能做到這一點?TListView和鼠標滾輪滾動
問候, evilone
這裏是我的代碼來做到這一點:
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;
是否已足夠?我認爲輪盤信息並不總是進入光標下的窗口,而是進入頂層窗口(Delphi窗體);所以列表視圖並不總是接收它們。我知道我必須爲Frame中需要輪子消息的項目帽子做很多消息轉發。 – 2011-03-14 10:24:31
@Cosmin是的,這就夠了! – 2011-03-14 10:26:17
@David,在我的項目中,我試圖直接處理WM_MOUSEHWHEEL,並且消息沒有正確流動(我有時會在框架上,有時在窗體上,有時在框架和窗體上)。我花了5分鐘找出其他人面臨這個問題,另外花了5分鐘來發展我的黑客。現在閱讀'TControl.WndProc()'中的代碼,我終於明白了:輪子消息不是必需的WM_MOUSEWHEEL(因爲WM_MOUSEWHEEL等於WM_MOUSELAST)。這就是爲什麼(a)我並不總是收到信息,(b)我有時收到了兩次的信息。感謝和+1。 – 2011-03-14 10:46:57