ComboBox Windows thông thường (csDropDown
hoặc csDropDownList
kiểu) sẽ mở danh sách thả xuống của nó ngay bên dưới hoặc, nếu không có khoảng trống bên dưới, phía trên kết hợp. Tôi có thể kiểm soát vị trí của danh sách này (ít nhất theo tọa độ Y) không?Tôi có thể lập trình thiết lập vị trí danh sách thả xuống của ComboBox không?
Trả lời
Đăng một ví dụ mã mà sẽ hiển thị danh sách phim hoạt hình thả xuống một cách chính xác và sẽ buộc hiển thị danh sách thả xuống ở trên ComboBox1
. mã này lớp con 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;
Ghi chú:
- Tôi hoàn toàn đồng ý với David, và những người khác rằng đây là một ý tưởng tồi để thay đổi hành vi mặc định cụ thể này cho
TComboBox
. OP chưa trả lời lý do tại sao ông ấy muốn có hành vi như vậy. - Mã ở trên đã được thử nghiệm với D5/XP.
Đã thử nghiệm thành công, cảm ơn bạn! – Andrew
Vâng, bạn có thể thực hiện việc này bằng cách sử dụng GetComboBoxInfo
để có được xử lý đối với cửa sổ được sử dụng cho danh sách và sau đó di chuyển cửa sổ đó. Như thế này:
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;
Tôi đã bỏ qua vấn đề kiểm tra lỗi để giữ mã đơn giản.
Tuy nhiên, được cảnh báo rằng có vẻ khá khủng khiếp vì hoạt ảnh thả xuống vẫn được hiển thị. Có lẽ bạn có thể tìm cách để vô hiệu hóa điều đó.
Tuy nhiên, bạn chỉ đơn giản là không cần phải làm bất cứ điều gì như thế này bởi vì Windows đã làm điều đó cho bạn. Kéo biểu mẫu xuống cuối màn hình và thả xuống combo của bạn. Sau đó, bạn sẽ thấy danh sách xuất hiện phía trên combo. Như thế này:
Được thử nghiệm trong XP với D5. mã này không hoạt động đối với tôi. 'cbi.hwndList' không được di chuyển. nó mở và đóng ngay lập tức. – kobik
@kobik Tuy nhiên, một lý do khác không làm điều này. Tôi hy vọng vấn đề là với XP chứ không phải là D5. Bạn có thể cần phải chuyển đổi hành vi cho các phiên bản hệ điều hành khác nhau. Không bao giờ là một kế hoạch tốt. –
Tôi đồng ý 100%. điều này có lẽ có thể được thực hiện bằng cách gắn kết với 'GWL_WNDPROC' và xử lý' WM_SIZE', nhưng hành vi này quá bất ngờ đến nỗi tôi hoàn toàn sẽ bỏ ý tưởng này. chỉ là một bình luận bên, tôi nghĩ rằng bằng cách sử dụng 'GetComboBoxInfo' là tốt hơn so với CB_GETCOMBOBOXINFO (xem bình luận liên quan đến tai nạn trên msdn). – kobik
- 1. Danh sách thả xuống Combobox
- 2. ASP.NET - Kiểm soát danh sách thả xuống postback lập trình
- 3. Thiết lập chiều cao thả xuống của một combobox trong WPF
- 4. Lập trình thiết lập vị trí mô phỏng iphone
- 5. Danh sách thả xuống QComboBox - thiết lập kiểu mục đã chọn
- 6. Lập trình thiết lập ComboBox SelectedItem trong WPF (3.5sp1)
- 7. DDMS không thể gửi vị trí tới trình giả lập
- 8. Làm thế nào tôi có thể thiết lập lại một NSSearchField ca cao lập trình?
- 9. WPF - Combobox SelectedItem không được thiết lập?
- 10. TextField() Thiết lập vị trí dấu nháy
- 11. Combobox của AJAX ASP.NET - Không thể thay đổi một cách có lập trình mục đã chọn
- 12. Vị trí thiết lập Android của scrollbox hortizontal
- 13. Làm thế nào để thiết lập vị trí của "JOptionPane.showMessageDialog"
- 14. android sửa chữa giả lập địa là không có khả năng thiết lập gps vị trí
- 15. Danh sách thả xuống thả xuống Nguồn dữ liệu
- 16. JavaScript 'có thể chỉnh sửa' - Nhận/Thiết lập Vị trí của Người Chăm sóc
- 17. Có mẫu nào tôi có thể sử dụng để chỉnh sửa danh sách thả xuống trong ứng dụng MVC3 không?
- 18. KendoUI Đặt chiều rộng của danh sách thả xuống
- 19. Làm thế nào để thiết lập một mục danh sách thả xuống như được chọn trong ASP.NET?
- 20. WPF: Thả xuống của một Combobox highlightes văn bản
- 21. Điền một danh sách thả xuống dựa trên việc chọn danh sách thả xuống khác
- 22. Điền vào danh sách thả xuống khi lựa chọn một danh sách thả xuống khác
- 23. Chọn lọc có lập trình trong WPF ComboBox
- 24. Không thể thoát ra khỏi danh sách thả xuống Winforms danh sách dữ liệu
- 25. Tôi làm cách nào để tạo danh sách thả xuống có thể chỉnh sửa trong HTML?
- 26. Làm thế nào để thiết lập vị trí văn bản xuống dưới trong TextField
- 27. Danh sách thả xuống không phải bảng Rails
- 28. cách kích hoạt danh sách thả xuống. Selectedindexchanged event programmatically
- 29. Thả xuống Combobox bên trong datagridview
- 30. Làm thế nào để thiết lập tràn trong danh sách thả xuống bootstrap twitter với menu con?
Chỉ cần tự hỏi: tại sao? Điều gì trong hành vi mặc định không theo ý thích của bạn? –
@MarjanVenema Nhà thiết kế của chúng tôi muốn cải thiện khả năng sử dụng cho combobox của chủ sở hữu – Andrew