2013-08-22 13 views
5

Używam Windows XE2, TVirtualStringTree i TComboBox jako edytora umieszczonego w folderze.Koło myszy wysyła wiadomość do niewłaściwej kontrolki

Po umieszczeniu bezpośrednio na formularzu, w czasie wykonywania mogę upuścić listę, a kółko myszy przewija pozycje na liście w górę iw dół (zgodnie z życzeniem). Jednak, gdy TComboBox jest tworzony w czasie wykonywania przez TVirtualStringTree jako edytor lokalny, nawet jeśli nowo utworzone pole kombi ma fokus, wiadomość kółka myszy jest wysyłana do kontrolki drzewa, a nie do pola kombi.

Jest to oczywiste, ponieważ pozycje na rozwijanej liście rozwijanej listy rozwijanej nie są przewijane. Zamiast tego kontrolka drzewa znajdująca się za polem kombi przewija. Stała część pola kombi porusza się wraz z drzewem, ale lista rozwijana zostaje odłączona od stałej części pola kombi i nie porusza się (jak pokazano).

Example of how the tree control scrolled behind the drop-down list

W obu przypadkach TComboBox.Style jest ustawiony na csDropDownList. Gdy pole kombi jest tworzony jako redaktora drzewa w miejscu, że odbywa się to w ten sposób:

FCBox := TComboBox.Create(TreeControl); 
FCBox.Visible := False; 
FCBox.Parent := TreeControl; 
// ... add items to combo box ... 
FCBox.Visible := True; 
FCBox.SetFocus; 
FCBox.DroppedDown := True; 

To nie ma znaczenia, gdzie mysz jest uciążliwy. Może znajdować się bezpośrednio nad pozycjami na rozwijanej liście rozwijanej listy rozwijanej, a kontrolka drzewa w tle jest wciąż tą, która się przewija. Jedynym sposobem przewijania elementów w polu kombi jest użycie paska przewijania.

Co spowodowałoby, że rodzic aktywnej kontroli odebrałby komunikaty kółka myszy zamiast samej kontrolki (w tym przypadku TComboBox)?

+0

Znalazłem ten artykuł (http://msdn.microsoft.com/en-us/library/windows/desktop/ms645617(v=vs.85).aspx), który wyjaśnia, że ​​wiadomość jest wysyłana do kontrolki, a jeśli go nie obsługuje, jest wysyłany do łańcucha do rodzica, dopóki nie zostanie obsłużony. Teraz szukam, czy 'TVirtualStringTree' robi coś, co zmieni sposób, w jaki' TComboBox' obsługuje wiadomość. –

Odpowiedz

1

VirtualTrees.pas zawiera następujące oświadczenie w klasie TBaseVirtualTree:

private 
    procedure CMMouseWheel(var Message: TCMMouseWheel); message CM_MOUSEWHEEL; 

Autor komponent przechwycone wiadomości kółka myszy, aby mógł najpierw przewijać w pionie, a następnie poziomo. Kod niestandardowy jest powodem, że komunikaty kółka myszy są wysyłane do TVirtualStringTree zamiast do TComboBox. Skomentowałem jego kod i lista rozwijana TComboBox przewinęła się zgodnie z oczekiwaniami.

Ponieważ naprawdę nie chcę usunąć kodu TBaseVirtualTree, utworzyłem własny TMyComboBox z następującym kodem do użycia jako lokalny edytor. Teraz przewijanie działa poprawnie zarówno na liście rozwijanej, jak i na drzewie.

interface 

type 
    TMyCombBox = class(TComboBox) 
    private 
    procedure CMMouseWheel(var Message: TCMMouseWheel); message CM_MOUSEWHEEL; 
    end; 

implementation 

procedure TMyComboBox.CMMouseWheel(var Message: TCMMouseWheel); 
begin 
    if DoMouseWheel([], Message.WheelDelta, SmallPointToPoint(Message.Pos)) then 
    Message.Result := 1; 
end; 

ten przechwytuje wiadomość CM_MOUSEWHEEL zanim zostanie przekazany do kontroli drzew i ręce go do metody TControl.DoMouseWheel() do procesu.

+0

Powszechną praktyką jest obsługa wiadomości z edytora w miejscu pracy. Gdybyś to zrobił, powiedziałbyś "WM_MOUSEWHEEL", że go obsłużyłeś (przez twojego inplace editor), więc nic, co opisałeś by się nie stało. – TLama

+0

Dzięki @TLama - Problem polega na tym, że wiadomość nigdy nie została wysłana do edytora w miejscu.Zamiast tego został natychmiast wysłany do kontroli drzewa, omijając całkowicie 'TComboBox'. Musiałem odzyskać wiadomość w niestandardowym "TComboBox", aby to działało. Dodam rozwiązanie do mojej odpowiedzi. –

+0

Wiadomość została wysłana do pola kombi, ale ta mała bestia po prostu to zignorowała (nie poradziła sobie z tym) :-) Zmiana pozycji w polu kombi jest kontrolowana przez system i nic poza tym, kombi używa koła myszy, więc Nie zastanawiam się, czy ignoruje tę wiadomość w VCL. – TLama

Powiązane problemy