2011-03-14 10 views
5

Bir formda TListView bileşen var. Çok uzun ve farenin bileşeni ve tekerleğin üzerine kaydırılmış olması durumunda kullanıcının onu kaydırmasını istiyorum. TListView nesnesi için herhangi bir OnMouseWheel, OnMouseWheelDown veya OnMouseWheelUp olay bulamıyorum. Bunu nasıl yapabilirim?TListView ve fare tekerleği kaydırma

Selamlar, evilone

cevap

6

İşte bunun için benim kod:

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 oldukça şık olduğunu. Dikey kaydırma çubuğu ile herhangi bir kontrol için çalışır. Ağaç görünümleri, liste görünümleri, liste kutuları, notlar, zengin düzenlemeler vb. Ile kullanın.

Benim ModifierKeyState rutini kaçırıyorsunuz ama tekerleğin değiştirilmediğini kontrol etmek için kendi yönteminizi kullanabilirsiniz. Bunu yapmak istediğiniz nedeni, örneğin, CTRL + fare tekerleği kaydırmak yerine zum anlamına gelir. Ne olursa olsun için

, bu şuna benzer:

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

bu yeterli midir? Tekerlek mesajlarının her zaman imlecin altındaki pencereye gitmediğini, üst seviye pencereye (Delphi formu) gittiğini; Yani liste görünümü her zaman onları almıyor. Bir çerçevede bir çerçeve mesajına ihtiyaç duyduğum bir proje paketi için çok fazla mesaj iletmek zorunda olduğumu biliyorum. –

+0

@Cosmin Evet bu yeterli! –

+1

@David, projemde doğrudan WM_MOUSEHWHEEL ile uğraşmaya çalışıyordum ve mesaj düzgün bir şekilde akmıyordu (bazen çerçeve üzerinde, bazen formda, bazen hem çerçeve hem de formda olsun). Bu sorunla karşılaşan diğerlerini anlamaya 5 dakika ve hack'imi geliştirmek için 5 dakika sürdü. Şimdi 'TControl.WndProc() 'daki kodu okuyarak sonunda anladım: Tekerlek mesajı gerekli değil WM_MOUSEWHEEL (WM_MOUSEWHEEL WM_MOUSELAST'a eşit olduğu için). İşte bu yüzden (a) her zaman mesajı almadım ve (b) bazen mesajı iki kez aldım. Teşekkür ve + 1. –