I.T. Discussion Community!
-Collapse +Expand
Delphi
Search Delphi Group:

Advanced
-Collapse +Expand Delphi To/From
To/FromCODEGuides
-Collapse +Expand Delphi Store
PRESTWOODSTORE

Prestwood eMagazine

October Edition
Subscribe now! It's Free!
Enter your email:

   ► KBProgrammingDelphi for W...Using Controls   Print This     
 
Delphi Using Controls:
Advanced Delphi: Resize Drop-down List
 
Posted 11 years ago on 12/12/2008 and updated 2/23/2009
Take Away:

To resize the list box of a combobox, you merely need to send the Windows API message: CB_SETDROPPEDWIDTH to the combo box.

KB101673

From the Prestwood Delphi Gazette: Nov 1998 Issue

by Brendan Delumpa, posted by Larry Rutledge

Can I resize the drop-down list of a TComboBox so that I can see the complete text of its items?
There are two ways to approach this. One's quick and dirty, the other's a bit more involved, but is much more reusable (read: it's a component). You can decide which one you want to use. Let's start out with the quick and dirty method, shall we?

To resize the list box of a combobox, you merely need to send the Windows API message: CB_SETDROPPEDWIDTH to the combo box. Using the procedure function to implement the message, your call would be as follows:

ComboBox1.Perform(CB_SETDROPPEDWIDTH, , 0);
   

The best place to put this call would be in the OnDropDown method of the combo box. Here's how I implemented it:

procedure TForm1.ComboBox1DropDown(Sender: TObject);
begin
  // Set the width of the list to 200
  ComboBox1.Perform(CB_SETDROPPEDWIDTH, 200, 0);
end;
   

Pretty straight-forward, right? But there's one glaring weakness with this methodology: Your string items almost invariably will be different lengths, so the size you set may not be big enough. In that case, you have to loop through each item in the list and figure what the biggest one is, then set the size based on that.

I could give you the code that does that - in fact, you could probably figure that part out yourself. But think about this a moment, this would be pretty useful in all your applications that use combo boxes, and to have to cut and paste code would be a real chore everytime you wanted to implement this behavior. Do you see what I'm getting at? Right. Let's build a component.

The comments pretty much explain all the logic behind the component, so I won't bore you with those details. But you should note that I implemented both sizing behaviors in the code through the DropDownFixedWidth property. If the value of DropDownFixedWidth is greater than 0, then the component will size its list box to the size set for the property. If the value is zero, then it'll dynamically size to the largest string in the Items list. I did this to provide greater flexibility when using the component. While I'd personally just let the component decide the size of the list box, there just might be times when I'd want to set the width explicitly. With this component, I can do that.

There's a weakness in the design of this code, though. Can you figure it out? Install the component, drop it onto a new test application and run it. Read no further until you've done that'.

Flawed Design?
If you haven't figured it out, place the component near the right edge of the form. Run your program again, and drop down the list. It gets cut off. For time's sake, I haven't even researched how to move the list box to accommodate form alignment of the combo box. If you figure it out, please let me know. I'll add your solution to this article and put your name in lights! Well, that's it for now!

To download the source code visit the file repository web-site.

{======================================================
 Enhanced TComboBox - Copyright ' 1998 Brendan V. Delumpa

 With this component, you have two ways to resize the
 drop-down list. The first way is to directly set the
 DropDownFixedWidth property to some integer value
 greater than zero. The second way involves leaving
 the DropDownFixedValue property at 0, and the list
 will automatically be sized to the longest string.
 ========================================================}
unit EnhCombo;

interface

uses
  Windows, Messages, SysUtils, Classes, 
  Graphics, Controls, Forms, Dialogs, 
  StdCtrls;

type
  TEnhCombo = class(TComboBox)
  private
    FItemWidth : Integer;
    FDropDownFixedWidth : Integer;

    procedure SetDropDownFixedWidth(
               const Value : Integer);
    function GetTextWidth(S : String) : 
             Integer;
  protected
    procedure DropDown; override;
  public
    constructor Create(AOwner : TComponent); 
                override;
    property ItemWidth : Integer 
             read FItemWidth 
            write FItemWidth;
  published
    property DropDownFixedWidth : Integer 
             read FDropDownFixedWidth 
            write FDropDownFixedWidth;
  end;

procedure Register;

implementation

constructor TEnhCombo.Create(AOwner : 
                             TComponent);
begin
  inherited Create(AOwner);
end;

procedure TEnhCombo.DropDown;
var
  I : Integer;

begin
  inherited DropDown;
  ItemWidth := 0;

  { Check to see if DropDownFixedWidth > 0. 
    Then just set the width of the list box. 
    Otherwise, loop through the items and set 
    the width of the list box to 8 pixels > 
    then the widest string to buffer the 
    right side. Anything less than 8 for some 
    reason touches the end of the item on 
    high-res monitor settings.}

if (FDropDownFixedWidth > 0) then
    Self.Perform(CB_SETDROPPEDWIDTH, 
                 FDropDownFixedWidth, 0)
  else
  begin
    for I := 0 to Items.Count - 1 do
      if (GetTextWidth(Items[I]) > ItemWidth) then
        ItemWidth := GetTextWidth(Items[I]) + 8;
    Self.Perform(CB_SETDROPPEDWIDTH, ItemWidth, 0);
  end;
end;

function TEnhCombo.GetTextWidth(S : String) : Integer;
begin
  result := TForm(Owner).Canvas.TextWidth(S);
end;

procedure TEnhCombo.SetDropDownFixedWidth(const Value : Integer);
begin
  FDropDownFixedWidth := Value;
end;

procedure Register;
begin
  RegisterComponents('BD', [TEnhCombo]);
end;

end.

Comments

0 Comments.
Share a thought or comment...
 
Write a Comment...
...
Sign in...

If you are a member, Sign In. Or, you can Create a Free account now.


Anonymous Post (text-only, no HTML):

Enter your name and security key.

Your Name:
Security key = P1212A1
Enter key:
Article Contributed By Larry J. Rutledge :
I worked for Prestwood Software as a Delphi developer from 1997 through 2002. During that time I enjoyed working with Mike Prestwood and the other developers at Prestwood.
Visit Profile

 KB Article #101673 Counter
7407
Since 12/12/2008

Follow PrestwoodBoards on: 


©1995-2019 PrestwoodBoards  [Security & Privacy]
Professional IT Services: Coding | Websites | Computer Tech