Zwykły styl Windows ComboBox (csDropDown
lub csDropDownList
) otworzy jego listę rozwijaną tuż poniżej lub, jeśli nie ma wolnego miejsca poniżej, nad kombinacją. Czy mogę kontrolować pozycję tej listy (przynajmniej przez współrzędną Y)?Czy mogę programowo ustawić pozycję listy rozwijanej ComboBox?
Odpowiedz
zamieszczaniu przykład kodu, który pokaże rozwijaną listę animację poprawnie i zmusi pokazujący listy rozwijanej powyżej ComboBox1
. Ten kod podklas ComboBox hwndList
:
TForm1 = class(TForm)
ComboBox1: TComboBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FComboBoxListDropDown: Boolean;
FComboBoxListWnd: HWND;
FOldComboBoxListWndProc, FNewComboBoxListWndProc: Pointer;
procedure ComboBoxListWndProc(var Message: TMessage);
end;
....
procedure TForm1.FormCreate(Sender: TObject);
var
Info: TComboBoxInfo;
begin
ZeroMemory(@Info, SizeOf(Info));
Info.cbSize := SizeOf(Info);
GetComboBoxInfo(ComboBox1.Handle, Info);
FComboBoxListWnd := Info.hwndList;
FNewComboBoxListWndProc := MakeObjectInstance(ComboBoxListWndProc);
FOldComboBoxListWndProc := Pointer(GetWindowLong(FComboBoxListWnd, GWL_WNDPROC));
SetWindowLong(FComboBoxListWnd, GWL_WNDPROC, Integer(FNewComboBoxListWndProc));
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
SetWindowLong(FComboBoxListWnd, GWL_WNDPROC, Integer(FOldComboBoxListWndProc));
FreeObjectInstance(FNewComboBoxListWndProc);
end;
procedure TForm1.ComboBoxListWndProc(var Message: TMessage);
var
R: TRect;
DY: Integer;
begin
if (Message.Msg = WM_MOVE) and not FComboBoxListDropDown then
begin
FComboBoxListDropDown := True;
try
GetWindowRect(FComboBoxListWnd, R);
DY := (R.Bottom - R.Top) + ComboBox1.Height + 1;
// set new Y position for drop-down list: always above ComboBox1
SetWindowPos(FComboBoxListWnd, 0, R.Left, R.Top - DY , 0, 0,
SWP_NOOWNERZORDER or SWP_NOZORDER or SWP_NOSIZE or SWP_NOSENDCHANGING);
finally
FComboBoxListDropDown := False;
end;
end;
Message.Result := CallWindowProc(FOldComboBoxListWndProc,
FComboBoxListWnd, Message.Msg, Message.WParam, Message.LParam);
end;
Uwagi:
- I całkowicie zgadzam się z Dawidem, a inni, że jest to zły pomysł, aby zmienić to domyślne zachowanie specyficznego dla
TComboBox
. OP jeszcze nie odpowiedział na pytanie, dlaczego chciał takie zachowanie. - Powyższy kod został przetestowany z D5/XP.
Testowany pomyślnie, dziękuję! – Andrew
Możesz to zrobić, używając GetComboBoxInfo
, aby uzyskać uchwyt do okna użytego na liście, a następnie przenieść to okno. W ten sposób:
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;
Zignorowałem kwestię sprawdzania błędów, aby zachować prosty kod.
Należy jednak pamiętać, że wygląda to dość okropnie, ponieważ animacja rozwijana jest nadal wyświetlana. Być może znajdziesz sposób, aby to wyłączyć.
Po prostu nie trzeba robić nic takiego, ponieważ system Windows już to robi. Przeciągnij formularz na dół ekranu i upuść kombi. Następnie zobaczysz listę wyświetloną nad kombinacją. Tak:
Testowany w XP z D5. ten kod nie działa dla mnie. 'cbi.hwndList' nie jest przenoszony. natychmiast się otwiera i zamyka. – kobik
@kobik Kolejny powód, żeby tego nie robić. Oczekuję, że problem dotyczy raczej XP niż D5. Prawdopodobnie musisz zmienić zachowanie dla różnych wersji systemu operacyjnego. Nigdy dobrego planu. –
Zgadzam się w 100%. można to prawdopodobnie zrobić przez zahaczenie do 'GWL_WNDPROC' i obsługę' WM_SIZE', ale zachowanie jest tak nieoczekiwane, że całkowicie zrzuciłem ten pomysł. tylko komentarz boczny, myślę, że używając 'GetComboBoxInfo' jest lepszy niż CB_GETCOMBOBOXINFO (patrz komentarz dotyczący awarii na msdn). – kobik
- 1. Jak wybrać pozycję listy rozwijanej według wartości programowo
- 2. Jak zmienić rozmiar listy rozwijanej combobox?
- 3. Jak zmienić kolor tła combobox (nie tylko z rozwijanej listy)
- 4. Spinner - jak ustawić obramowanie wokół listy rozwijanej?
- 5. WPF: rozwijanej combobox highlightes tekst
- 6. jak ustawić domyślną wartość kontrolki listy rozwijanej?
- 7. Czy można programowo ukryć konkretną pozycję listy radiobuttonlist?
- 8. dodać pozycję do listy rozwijanej w html przy użyciu javascript
- 9. Jak filtrować opcje listy rozwijanej za pomocą innej rozwijanej listy
- 10. Jak ustawić wysokość listy rozwijanej i jak wyświetlić listę listy rozwijanej zawsze wyświetlać w dół?
- 11. Czy mogę ustawić android: layout_toLeftOf programowo?
- 12. Open ComboBox DropDown programowo
- 13. Jak mogę dodać dodatkowe pola atrybutów do listy rozwijanej asp.net
- 14. Rozszerzanie wiersza grupy programowo w rozwijanej liście
- 15. Automatyczne przewijanie listy rozwijanej WPF podczas przeciągania
- 16. Zakrętarka paska narzędzi Android wybranego elementu, podtytułu i listy rozwijanej
- 17. IBInspectable Tworzenie listy rozwijanej i lepszej organizacji
- 18. Jak mogę ustawić i uzyskać wartość listy rozwijanej w siatce w Kendo UI MVC?
- 19. Jak ustawić pozycję przewijania do góry widoku listy
- 20. Usuń pozycję z listy
- 21. Rozwijanie listy rozwijanej nie działa
- 22. KendoUI Ustaw szerokość rozwijanej listy
- 23. Czyszczenie rozwijanej listy w C#
- 24. Jak ustawić programowo programowo?
- 25. React-bootstrap jak uchwycić wartość listy rozwijanej
- 26. Jak wysłać wybraną pozycję z listy rozwijanej kątowe-ui z powrotem do kątowego kontrolera
- 27. Ustawianie szerokości listy rozwijanej w Bootstrap 3.0
- 28. Combobox ASP.NET AJAX - Nie można programowo zmienić wybranego elementu
- 29. Jak ustawić pozycję okna dialogowego?
- 30. Dostosuj pozycję obrazu stylu listy?
Zastanawiasz się: dlaczego? Co w domyślnym zachowaniu nie jest do twoich upodobań? –
@MarjanVenema Nasz projektant chce wprowadzić pewne ulepszenia użyteczności dla właściciela-remisu combobox – Andrew