Take a TComboBox and put it on a TScrollBox. In the OnMouseWheel event of the TScrollBox, the position of the vertical scroll bar is adjusted as follows:
void __fastcall TForm1::ScrollBox1MouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta,
TPoint &MousePos, bool &Handled)
{
ScrollBox1->VertScrollBar->Position = ScrollBox1->VertScrollBar->Position - WheelDelta;
Handled = true;
}
If the drop-down list of the TComboBox is expanded, and you scroll outside the TComboBox with the mouse wheel, the TComboBox moves, but the drop-down list remains at the previous position.
I found an old-fashioned Windows 10 OS form and the TComboBox there shows the same behavior, so this seems to be default.
A simple way is to set the DroppedDown property of the TComboBox in the OnMouseWheel event to false. However, the TComboBox is not known in the actual application. So you would have to search for a corresponding TComboBox in the control list of the TScrollBox.
Ideally, the behavior should be like the default behavior when you click something outside the TComboBox, which hides the drop-down list. Unfortunately, I couldn't figure out how this is implemented in the VCL.
Do you have an idea how this could be realized?
As you already noted TComboBox closes its dropdown list if it loses focus so you could programmatically switch focus to your ScrollBox for instance using
EDIT: As you have noted in the comment below clicking anywhere outside ComboBox dropped down list closes it.
That is because when TCobmoBox dropdown list is shown it registers mouse capture so that next mouse click message is handled by the dropped down list directly. So if the click occurs inside dropdown list the appropriate list item is selected. If not dropdown list is closed. This even prevents clicking on Close button of your window.
So you could in theory simulate mouse click for instance using using
But simulating user input in this manner is not considered as good practice. Instead it is recommended to use UI automation which might not lead to desired results in this case.
There is another way. You could use OnDropDown event of your combo boxes to store reference to the combo box that has its dropdown list shown in some global variable. Then in MouseScroll event you just use that reference to change DroppedDown property of the specific combo box to false which would then hide its dropdown list.