【问题标题】:Is there a way to track scroll bar messages from TComboBox?有没有办法从 ComboBox 跟踪滚动条消息?
【发布时间】:2015-03-05 12:30:06
【问题描述】:

在我的扩展 TComboBox 类中,我覆盖了 ComboWndProc() 过程处理程序,但我无法从列表的滚动条 (FListHandle) 中检测到 CN_VSCROLL 和 WM_VSCROLL 消息。

我基本上想用winapi实现无限滚动。
我想,为了做我想做的事,我基本上需要知道滚动条的轨迹栏位置,所以当轨迹栏触摸下线按钮时,我会向字符串添加更多数据。

这个想法很简单,也许很天真,但我可以从那里开始,看看我会遇到什么问题。

这样的事情有可能吗?

有没有办法从 TComboBox 跟踪滚动条消息?

更重要的是:

  • 如果是,如何
  • 如果不是,为什么

【问题讨论】:

  • 也欢迎替代品,只是说
  • 你当然需要 ListWndProc。而且我看不到您收到任何 CN_XXX 消息。我希望这是一个纯 Win32 窗口。
  • @DavidHeffernan ListWndProc 只是调用 ComboWndProc。我想知道,我认为这些消息永远不会到达列表句柄
  • 你的组合是什么风格?以防万一
  • @DavidHeffernan csDropDown

标签: windows delphi winapi combobox delphi-6


【解决方案1】:

您可以使用WM_VSCROLL,为此您必须继承组合框的列表框控件。 CN_VSCROLL 将不起作用,因为组合框的列表框部分不是 VCL 控件。

以下示例主要来自 Kobik 的 this answer,为了完整起见,将其包含在此处。

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FComboListWnd: HWND;
    FComboListWndProc, FSaveComboListWndProc: Pointer;
    procedure ComboListWndProc(var Message: TMessage);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  Info: TComboBoxInfo;
begin
  ZeroMemory(@Info, SizeOf(Info));
  Info.cbSize := SizeOf(Info);
  GetComboBoxInfo(ComboBox1.Handle, Info);
  FComboListWnd := Info.hwndList;
  FComboListWndProc := classes.MakeObjectInstance(ComboListWndProc);
  FSaveComboListWndProc := Pointer(GetWindowLong(FComboListWnd, GWL_WNDPROC));
  SetWindowLong(FComboListWnd, GWL_WNDPROC, Longint(FComboListWndProc));
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  SetWindowLong(FComboListWnd, GWL_WNDPROC, Longint(FSaveComboListWndProc));
  classes.FreeObjectInstance(FComboListWndProc);
end;

procedure TForm1.ComboListWndProc(var Message: TMessage);
begin
  case Message.Msg of
    WM_VSCROLL: OutputDebugString('scrolling');
  end;
  Message.Result := CallWindowProc(FSaveComboListWndProc,
      FComboListWnd, Message.Msg, Message.WParam, Message.LParam);
end;

【讨论】:

  • 非常感谢。我相信我现在可以让它发挥作用
  • 顺便说一句,你怎么知道列表是桌面窗口的子级。我怎样才能更多地了解它?这种知识只有实践才能获得?我可以在某处读到它吗?
  • @epro - 我想你能找到的最多记录是列表框控件是一些'ComboLBox'。除此之外,您可能会在这里和那里找到碎片。为了快速检查像这样的易失性弹出窗口(菜单等),我所做的是构建一个所有者绘制的弹出窗口并在绘图代码中放置一个断点。然后你可以冻结窗口并尝试 spy++。不过,这有点微妙,当我还包括消息处理时,此设置有时会设法冻结整个框。否则,如果您可以对窗口进行子类化,那么您可以做任何您想做的事情。不客气!
猜你喜欢
  • 1970-01-01
  • 2022-08-22
  • 2012-01-26
  • 1970-01-01
  • 2015-06-14
  • 2021-02-27
  • 1970-01-01
  • 2021-09-10
  • 1970-01-01
相关资源
最近更新 更多