加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 我可以以编程方式设置ComboBox下拉列表的位置吗?

发布时间:2020-12-15 10:04:25 所属栏目:大数据 来源:网络整理
导读:普通的Windows ComboBox(csDropDown或csDropDownList样式)将在其下方打开其下拉列表,如果下方没有空格,则在组合上方打开.我可以控制此列表的位置(至少按Y坐标)吗? 解决方法 发布将正确显示下拉列表动画的代码示例,并强制显示ComboBox1上方的下拉列表.这个代
普通的Windows ComboBox(csDropDown或csDropDownList样式)将在其下方打开其下拉列表,如果下方没有空格,则在组合上方打开.我可以控制此列表的位置(至少按Y坐标)吗?

解决方法

发布将正确显示下拉列表动画的代码示例,并强制显示ComboBox1上方的下拉列表.这个代码子类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,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,R.Left,R.Top - DY,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;

笔记:

>我完全同意David和其他人的意见,这对于改变TComboBox的这种特定默认行为是一个坏主意. OP尚未回应为什么他想要这样的行为.>上面的代码是用D5 / XP测试的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读