Well, you can do this using GetComboBoxInfo to get the window handle used for the list, and then move that window. Like this:
type TMyForm = class(TForm) ComboBox1: TComboBox; procedure ComboBox1DropDown(Sender: TObject); protected procedure WMMoveListWindow(var Message: TMessage); message WM_MOVELISTWINDOW; end; .... procedure TMyForm.ComboBox1DropDown(Sender: TObject); begin PostMessage(Handle, WM_MOVELISTWINDOW, 0, 0); end; procedure TMyForm.WMMoveListWindow(var Message: TMessage); var cbi: TComboBoxInfo; Rect: TRect; NewTop: Integer; begin cbi.cbSize := SizeOf(cbi); GetComboBoxInfo(ComboBox1.Handle, cbi); GetWindowRect(cbi.hwndList, Rect); NewTop := ClientToScreen(Point(0, ComboBox1.Top-Rect.Height)).Y; MoveWindow(cbi.hwndList, Rect.Left, NewTop, Rect.Width, Rect.Height, True); end;
I ignored the error checking problem to keep the code simple.
However, it should be warned that this looks pretty terrible because the animation of the drop-down menu is shown. Perhaps you can find a way to disable this.
However, you simply do not need to do anything, because Windows is already doing this for you. Drag the shape to the bottom of the screen and lower the combo. Then you will see a list appear above the combo. Like this:

source share