1

In my extended TComboBox class, I overrided ComboWndProc() procedure handler, but I was not able to detect neither CN_VSCROLL nor WM_VSCROLL messages from the scroll bar of the List (FListHandle).

I basically want to implement an infinite scroll using winapi.
I imagine that, to do what I want, I basically would need to know the track bar position of the scroll so when the track bar touch the line down button I would add more data to strings.

The idea is simple and maybe naive, but I could start from there and see what problems I would have.

Is it possible to do such a thing?

Is there a way to track scroll bar messages from TComboBox?

More importantly:

  • If yes, How?
  • If no, Why?
7
  • Alternatives are welcome too, just saying Commented Mar 5, 2015 at 13:08
  • Surely you need ListWndProc. And I cannot see you getting any CN_XXX messages. I'd expect this to be a pure Win32 window. Commented Mar 5, 2015 at 13:10
  • @DavidHeffernan ListWndProc just calls ComboWndProc. I wondered that, I think those messages never reaches the list handle Commented Mar 5, 2015 at 13:10
  • And what Style is your combo? In case that matters Commented Mar 5, 2015 at 13:14
  • @DavidHeffernan csDropDown Commented Mar 5, 2015 at 13:15

1 Answer 1

4

You can use WM_VSCROLL, to do so you have to subclass the listbox control of the combobox. CN_VSCROLL will not work because the listbox part of the combobox is not a VCL control.

Below example is essentially from this answer of Kobik, included here for the sake of completeness.

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; 
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you so much. I believe I can manage to make it work now
By the way, how did you knew the list is child of the of the desktop window. How can I learn more about it? This kind of knowledge only comes with practice? May I read about it somewhere?
@epro - I guess the most you can find documented is that the listbox control is some 'ComboLBox'. Other than that you may find pieces here and there. What I do to quickly examine volatile popups like this (menu, etc..) is to construct an owner-drawn one and put a breakpoint in drawing code. Then you can freeze the window and try spy++ on it. It's kind of delicate though, when I also include message processing, this setup sometimes manages to freeze the entire box. Otherwise, if you can subclass the window then you can do whatever you want.. You're welcome!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.