5

我正在使用 Windows XE2、TVirtualStringTree和 aTComboBox作为就地编辑器。

当我将 aTComboBox直接放在表单上时,在运行时我可以下拉列表,鼠标滚轮会上下滚动列表中的项目(根据需要)。但是,当作为就地编辑器TComboBox在运行时创建时,即使新创建的组合框具有焦点,鼠标滚轮的消息也会发送到树控件而不是组合框。TVirtualStringTreeWM_MOUSEWHEEL

这很明显,因为组合框下拉列表中的项目不滚动。相反,组合框后面的树控件滚动。组合框的固定部分与树一起移动,但下拉列表与组合框的固定部分断开连接并且不移动(如图所示)。

树控件如何滚动到下拉列表后面的示例

在这两种情况下,TComboBox.Style都设置为csDropDownList。当组合框被创建为树的就地编辑器时,它是这样完成的:

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

鼠标悬停在哪里并不重要。它可以直接在组合框下拉列表中的项目上方,并且背景中的树控件仍然是滚动的。滚动组合框中的项目的唯一方法是使用它的滚动条。

什么会导致焦点控件的父级接收鼠标滚轮消息而不是控件本身(在本例中为TComboBox)?

4

1 回答 1

1

VirtualTrees.pas在类中包含以下声明TBaseVirtualTree

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

组件作者捕获了鼠标滚轮消息,因此他可以先垂直滚动,然后再水平滚动。自定义代码是将鼠标滚轮消息发送到TVirtualStringTree而不是TComboBox. 我注释掉了他的代码,TComboBox下拉列表按预期滚动。

由于我真的不想删除TBaseVirtualTree代码,因此我使用以下代码创建了自己TMyComboBox的代码以用作就地编辑器。现在滚动在下拉列表和树控件中都可以正常工作。

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;

这会在消息传递给树控件之前捕获CM_MOUSEWHEEL消息,并将其交给TControl.DoMouseWheel()方法进行处理。

于 2013-08-22T23:52:23.413 回答