2007. január 26., péntek

How to change the position of the dropdown list of a TComboBox


Problem/Question/Abstract:

I have been able to find out how to increase the width of a combo box drop down so that it is wide enough to read the text. However if my combo box is positioned on the right hand side of a form when there is a particularly wide list the scroll bar and the list gets cut off on the edge of the screen. Is there a way to change the position the dropdown list?

Answer:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, stdctrls, Unit2;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    ComboBox1: TComboBox;
    procedure Button1Click(Sender: TObject);
    procedure ComboBox1DropDown(Sender: TObject);
  private
    { Private declarations }
    procedure WMUser(var msg: TMessage); message WM_USER;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to 20 do
    combobox1.Items.add(StringofChar(Chr(Ord('A') + i), Random(50) + 10));
  combobox1.Perform(CB_SETDROPPEDWIDTH, combobox1.Width * 2, 0)
end;

function EnumProc(wnd: HWND; var wndresult: HWND): BOOL; stdcall;
var
  classname: array[0..63] of Char;
begin
  Result := True;
  GetClassname(wnd, classname, sizeof(classname));
  if SameText(classname, 'ComboLBox') then
  begin
    Result := false;
    wndresult := wnd;
  end;
end;

procedure TForm1.ComboBox1DropDown(Sender: TObject);
var
  wnd: HWND;
  r: Trect;
  w: Integer;
begin
  wnd := 0;
  EnumThreadWindows(GetCurrentThreadID, @EnumProc, integer(@wnd));
  if wnd <> 0 then
  begin
    PostMessage(handle, WM_USER, wnd, 0);
  end
  else
    memo1.lines.add('Window not found');
end;

procedure TForm1.WMUser(var msg: TMessage);
var
  wnd: HWND;
  r: Trect;
  w: Integer;
begin
  wnd := msg.wparam;
  GetWindowRect(wnd, r);
  if r.Right > Screen.width then
  begin
    w := r.right - r.Left;
    MoveWindow(wnd, Screen.Width - w, r.top, w, r.Bottom - r.Top, true);
  end;
  memo1.lines.add(format('Wnd: %x, r: (%d,%d,%d,%d)', [wnd, r.left, r.top, r.right, r.bottom]));
end;

initialization
  randomize;
end.

Nincsenek megjegyzések:

Megjegyzés küldése