10886

How to make ComboBox drop-down list be *Narrower* than the ComboBox itself

Question:

Is it possible to make a ComboBox Drop-down list be <em>Narrower</em> than the Combobox itself?

There are plenty of examples setting the width using SendMessage(Handle, CB_SETDROPPEDWIDTH, 100, 200);

but the <em>minimum</em> value is taken from the combobox itself, regardless of what is specificed here.

All these examples make it bigger.

Answer1:

Before the drop-down list is to be painted, a <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/bb761360(v=vs.85).aspx" rel="nofollow">WM_CTLCOLORLISTBOX</a> message is issued.

By overriding the combobox WindowProc it is possible to shrink the drop down list width.

The WM_CTLCOLORLISTBOX message is detected and since the message supplies the handle of the list window, we can grab the list bounds and call MoveWindow with a shrinked width.

type TMyForm = class(TForm) ... ComboBox1 : TComboBox; procedure FormCreate(Sender: TObject); ... private { Private declarations } ComboBox1WindowProcORIGINAL : TWndMethod; procedure ComboBox1WindowProc(var Message: TMessage); ... end; procedure TMyForm.ComboBox1WindowProc(var Message: TMessage); var lbr: TRect; begin //drawing the list box with combobox items if Message.Msg = WM_CTLCOLORLISTBOX then begin //list box rectangle GetWindowRect(Message.LParam, lbr); //Shrink window width MoveWindow( Message.LParam, lbr.Left, lbr.Top, 50, // New width lbr.Bottom-lbr.Top, false); end; ComboBox1WindowProcORIGINAL(Message); end; procedure TMyForm.FormCreate(Sender: TObject); begin //attach custom WindowProc for ComboBox1 ComboBox1WindowProcORIGINAL := ComboBox1.WindowProc; ComboBox1.WindowProc := ComboBox1WindowProc; end;

<a href="https://i.stack.imgur.com/41KMq.png" rel="nofollow"><img alt="enter image description here" class="b-lazy" data-src="https://i.stack.imgur.com/41KMq.png" data-original="https://i.stack.imgur.com/41KMq.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" /></a> <a href="https://i.stack.imgur.com/JnPOV.png" rel="nofollow"><img alt="enter image description here" class="b-lazy" data-src="https://i.stack.imgur.com/JnPOV.png" data-original="https://i.stack.imgur.com/JnPOV.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" /></a>

<hr />

You can make a small hack by creating an interposer class. Either put it in a separate unit and declare it after vcl.StdCtrls, or put it in your form unit.

type TComboBox = class(vcl.StdCtrls.TComboBox) private FDropDownWidth : Integer; function GetDropDownWidth : Integer; protected procedure WndProc(var Mess: TMessage); override; public Constructor Create( aOwner: TComponent ); override; property DropDownWidth : Integer read GetDropDownWidth write FDropDownWidth; end; constructor TComboBox.Create(aOwner: TComponent); begin inherited; DropDownWidth := -1; // Default state end; function TComboBox.GetDropDownWidth: Integer; begin if FDropDownWidth = -1 then // Just keep a default state Result := Self.Width else Result := FDropDownWidth; end; procedure TComboBox.WndProc(var Mess: TMessage); var lbr: TRect; begin if Mess.Msg = WM_CTLCOLORLISTBOX then begin //list box rectangle GetWindowRect(Mess.LParam, lbr); //Shrink window width MoveWindow( Mess.LParam, lbr.Left, lbr.Top, DropDownWidth, lbr.Bottom-lbr.Top, false); end else if Mess.Msg = CB_SETDROPPEDWIDTH then DropDownWidth := Mess.WParam; Inherited WndProc(Mess); end;

Either set the drop-down width with cb.Perform(CB_SETDROPPEDWIDTH,newWidth,0); or cb.DropDownWidth := newWidth;

Recommend

  • NULL http headers are passed to the server from Angular2 app
  • WSO2 Endpoint look-up sample
  • NOT NULL constraint failed Django CreateView
  • Delphi filling combobox items from SQL database [closed]
  • How to filter through a table using ng-repeat checkboxes with Angularjs
  • How I can get QMetaObject from just class name?
  • How to read until EOF and print the even/odd numbers entered?
  • split string by char
  • git strategy to have a set of commits limited to a particular branch
  • how to define colormap with absolute values with matplotlib
  • React.default.memo is not a function (React-Native) wrapWithConnect
  • Why does the FOR Clause not work with an alias in SQL Server 2016 with temporal tables?
  • Critical sections in ARM
  • Get full URL inside SignalR hub
  • AWS PHP SDK issue (DynamoDB)
  • Why does `[DllImport]` fail with an entry point of `RtlSecureZeroMemory`, even though it is a well d
  • After updating xdan/datetimepicker from 2.4.0 to 2.5.4 - $.datetimepicker is undefined
  • Sizes calculation with JavaScript and jQuery
  • Automatically change value in sql database based on a given date
  • Permission for an image from Gallery is lost after re-launch
  • candlestick plot from pandas dataframe, replace index by dates
  • Read attribute/value pairs from XML file using Linq
  • Repeatable job for Laravel json api
  • Google TV VideoView playing YouTube rtsp videos
  • readmore button or show/hide for php
  • Send array to next viewcontroller iOs xcode [duplicate]
  • Codeigniniter insert data through models and controller
  • Passing value from popup window to parent form's TextBox
  • Using Service Component Runtime
  • PHP Permalinks.. how to change?
  • What does the “id” field in an Android “Google Play Music” broadcast intent correspond to?
  • How to handle a codeigniter PDF generator