How can I make a ComboBox change selection on double-click?

Hi,

I have a Combobox with Style=DropDownList.  I would like to make it so that the user can double-click on the combobox and have it change selection.  The OnDblClick event does not fire if the Style=DropDownList

How can I do this?

It's nice to be able to double-click a combobox and have it toggle the selection.

Thanks!
MP
LVL 2
mikepjAsked:
Who is Participating?
 
bugrogerCommented:
Hi,

Try this TComboBox component.
It's like the normal TComboBox but
the onDlbClick event also will be fired if the
 "Style" is set to "csDropDownList".

GL
 Bug

unit CBDblClick;



interface
uses Messages, Windows, SysUtils, Classes, Controls, Forms, Menus, Graphics,
     StdCtrls;

TYPE
  TComboBoxDblClick = class(TCustomComboBox)
  Private
  protected
    procedure WndProc(var Message: TMessage); override;
    function  MouseOnBtn : Boolean;
  published
    property Style; {Must be published before Items}
    property Anchors;
    property BiDiMode;
    property Color;
    property Constraints;
    property Ctl3D;
    property DragCursor;
    property DragKind;
    property DragMode;
    property DropDownCount;
    property Enabled;
    property Font;
    property ImeMode;
    property ImeName;
    property ItemHeight;
    property MaxLength;
    property ParentBiDiMode;
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property Sorted;
    property TabOrder;
    property TabStop;
    property Text;
    property Visible;
    property OnChange;
    property OnClick;
    property OnContextPopup;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnDrawItem;
    property OnDropDown;
    property OnEndDock;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMeasureItem;
    property OnStartDock;
    property OnStartDrag;
    property Items; { Must be published after OnMeasureItem }
  end;
  Procedure Register;
implementation

Procedure Register;
Begin
 RegisterComponents('Eigene', [TComboBoxDblClick]);
End;

Function  TComboBoxDblClick.MouseOnBtn : Boolean;
Var
 mx, my : Integer;
 cp     : TPoint;

Begin
 Result := FALSE;

 mx := Mouse.CursorPos.x;
 my := Mouse.CursorPos.y;

 cp.x := Self.Left;
 cp.y := self.Top;
 cp := Parent.ClientToScreen(cp);

 cp.x := cp.x + (Self.Width - 18);
 cp.y := cp.y +2;

 IF ( (my >= cp.y) and (my <= cp.y + (Self.ClientHeight -5) ) )AND
    ( (mx >= cp.x) and (mx <= cp.x + 15) )THEN Result := TRUE;
End;

procedure TComboBoxDblClick.WndProc(var Message: TMessage);
Var
 s : string;
begin
  with Message do
    case Msg of
      WM_SIZE:
        { Prevent TWinControl from handling WM_SIZE when adjusting drop-down
          listbox size. }
        if DroppedDown then
        begin
          DefaultHandler(Message);
          Exit;
        end;
      WM_CTLCOLORMSGBOX..WM_CTLCOLORSTATIC:
        begin
          SetTextColor(WParam, ColorToRGB(Font.Color));
          SetBkColor(WParam, ColorToRGB(Brush.Color));
          Result := Brush.Handle;
          Exit;
        end;
      CN_CTLCOLORMSGBOX..CN_CTLCOLORSTATIC:
        if not NewStyleControls and (Style < csDropDownList) then
        begin
          Result := Parent.Brush.Handle;
          Exit;
        end;
      WM_CHAR:
        begin
          if DoKeyPress(TWMKey(Message)) then Exit;
          if ((TWMKey(Message).CharCode = VK_RETURN) or
            (TWMKey(Message).CharCode = VK_ESCAPE)) and DroppedDown then
          begin
            DroppedDown := False;
            Exit;
          end;
        end;
    end;
 if not (csDesigning in ComponentState) then
 Begin
  IF (Message.Msg = WM_LBUTTONDBLCLK)and (not MouseOnBtn) then Self.OnDblClick(Owner);
  IF ((Message.Msg <> WM_LBUTTONDOWN) and (Message.Msg <> WM_LBUTTONDBLCLK))or(MouseOnBtn) then
   inherited WndProc(Message);
 end else inherited WndProc(Message);
end;

end.
0
 
d32coderCommented:
Sounds like you only have 2 options in the list, if so, I recommend this..

Use an Editbox instead...
When it is clicked, the caption will toggle.

If your two options were 'On' and 'Off' ...
In the OnClick or OnDblClick method


procedure Edit1DblClick(sender: TObject);
begin
 if Edit1.Text = 'On' then
   Edit1.Text := 'Off'
 else Edit1.Text := 'On';
end;

Simple.
If you have more than 2 options, let me and I'll show how to skip to the next one without any dropdown,

Don
0
 
mikepjAuthor Commented:
bugroger!

That is a beautiful piece of work & it works great!

Thanks a lot!  (I increased the points to 150 as I see this was much more involved than I had hoped)

MP
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.