Thanks very much for these two - in particular the control version - I will
add it to my list of controls.
I took a slightly different approach in my implementation where I used the
object part of the items list to identify if it was enabloed or disabled
rather than maintain a separate list as you have suggested.

JohnB

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf
Of Jeremy North
Sent: 04 December 2007 00:09
To: Borland's Delphi Discussion List
Subject: Re: Dumb question about ComboBoxes

Here is the component version. If a disabled item is selected then the
ItemIndex is set to -1. You can modify the code to take action accordingly.

unit DisabledCombo;

interface

uses
    StdCtrls
  , Classes
  , Controls
  , Windows
  , Messages
  , Graphics
  ;

type
  TCustomDisabledComboBox = class(TCustomComboBox)
  private
    FDisabledItems: TStrings;
    FShowDisabledFocus: Boolean;
    procedure SetDisabledItems(const Value: TStrings);
    procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;
  protected
    function IsItemDisabled(const AIndex: Integer): Boolean; inline;
    procedure DrawItem(Index: Integer; Rect: TRect; State:
TOwnerDrawState); override;
    property ShowDisabledFocus: Boolean read FShowDisabledFocus write
FShowDisabledFocus default False;
    property DisabledItems: TStrings read FDisabledItems write
SetDisabledItems;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

  TDisabledComboBox = class(TCustomDisabledComboBox)
  published
    property Align;
    property AutoComplete default True;
    property AutoCompleteDelay default 500;
    property AutoDropDown default False;
    property AutoCloseUp default False;
    property BevelEdges;
    property BevelInner;
    property BevelKind default bkNone;
    property BevelOuter;
//    property Style; {Must be published before Items}
    property Anchors;
    property BiDiMode;
    property CharCase;
    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 ItemIndex default -1;
    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 OnCloseUp;
    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 OnMouseEnter;
    property OnMouseLeave;
    property OnSelect;
    property OnStartDock;
    property OnStartDrag;
    property Items; { Must be published after OnMeasureItem }
    property DisabledItems;
    property ShowDisabledFocus;
  end;

procedure Register;

implementation

uses
    SysUtils
  ;

procedure Register;
begin
  RegisterComponents('Samples', [TDisabledComboBox]); end;

{ TCustomDisabledComboBox }

procedure TCustomDisabledComboBox.CNCommand(var Message: TWMCommand); begin
  case Message.NotifyCode of
    CBN_SELCHANGE:
      begin
        // if the user selects a disabled item, clear the selection
        if not IsItemDisabled(ItemIndex) then
        begin
          Text := Items[ItemIndex];
          Click;
          Select;
        end
        else
          ItemIndex := -1;
      end;
  else
    inherited;
  end;
end;

constructor TCustomDisabledComboBox.Create(AOwner: TComponent); begin
  inherited;
  Style := csOwnerDrawFixed;
  FDisabledItems := TStringList.Create;
  FShowDisabledFocus := False;
end;

destructor TCustomDisabledComboBox.Destroy; begin
  FDisabledItems.Free;
  inherited;
end;

procedure TCustomDisabledComboBox.DrawItem(Index: Integer; Rect: TRect;
  State: TOwnerDrawState);
var
  lDrawFlags: Cardinal;
  lStr: string;
begin
  TControlCanvas(Canvas).UpdateTextFlags;
  Canvas.Brush.Style := bsSolid;
  // setup background color
  if (odSelected in State) and not IsItemDisabled(Index) then
    Canvas.Brush.Color := clHighlight
  else
    Canvas.Brush.Color := Color;
  Canvas.FillRect(Rect);
  Canvas.Brush.Style := bsClear;
  // setup font color
  if (odSelected in State) and not IsItemDisabled(Index) then
    Canvas.Font.Color := clHighlightText
  else if IsItemDisabled(Index) then
    Canvas.Font.Color := clGrayText
  else
    Canvas.Font.Color := Font.Color;
  InflateRect(Rect, -2, -2);
  lDrawFlags := DT_LEFT or DT_VCENTER or DT_SINGLELINE or DT_NOPREFIX or
DT_END_ELLIPSIS;
  lStr := Items[Index];
  DrawText(Canvas.Handle, PChar(lStr), Length(lStr), Rect, lDrawFlags);
  // comment this out if you want the focus rect to be draw even when a
  // disabled item has focus
  if (odSelected in State) and IsItemDisabled(Index) and not
ShowDisabledFocus then
  begin
    InflateRect(Rect, 2, 2);
    DrawFocusRect(Canvas.Handle, Rect);
  end;
end;

function TCustomDisabledComboBox.IsItemDisabled(const AIndex: Integer):
Boolean; begin
  result := FDisabledItems.IndexOf(IntToStr(AIndex)) > -1; end;

procedure TCustomDisabledComboBox.SetDisabledItems(const Value: TStrings);
begin
  FDisabledItems.Assign(Value);
end;

end.
_______________________________________________
Delphi mailing list -> [email protected]
http://lists.elists.org/cgi-bin/mailman/listinfo/delphi


_______________________________________________
Delphi mailing list -> [email protected]
http://lists.elists.org/cgi-bin/mailman/listinfo/delphi

Reply via email to