| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 | unit IEComboBox;{================================================================== Components TIECustomCombobox  /  Version 1.4  / January 2000            TIEComboBox            TIEDriveBox ==================================================================    Description:    ============    TIECustomComboBox is a combobox with variable width of the dropdown list and    provides the additional event OnCloseUp.    TIEComboBox publishes the properties of the class TIECustomComboBox including    the property Align wich might be was forgotten by Borland.    TIEDriveComboBox realizes a selection control for the aviable drives of    the system with icons. The drive icons are taken from the system image    list.    Author:    =======    (c) Ingo Eckel 1999    Sodener Weg 38    65812 Bad Soden    Germany    For detailed documentation and history see the documentation in TIEDriveComboBox.htm.    V1.3:    - Property DisplayStyle changed.{==================================================================}{Required compiler options:}{$A+,B-,X+,H+,P+}interfaceuses  StdCtrls, Controls, Messages, Types, Classes, Graphics;const  IconWidth = 16;type  TIECloseUpEvent = procedure (Sender: TObject; Canceled: Boolean) of object;// =======================================================================// Class TIECustomComboBox// =======================================================================  TIECustomComboBox = class(TCustomComboBox)  private    FDropDownFixedWidth: Integer;    FOnCloseUp: TIECloseUpEvent;    FCanceled: Boolean;    FUseSystemImageList: Boolean;    FSystemImageList: TImageList;    function GetTopIndex: Integer;    procedure SetTopIndex(Value: Integer);    procedure SetUseSystemImageList(Value: Boolean);    procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;  protected    procedure DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState); override;    function GetItemImage(Index: Integer): Integer; virtual;    function GetItemIndent(Index: Integer): Integer; virtual;    function GetItemText(Index: Integer): string;    function GetItemTextEx(Index: Integer; ForList: Boolean): string; virtual;    function ImageList: TImageList; virtual;    procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;    procedure DoCloseUp(Canceled: Boolean); virtual;    procedure DropDown; override;    function GetMaxItemWidth: Integer;    procedure ResetItemHeight;  public    constructor Create(AOwner: TComponent); override;    destructor Destroy; override;    function GetTextWidth(Str: string): Integer;    procedure DoPreloadImages;    property ItemImage[Index: Integer]: Integer read GetItemImage;    property ItemIndent[Index: Integer]: Integer read GetItemIndent;    property ItemText[Index: Integer]: string read GetItemText;    property TopIndex: Integer read GetTopIndex write SetTopIndex;    property UseSystemImageList: Boolean read FUseSystemImageList write SetUseSystemImageList;    property DropDownFixedWidth: Integer read FDropDownFixedWidth write FDropDownFixedWidth default 0;    property OnCloseUp: TIECloseUpEvent read FOnCloseUp write FOnCloseUp;  published  end;// =======================================================================// Class TIEComboBox// =======================================================================  TIEComboBox = class(TIECustomComboBox)  published    property DropDownFixedWidth;    property OnCloseUp;    property Style; {Must be published before Items}    property Align;    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 Items;    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 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;  end;function  GetItemHeight(Font: TFont): Integer;procedure Register;implementationuses  SysUtils, Forms, Dialogs, Imglist, ShellAPI, CommCtrl, Math, Windows, PasTools;procedure Register;begin  RegisterComponents('DriveDir', [TIEComboBox]);end;// =======================================================================// Class TIECustomComboBox// =======================================================================constructor TIECustomComboBox.Create(AOwner: TComponent);begin  inherited Create(AOwner);  FCanceled := True;  FUseSystemImageList := False;  FSystemImageList := nil;end; {TIECustomComboBox.Create}destructor TIECustomComboBox.Destroy;begin  FreeAndNil(FSystemImageList);  inherited;end;procedure TIECustomComboBox.CMFontChanged(var Message: TMessage);begin  inherited;  ResetItemHeight;  RecreateWnd;end; {CMFontChanged}procedure TIECustomComboBox.DoCloseUp(Canceled: Boolean);begin  if Assigned(FOnCloseUp) then    FOnCloseUp(Self, Canceled);end; { DoCloseUp }procedure TIECustomComboBox.DropDown;var  ItemWidth: Integer;begin  {Check to see if DropDownFixed Width > 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 > than 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    ItemWidth := GetMaxItemWidth + ScaleByPixelsPerInch(8);    if Items.Count > DropDowncount then      Inc(ItemWidth, GetSystemMetrics(SM_CXVSCROLL));    Self.Perform(CB_SETDROPPEDWIDTH, ItemWidth, 0);  end;  inherited DropDown;end; {TIECustomComboBox.DropDown}function TIECustomComboBox.GetTextWidth(Str: string): Integer;var  DC: HDC;  SaveFont: HFont;  Size: TSize;begin  DC := GetDC(0);  try    SaveFont := SelectObject(DC, Font.Handle);    GetTextExtentPoint32(DC, PChar(Str), Length(Str), Size);    Result := Size.Cx;    SelectObject(DC, SaveFont);  finally    ReleaseDC(0, DC);  end;end; {TIECustomComboBox.GetTextWidth}function TIECustomComboBox.GetMaxItemWidth: Integer;var  DC: HDC;  SaveFont: HFont;  Size: TSize;  Index: Integer;begin  Result := 0;  DC := GetDC(0);  try    SaveFont := SelectObject(DC, Font.Handle);    for Index := 0 to Items.Count - 1 do    begin      GetTextExtentPoint32(DC, PChar(ItemText[Index]), Length(ItemText[Index]), Size);      if (ImageList <> nil) and (ItemImage[Index] >= 0) then        Inc(Size.Cx, IconWidth + 6);      Inc(Size.Cx, ItemIndent[Index]);      if Size.Cx > Result then Result := Size.Cx;    end;    SelectObject(DC, SaveFont);  finally    ReleaseDC(0, DC);  end;end; {TIECustomComboBox.GetMaxItemWidth}function TIECustomComboBox.GetTopIndex: Integer;begin  Result := Perform(CB_GETTOPINDEX, 0, 0);end; {TIECustomComboBox.GetTopIndex}{$HINTS OFF}procedure TIECustomComboBox.DoPreloadImages;var  Index, Dummy: Integer;begin  for Index := 0 to Items.Count-1 do    Dummy := ItemImage[Index];end;{$HINTS ON}procedure TIECustomComboBox.ResetItemHeight;var  AHeight: Integer;Begin  AHeight := Max(GetItemHeight(Font), 10) + 2;  inherited ItemHeight := AHeight;  if HandleAllocated then  begin    {Set height of list items:}    SendMessage(Handle, CB_SETITEMHEIGHT,  0, Max(AHeight, 12));    {Set height of selection field:}    SendMessage(Handle, CB_SETITEMHEIGHT, -1, AHeight);    {Set height of delphi-control:}    Height := AHeight;  end;end;procedure TIECustomComboBox.SetTopIndex(Value: Integer);begin  if Value <> TopIndex then    Perform(CB_SETTOPINDEX, Value, 0);end; {TIECustomComboBox.SetTopIndex}procedure TIECustomComboBox.CNCommand(var Message: TWMCommand);begin  inherited;  case Message.NotifyCode of    CBN_CLOSEUP:      DoCloseUp(FCanceled);    CBN_SELENDCANCEL:      FCanceled := True;    CBN_SELENDOK:      FCanceled := False;  end;end; {TIECustomComboBox.CNCommand}function GetItemHeight(Font: TFont): Integer;var  DC: HDC;  SaveFont: HFont;  Metrics: TTextMetric;begin  DC := GetDC(0);  try    SaveFont := SelectObject(DC, Font.Handle);    GetTextMetrics(DC, Metrics);    SelectObject(DC, SaveFont);  finally    ReleaseDC(0, DC);  end;  Result := Metrics.tmHeight;end; {GetItemHeight}procedure TIECustomComboBox.DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState);var  Text: string;  Image: Integer;  InList: Boolean;begin  inherited;  if Style = csOwnerDrawFixed then  with Canvas do  begin    FillRect(Rect);    Pen.Color := clWindowText;    // Rect.Top = 3 when we draw selected item in component rect (not in dropdown)    InList := (Rect.Top <> 3);    Text := GetItemTextEx(Index, InList);    if InList then Rect.Left := Rect.Left + ItemIndent[Index];    if ImageList <> nil then    begin      Image := ItemImage[Index];      if Image >= 0 then      begin        ImageList.Draw(Canvas, Rect.Left + 2, Rect.Top, Image);        Rect.Left := Rect.Left + IconWidth + 6;      end        else Rect.Left := Rect.Left + 2;    end      else Rect.Left := Rect.Left + 2;    DrawText(Canvas.Handle, PChar(Text), Length(Text), Rect,      DrawTextBiDiModeFlags(DT_SINGLELINE or DT_VCENTER or DT_NOPREFIX));  end;end;function TIECustomComboBox.GetItemImage(Index: Integer): Integer;begin  Result := -1;end;function TIECustomComboBox.GetItemIndent(Index: Integer): Integer;begin  Result := 0;end;function TIECustomComboBox.GetItemText(Index: Integer): string;begin  Result := GetItemTextEx(Index, True);end;function TIECustomComboBox.GetItemTextEx(Index: Integer; ForList: Boolean): string;begin  Result := Items[Index];end;function TIECustomComboBox.ImageList: TImageList;var  ImageListHandle: HImageList;  FileInfo: TSHFileInfo;begin  if FUseSystemImageList then  begin    if not Assigned(FSystemImageList) then    begin      FSystemImageList := TImageList.Create(Self);      ImageListHandle := SHGetFileInfo('', 0, FileInfo, SizeOf(FileInfo),        SHGFI_SYSICONINDEX or SHGFI_SMALLICON);      if ImageListHandle <> 0 then        with FSystemImageList do        begin          ShareImages  := True;          Handle := ImageListHandle;          DrawingStyle := dsTransparent;        end;    end;    Result := FSystemImageList;  end    else Result := nil;end;procedure TIECustomComboBox.SetUseSystemImageList(Value: Boolean);begin  if FUseSystemImageList <> Value then  begin    if not FUseSystemImageList then    begin      if ImageList <> nil then        raise Exception.Create('ImageList is already created.');    end      else FreeAndNil(FSystemImageList);    FUseSystemImageList := Value;  end;end;initializationend.
 |