Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mouse-Wheel sending message to the wrong control

I am using Windows XE2, the TVirtualStringTree, and a TComboBox as an in-placed editor.

When I place a TComboBox directly on the form, at run-time I can drop down the list and the mouse wheel scrolls the items in the list up and down (as desired). However, when the TComboBox is created at run-time by TVirtualStringTree as an in-place editor, even though the newly created combo box has focus, the mouse wheel's WM_MOUSEWHEEL message is sent to the tree control and not the combo box.

This is evident because the items in the combo box drop-down list do not scroll. Instead, the tree control behind the combo box scrolls. The fixed portion of the combo box moves with the tree, but the drop-down list becomes disconnected from the fixed portion of the combo box and does not move (as depicted).

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

In both cases the TComboBox.Style is set to csDropDownList. When the combo box is created as the tree's in-place editor, it is done this way:

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

It doesn't matter where the mouse is hovering. It can be directly over the items in the combo box drop-down list and the tree control in the background is still the one that scrolls. The only way to scroll the items in the combo box is to use its scroll bar.

What would cause the parent of the focused control to receive the mouse wheel messages instead of the control itself (in this case, the TComboBox)?

like image 658
James L. Avatar asked Nov 12 '22 23:11

James L.


1 Answers

VirtualTrees.pas includes the following declaration in the TBaseVirtualTree class:

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

The component author captured the mouse wheel messages so he could first scroll vertically and then horizontally. The custom code is the reason that the mouse wheel messages are being sent to the TVirtualStringTree instead of the TComboBox. I commented out his code and the TComboBox drop-down list scrolled as expected.

Since I really don't want to remove the TBaseVirtualTree code, I created my own TMyComboBox with the following code to use as the in-place editor. Now scrolling works correctly in both the drop-down list and in the tree control.

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;

This captures the CM_MOUSEWHEEL message before it is passed to the tree control and hands it to the TControl.DoMouseWheel() method to process.

like image 183
James L. Avatar answered Nov 15 '22 05:11

James L.