unit SRVComboBox;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  SRVControl, SRVEdit, ImgList, StdCtrls, SRVTypeItems, SRVSBar, SRVSkinManager;

type
  TSRVCustomComboBox = class(TSRVEditControl)
  private
    { Private declarations }
    CanUpdateEdit : Boolean;
    FScrollBar : TSRVScrollBar;

    isEditMouswDown : Boolean;
    isResizeHints : Boolean;
    isUpdateAutoText : Boolean;
    isMouseDown : Boolean;
    lockUpdate : Integer;
    FirstItem : Integer;
    FListMarginWidth : Integer;
    FListMarginHeight : Integer;
    LockChangeCount : Integer;
    MouseMoveIndex : Integer;
    LBVisible : Boolean;
    LBHeight : Integer;
    FOnEditHints : TSRVEditHintsEvent;
  protected
    { Protected declarations }
    Buffer : TBitmap;
    FSorted : Boolean;
    FHideSelection : Boolean;
    FOption : TSRVCBOptions;
    FRestrictListHeight : Boolean;
    FDoubleBuffered : Boolean;
    FAutoComplete : Boolean;
    FAutoDropDown : Boolean;
    FCanvas : TCanvas;
    FStyle: TComboBoxStyle;
    FDropingDown: Boolean;
    FDropDownHints: Integer;
    FOnChange: TNotifyEvent;
    FOnDropDown: TNotifyEvent;
    FOnDrawItem: TDrawItemEvent;
    FOnMeasureItem: TMeasureItemEvent;
    FCanvasList: TCanvas;
    FItems : TSRVCBoxItemCollection;
    FUseItemFontNames : Boolean;
    FColor : TColor;
    FSelectedItemBorderColor : TColor;
    FSelectedItemBackColor : TColor;
    FSelectedItemTextColor : TColor;
    FHotItemBorderColor : TColor;
    FHotItemBackColor : TColor;
    FHotItemTextColor : TColor;
    FHintsSkinSchemeIndex : Integer;
    FHintsScrollBarSkinSchemeIndex : Integer;
    FHintsItemSkinSchemeIndex : Integer;

    FAutoSize: Boolean;
    FImageList: TCustomImageList;
    FItemIndex : Integer;
    FItemHeight : Integer;
    FItemWidth : Integer;
    FDropDownCount : Integer;
    isMouseMove : Boolean;
    IsByse : Boolean;
    procedure CBSetItemIndex(Value : Integer);
    procedure CBListClose(Sender: TObject; var Action: TCloseAction);
    function GetScrollBarHeight : Integer;
    procedure HookOnChange(Sender: TObject);
    procedure HookOnClick(Sender: TObject);
    procedure HookOnKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure HookOnExit(Sender: TObject);
    function GetSelLength: Integer; override;
    procedure UpdateAutoText;
    procedure CheckOpenTree(Value: Integer);
    procedure ItemHint(Sender : TControl; Index : Integer);

    function GetText : String;
    function GetCharCase : TSRVEditCharCase;
    function GetReadOnly : Boolean;
    function GetMaxLength : Integer;
    function GetModified: Boolean;
    function GetFont : TFont;

    procedure SetSorted(Value: Boolean);
    procedure SetHideSelection(Value: Boolean);
    procedure SetAutoDropDown(Value: Boolean);
    procedure SetAutoComplete(Value: Boolean);
    procedure SetAutoSize(Value: Boolean); reintroduce;
    procedure SetFont(Value: TFont);
    procedure SetStyle(Value: TComboBoxStyle);
    procedure SetItemHeight(Value: Integer);
    procedure SetItemWidth(Value: Integer);
    procedure SetMaxLength(Value: Integer);
    procedure SetItemIndex(Value: Integer);
    procedure SetColor(Value: TColor);
    procedure SetImageList(Value: TCustomImageList);
    procedure SetText(Value: String);
    procedure SetCharCase(Value: TSRVEditCharCase);
    procedure SetReadOnly(Value: Boolean);
    procedure SetModified(Value: Boolean);
    procedure SetUseItemFontNames(const Value : Boolean);
    procedure SetSelectedItemBorderColor(const Value : TColor);
    procedure SetSelectedItemBackColor(const Value : TColor);
    procedure SetSelectedItemTextColor(const Value : TColor);
    procedure SetOnEditHints(const Value : TSRVEditHintsEvent);
    procedure SetDropDownHints(const Value: Integer);
    procedure SetSkinManager(Value : TSRVSkinManager);
    procedure SetItemSkinSchemeIndex(Value : Integer);
    procedure SetSkinSchemeIndex(Value : Integer);
    procedure SetScrollBarSkinSchemeIndex(Value : Integer);
    procedure SetHintsSkinSchemeIndex(Value : Integer);
    procedure SetHintsScrollBarSkinSchemeIndex(Value : Integer);
    procedure SetHintsItemSkinSchemeIndex(Value : Integer);
    procedure SetDoubleBuffered(Value: Boolean);
    procedure SetRestrictListHeight(Value: Boolean);
    procedure SetOption(Value: TSRVCBOptions);
    procedure SetListMarginWidth(Value : Integer);
    procedure SetListMarginHeight(Value : Integer);

    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure WMDblClick(var Message: TWMMouse); message WM_LBUTTONDBLCLK;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    function  DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint) : Boolean; override;
    procedure WMRepaintControl(var Message: TMessage); message WM_REPAINT_CONTROL;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
    procedure WMSetFocus(var Message: TMessage); message WM_SETFOCUS;
    procedure WMKillFocus(var Message: TMessage); message WM_KILLFOCUS;
    procedure WMGetDlgCode(var Message: TMessage); message WM_GETDLGCODE;
    procedure Loaded; override;
    procedure HookOnAppend(Sender: TObject);
    procedure HookOnModify(Sender: TObject);
    procedure HookOnRemove(Sender: TObject);
    procedure HookOnScroll(Sender: TObject; ScrollCode: TScrollCode;
      var ScrollPos: Integer);
    procedure UpdateListBox(ACanvas : TCanvas; ARect : TRect);
    function GetItemHeight(Index : Integer) : Integer;
    function GetItemWidth : Integer;
    procedure LBMouseMove(Shift: TShiftState; X, Y: Integer);
    procedure LBMouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer);
    procedure LBMouseWheel(Shift: TShiftState;
      WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
    procedure DrawButton(Canvas : TCanvas; r : TRect);
    procedure ResizeCB;
    procedure ResizeLB;
    procedure UpdateBuffer(Canvas : TCanvas);
    function GetButtonHeight : Integer;
    function CalculateShowItemCount(FirstItem, OffY, Height : Integer) : Integer;
    function CalculateDrawItemCount(FirstItem, OffY, Height : Integer) : Integer;
    function CalculateItemCount : Integer;
    function CalculateItemsHeight : Integer;
    function CalculateItemsHeightTo(FirstIndex, ItemCount : Integer) : Integer;
    function CalculateItemCountToHeight(Height : Integer) : Integer;
    function CalculateDropItemCount(FirstItem, OffY, Height : Integer) : Integer;
    function GetItem(Position : Integer) : Integer;
    function GetPosition(ItemIndex : Integer) : Integer;
    procedure QsString(var PItems : array of TSRVCBoxItem; Count : Integer);
    procedure FormHintsClose(Sender: TObject; FormWidth, FormHeight : Integer; var NewText : String);
  public
    { Public declarations }
    Edit: TSRVEdit;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function  GetCaretPos: TPoint; override;
    function  GetCaretHeight: Integer; override;
    function  GetSelected: Boolean; override;
    procedure Invalidate; override;
    procedure LockChange;
    procedure UnlockChange;
    procedure BeginUpdate;
    procedure EndUpdate;
    function CBFocused: Boolean;
    function Focused: Boolean; override;
    function IndexOf(Value : String) : Integer;
    function GetNextItem(Index, Delta : Integer; isMouse : Boolean) : Integer;
    function GetPriorItem(Index, Delta : Integer; isMouse : Boolean) : Integer;
    function ItemHasChild(Index : Integer) : Boolean;
    function ItemHasParent(Index : Integer) : Boolean;
    function GetParent(Index : Integer) : Integer;
    procedure AppendStrings(List : TStrings; UseIndent: Boolean);
    function AppendItem(Text : string;
                        ImageIndex, SelectedImageIndex, Indent : Integer;
                        Enabled : Boolean; Style: TFontStyles;
                        Color, BackColor : TColor; FontName : TFontName;
                        Expanded : Boolean; Option : TSRVItemOptions) : TSRVCBoxItem;
    function InsertItem(Index : Integer; Text : string;
                        ImageIndex, SelectedImageIndex, Indent : Integer;
                        Enabled : Boolean; Style: TFontStyles;
                        Color, BackColor : TColor; FontName : TFontName;
                        Expanded : Boolean; Option : TSRVItemOptions) : TSRVCBoxItem;
    procedure DeleteItem(Index : Integer);
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    property ScrollBar : TSRVScrollBar read FScrollBar;
    property UseItemFontNames : Boolean read FUseItemFontNames write SetUseItemFontNames default False;
    property ImageList: TCustomImageList read FImageList write SetImageList;
    property DropDownCount: Integer read FDropDownCount write FDropDownCount default 5;
    property ItemHeight: Integer read FItemHeight write SetItemHeight default 20;
    property ItemWidth: Integer read FItemWidth write SetItemWidth default 0;
    property ItemIndex: Integer read FItemIndex write SetItemIndex default -1;
    property MaxLength: Integer read GetMaxLength write SetMaxLength default 0;
    property Style: TComboBoxStyle read FStyle write SetStyle default csDropDown;
    property Items : TSRVCBoxItemCollection read FItems write FItems;
    property ListMarginWidth: Integer read FListMarginWidth write SetListMarginWidth default 3;
    property ListMarginHeight: Integer read FListMarginHeight write SetListMarginHeight default 2;
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
    property OnDropDown: TNotifyEvent read FOnDropDown write FOnDropDown;
    property OnDrawItem: TDrawItemEvent read FOnDrawItem write FOnDrawItem;
    property OnMeasureItem: TMeasureItemEvent read FOnMeasureItem write FOnMeasureItem;
    property OnEditHints : TSRVEditHintsEvent read FOnEditHints write SetOnEditHints;
    property TabStop default True;
    property Canvas : TCanvas read FCanvas;
    property Width default 80;
    property Height default 20;
    property Color : TColor read FColor write SetColor default clWindow;
    property Text : string read GetText write SetText;
    property CharCase: TSRVEditCharCase read GetCharCase write SetCharCase default srvecNormal;
    property DropDownHints: Integer read FDropDownHints write SetDropDownHints default 10;
    property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
    property Modified: Boolean read GetModified write SetModified;
    property AutoSize: Boolean read FAutoSize write SetAutoSize default True;
    property Font: TFont read GetFont write SetFont;
    property HotItemBorderColor : TColor read FHotItemBorderColor write FHotItemBorderColor default clSilver;
    property HotItemBackColor : TColor read FHotItemBackColor write FHotItemBackColor default clBackground;
    property HotItemTextColor : TColor read FHotItemTextColor write FHotItemTextColor default clWhite;
    property SelectedItemBorderColor : TColor read FSelectedItemBorderColor write SetSelectedItemBorderColor default clSilver;
    property SelectedItemBackColor : TColor read FSelectedItemBackColor write SetSelectedItemBackColor default clHighlight;
    property SelectedItemTextColor : TColor read FSelectedItemTextColor write SetSelectedItemTextColor default clHighlightText;
    property AutoComplete : Boolean read FAutoComplete write SetAutoComplete default True;
    property AutoDropDown : Boolean read FAutoDropDown write SetAutoDropDown default False;
    property Sorted : Boolean read FSorted write SetSorted default False;
    property HideSelection : Boolean read FHideSelection write SetHideSelection default True;
    property SkinManager : TSRVSkinManager read FSkinManager write SetSkinManager;
    property ScrollBarSkinSchemeIndex : Integer read FScrollBarSkinSchemeIndex write SetScrollBarSkinSchemeIndex default 0;
    property ItemSkinSchemeIndex : Integer read FItemSkinSchemeIndex write SetItemSkinSchemeIndex default 0;
    property SkinSchemeIndex : Integer read FSkinSchemeIndex write SetSkinSchemeIndex default 0;
    property HintsSkinSchemeIndex : Integer read FHintsSkinSchemeIndex
      write SetHintsSkinSchemeIndex default 0;
    property HintsScrollBarSkinSchemeIndex : Integer read FHintsScrollBarSkinSchemeIndex
      write SetHintsScrollBarSkinSchemeIndex default 0;
    property HintsItemSkinSchemeIndex : Integer read FHintsItemSkinSchemeIndex
      write SetHintsItemSkinSchemeIndex default 0;
    property DoubleBuffered : Boolean read FDoubleBuffered write SetDoubleBuffered default False;
    property RestrictListHeight : Boolean read FRestrictListHeight write SetRestrictListHeight default True;
    property Option : TSRVCBOptions read FOption write SetOption default [srvcbQuickKeySelect];

  published
    { Published declarations }
  end;

  TSRVComboBox = class(TSRVCustomComboBox)
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
  published
    { Published declarations }
    property SkinManager;
    property SkinSchemeIndex;
    property ScrollBarSkinSchemeIndex;
    property ItemSkinSchemeIndex;
    property ButtonSkinSchemeIndex;
    property EditSkinSchemeIndex;
    property HintsSkinSchemeIndex;
    property HintsScrollBarSkinSchemeIndex;
    property HintsItemSkinSchemeIndex;
    property Style;
    property AutoSize;
    property Anchors;
    property Align;
    property Hint;
    property Enabled;
    property Color;
    property Width;
    property Height;
    property PopupMenu;
    property AutoComplete;
    property AutoDropDown;
    property Sorted;
    property HideSelection;
    property Option;
    property HotItemBorderColor;
    property HotItemBackColor;
    property HotItemTextColor;
    property SelectedItemBorderColor;
    property SelectedItemBackColor;
    property SelectedItemTextColor;
    property EnabledBorderColor;
    property DisabledBorderColor;
    property MouseInBorderColor;
    property FocusedBorderColor;
    property UseItemFontNames;
    property ListMarginWidth;
    property ListMarginHeight;
    property ShowHint;
    property Text;
    property Visible;
    property DrawOnPrint;
    property ImageList;
    property DoubleBuffered;
    property RestrictListHeight;
    property DropDownCount;
    property ItemHeight;
    property ItemWidth;
    property ItemIndex;
    property MaxLength;
    property Items;
    property Font;
    property DropDownHints;
    property TabStop;
    property TabOrder;
    property OnChange;
    property OnDropDown;
    property OnDrawItem;
    property OnMeasureItem;
    property OnClick;
    property OnMouseMove;
    property OnMouseDown;
    property OnMouseUp;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnEnter;
    property OnExit;
    property OnDblClick;
    {$IFDEF RICHVIEWDEF5}
    property OnContextPopup;
    {$ENDIF}
    property OnMouseEnter;
    property OnMouseLeave;
  end;

implementation

uses Math, SRVCBDropList;

{-----------------------------------------------------------------------}
procedure TSRVCustomComboBox.DrawButton(Canvas : TCanvas; r : TRect);
var
     state : Integer;
begin
  if isMouseDown then
    state := DFCS_PUSHED
  else if isMouseMove then
    state := DFCS_HOT
  else
    state := 0;

  DrawFrameControl(Canvas.Handle, r, DFC_SCROLL, DFCS_SCROLLCOMBOBOX + state)
end;

function TSRVCustomComboBox.GetPriorItem(Index, Delta : Integer; isMouse : Boolean) : Integer;
begin
  Result := Index;
  Index := Index + Delta;
  while (Index >= 0) and
        (((not TSRVCBoxItem(Items.Items[Index]).Enabled) and not isMouse) or
//         (not TSRVCBoxItem(Items.Items[Index]).OpenParent) or
          not (srvioCanSelect in TSRVCBoxItem(Items.Items[Index]).Option)) do
    Dec(Index);
  if (Index >= 0) then
    Result := Index;
end;

function TSRVCustomComboBox.IndexOf(Value : String) : Integer;
var
     i : Integer;
begin
  Result := -1;
  for i:=0 to Items.Count-1 do
    if TSRVCBoxItem(Items.Items[i]).Caption = Value then begin
      Result := i;
      break;
    end;
end;

function TSRVCustomComboBox.GetNextItem(Index, Delta : Integer; isMouse : Boolean) : Integer;
begin
  Result := Index;
  Index := Index + Delta;
  while (Index < Items.Count) and
        (((not TSRVCBoxItem(Items.Items[Index]).Enabled) and not isMouse) or
//        (not TSRVCBoxItem(Items.Items[Index]).OpenParent) or
        not (srvioCanSelect in TSRVCBoxItem(Items.Items[Index]).Option)) do
    Inc(Index);
  if (Index < Items.Count) then
    Result := Index;
end;

procedure TSRVCustomComboBox.AppendStrings(List : TStrings;
  UseIndent: Boolean);
var
     index, Indent : Integer;
     Text : String;
begin
  BeginUpdate;
  Indent := 0;
  for index:=0 to List.Count-1 do begin
    Text := List.Strings[index];
    if UseIndent then begin
      Indent := Length(Text) - Length(TrimLeft(Text));
      // If Tab
      while Text[1] = #9 do begin
        Indent := Indent + 10;
        Text := Copy(Text, 2, Length(Text) - 1);
      end;
    end;
    if UseIndent then
      if Indent = 0 then
        AppendItem(Text, -1, -1, Indent, True, [], Font.Color, Color, Font.Name,
          False, [srvioShowCheckBox, srvioShowImage, srvioShowText, srvioCanHaveChildren])
      else
        AppendItem(Text, -1, -1, Indent, True, [], Font.Color, Color, Font.Name,
          True, [srvioShowCheckBox, srvioShowImage, srvioShowText, srvioCanSelect, srvioCanHaveChildren])
    else
      AppendItem(Text, -1, -1, Indent, True, [], Font.Color, Color, Font.Name,
        True, [srvioShowCheckBox, srvioShowImage, srvioShowText, srvioCanSelect, srvioCanHaveChildren]);
  end;
  EndUpdate;
end;

function TSRVCustomComboBox.AppendItem(Text : string;
                            ImageIndex, SelectedImageIndex, Indent : Integer;
                            Enabled : Boolean; Style: TFontStyles;
                            Color, BackColor : TColor; FontName : TFontName;
                            Expanded : Boolean; Option : TSRVItemOptions) : TSRVCBoxItem;
var
     Item : TSRVCBoxItem;
begin
  BeginUpdate;
  Item := TSRVCBoxItem(FItems.Add);
  Item.Caption := Text;
  Item.ImageIndex := ImageIndex;
  Item.SelectedImageIndex := SelectedImageIndex;
  Item.Indent := Indent;
  Item.Enabled := Enabled;
  Item.Style := Style;
  Item.Color := Color;
  Item.BackColor := BackColor;
  Item.FontName := FontName;
  Item.Option := Option;
  Item.Expanded := Expanded;
  if FSorted then
    Sorted := Sorted;
  Result := Item;
  EndUpdate;
  if LBVisible then
    ResizeLB;
end;

function TSRVCustomComboBox.InsertItem(Index : Integer; Text : string;
                            ImageIndex, SelectedImageIndex, Indent : Integer;
                            Enabled : Boolean; Style: TFontStyles;
                            Color, BackColor : TColor; FontName : TFontName;
                            Expanded : Boolean; Option : TSRVItemOptions) : TSRVCBoxItem;
var
     Item : TSRVCBoxItem;
begin
  BeginUpdate;
  Item := TSRVCBoxItem(FItems.Insert(Index));
  Item.Caption := Text;
  Item.ImageIndex := ImageIndex;
  Item.SelectedImageIndex := SelectedImageIndex;
  Item.Indent := Indent;
  Item.Enabled := Enabled;
  Item.Style := Style;
  Item.Color := Color;
  Item.BackColor := BackColor;
  Item.FontName := FontName;
  Item.Option := Option;
  Item.Expanded := Expanded;
  if FSorted then
    Sorted := Sorted;
  Result := Item;
  EndUpdate;
  if LBVisible then
    ResizeLB;
end;

procedure TSRVCustomComboBox.DeleteItem(Index : Integer);
begin
  FItems.Items[Index].Free;;
  if ItemIndex = FItems.Count then
    ItemIndex := FItems.Count - 1;
end;

constructor TSRVCustomComboBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  isMouseDown := False;
  isMouseMove := False;
  IsByse := False;

  lockUpdate := 0;
  LockChangeCount := 0;

  isEditMouswDown := False;
  isResizeHints := False;
  isUpdateAutoText := False;
  FSorted := False;
  FHideSelection := True;
  FAutoDropDown := False;
  FAutoComplete := True;
  FAutoSize := True;
  CanUpdateEdit := True;
  FSRVCBList := nil;
  FImageList := nil;
  FUseItemFontNames := False;
  FOption := [srvcbQuickKeySelect];
  FDropingDown := False;
  FDropDownCount := 5;
  FItemIndex := -1;
  TabStop := True;
  FListMarginWidth := 3;
  FListMarginHeight := 2;
  Buffer := nil;
  FDoubleBuffered := False;
  FRestrictListHeight := True;
  FDropDownHints := 10;
  FEnabledBorderColor := SRV_BORDER_ENABLED;
  FDisabledBorderColor := SRV_BORDER_DISABLED;
  FMouseInBorderColor := SRV_BORDER_MOUSEIN;
  FFocusedBorderColor := SRV_BORDER_FOCUSED;
  FSelectedItemBorderColor := clSilver;
  FSelectedItemBackColor := clHighlight;
  FSelectedItemTextColor := clHighlightText;
  FHotItemBorderColor := clSilver;
  FHotItemBackColor := clBackground;
  FHotItemTextColor := clWhite;
  FHintsSkinSchemeIndex := 0;
  FHintsScrollBarSkinSchemeIndex := 0;
  FHintsItemSkinSchemeIndex := 0;

  FCanvas := TCanvas.Create;

  FItems := TSRVCBoxItemCollection.Create(TSRVCBoxItem, Self);  

  Edit := TSRVEdit.Create(nil);
  Edit.Parent := Self;
  Edit.Name := 'SRVCBoxEdit';
  Edit.Enabled := not (csDesigning in ComponentState);
  Edit.Color := clNone;
  Edit.OnChange := HookOnChange;
  Edit.OnClick :=  HookOnClick;
  Edit.OnKeyDown := HookOnKeyDown;
  Edit.OnExit := HookOnExit;
  Edit.OnCloseHints := FormHintsClose;
  Edit.EnabledBorderWidth := 0;
  Edit.DisabledBorderWidth := 0;
  Edit.MouseInBorderWidth := 0;
  Edit.FocusedBorderWidth := 0;
  Text := Name;

  FScrollBar := TSRVScrollBar.Create(nil);
  FScrollBar.Parent := Self;
  FScrollBar.Kind := sbVertical;
  FScrollBar.Width := GetSystemMetrics(SM_CXVSCROLL);
  FScrollBar.SmallChange := 1;
  FScrollBar.LargeChange := 5;
  FScrollBar.TabStop := False;
  FScrollBar.OnScroll := HookOnScroll;
  FScrollBar.Enabled := True;
  FScrollBar.Visible := False;
  FScrollBar.Left := -FScrollBar.Width;

  FItems.OnAppend := HookOnAppend;
  FItems.OnModify := HookOnModify;
  FItems.OnRemove := HookOnRemove;

  Height := 20;
  Width := 120;
  BorderWidth := 0;
  Color := clWindow;
  FItemHeight := Height;
  FItemWidth := 0;
  Style := csDropDown;
  ResizeCB;
end;

destructor TSRVCustomComboBox.Destroy;
begin
  FScrollBar.Destroy;
  FScrollBar := nil;
  Edit.Destroy;
  FItems.Destroy;
  if Assigned(Buffer) then
    Buffer.Free;
  FCanvas.Handle := 0;
  FCanvas.Destroy;
  inherited;
end;

procedure TSRVCustomComboBox.CBListClose(Sender: TObject; var Action: TCloseAction);
begin
  isMouseDown := False;
  if FSRVCBList.ItemIndex >= 0 then
    ItemIndex := FSRVCBList.ItemIndex;
  FDropingDown := False;
  FCanvasList := nil;
  if ItemIndex <> -1 then
    if Edit.Visible then
      Edit.SetFocus
    else if Visible then
      SetFocus;
end;

procedure TSRVCustomComboBox.CBSetItemIndex(Value : Integer);
begin
  ItemIndex := Value;
end;

procedure TSRVCustomComboBox.ResizeCB;
var
     imgWidth : Integer;
begin
  if Assigned(ImageList) then begin
    imgWidth := ImageList.Width + 4;
    Edit.Left := 1 + imgWidth;
    if FStyle = csSimple then
      Edit.Width := Width - imgWidth - 3
    else
      Edit.Width := Width - GetButtonHeight - imgWidth - 3;
  end else begin
    Edit.Left := 1;
    if FStyle = csSimple then
      Edit.Width := Width - 3
    else
      Edit.Width := Width - GetButtonHeight - 3;
  end;
  if FStyle = csSimple then
    Edit.Top := Max((ItemHeight - Edit.Height + 1) div 2, 1)
//    Edit.Top := Min(ListMarginHeight, Max((Height - Edit.Height + 1) div 2, 1))
  else
    Edit.Top := Max((Height - Edit.Height + 1) div 2, 1);
  Edit.CanvasOffX := Edit.Left;
  Edit.CanvasOffY := Edit.Top;
  If Assigned(Buffer) then
    if FStyle = csSimple then
      Buffer.Height := ItemHeight + LBHeight
    else
      Buffer.Height := Round(Height * ScaleY);
end;

procedure TSRVCustomComboBox.UpdateBuffer(Canvas : TCanvas);
var
     BorderColor : TColor;
     R, cbRect : TRect;
     OffImgY : Integer;
     DoSkin : Boolean;
begin
  GetWindowRect(Handle, cbRect);
  OffsetRect(cbRect, -cbRect.Left, -cbRect.Top);

  If LBVisible then
    cbRect.Bottom := ItemHeight + LBHeight;

  if (not CBFocused and FHideSelection) or (ItemIndex = -1) then begin
    Canvas.Brush.Color := Color;
    If not ParentSRV then begin
      Edit.Color := Color;
      Edit.Font.Color := Font.Color;
    end else begin
      Edit.BGTextColor := Color;
      Edit.TextColor := Font.Color;
    end;
  end else begin
    Canvas.Brush.Color := clHighlight;
    If not ParentSRV then begin
      Edit.Color := clHighlight;
      Edit.Font.Color := clWhite;
    end else begin
      Edit.BGTextColor := clHighlight;
      Edit.TextColor := clWhite;
    end;
  end;

  If (csDesigning in ComponentState) and (Canvas.Brush.Color = clNone) then
    DrawBoxBG(Canvas, cbRect, SkinManager, EditSkinSchemeIndex, True,
      MouseIn or isMouseMove, isMouseDown, Enabled, Focused, 1, clWhite)
  else
    DrawBoxBG(Canvas, cbRect, SkinManager, EditSkinSchemeIndex, True,
      MouseIn or isMouseMove, isMouseDown, Enabled, Focused, 1, Canvas.Brush.Color);

  if LBVisible then
    UpdateListBox(Canvas, Bounds(0, ItemHeight, Width, LBHeight));

  if (FStyle <> csOwnerDrawFixed) and (FStyle <> csOwnerDrawVariable) and
     Assigned(ImageList) and (FItemIndex <> -1) then begin

    if FStyle <> csSimple then
      OffImgY := 1 + (Height - ImageList.Height - 2) div 2
    else
      OffImgY := 1 + (ItemHeight - ImageList.Height - 2) div 2;
    ImageList.Draw(Canvas, 4, OffImgY, TSRVCBoxItem(Items.Items[FItemIndex]).ImageIndex);
  end;

  if (FStyle = csDropDownList) then begin
    Canvas.Font := Font;

    if (CBFocused or not FHideSelection) and (ItemIndex <> -1) then
      Canvas.Font.Color := SelectedItemTextColor;
    Canvas.Brush.Style := bsClear;
    Canvas.TextOut(Edit.Left + 2, Edit.Top + 2, Edit.Text);
  end;

  if (FStyle = csOwnerDrawFixed) or (FStyle = csOwnerDrawVariable) then
    if Assigned(FOnDrawItem) then begin
      R := Rect(1, 1, Width-2, ItemHeight-2);
      if CBFocused then
        FOnDrawItem(Self, FItemIndex, R, [odSelected, odFocused])
      else
        FOnDrawItem(Self, FItemIndex, R, [{odNoFocusRect}]);
    end;

  if (not Enabled) then
    BorderColor := FDisabledBorderColor
  else if Edit.Focused or CBFocused then
    BorderColor := FFocusedBorderColor
  else if MouseIn then
    BorderColor := FMouseInBorderColor
  else
    BorderColor := FEnabledBorderColor;

  if FStyle <> csSimple then begin
    R := Bounds(Width - GetButtonHeight, 0, GetButtonHeight, Height);
    DoSkin := DrawBoxBG(Canvas, R, SkinManager, ButtonSkinSchemeIndex, True,
      MouseIn or isMouseMove, isMouseDown, Enabled, Focused, 1, clNone);

    if not DoSkin then
      DrawButton(Canvas, R);

    DrawBoxBorder(Canvas, R, SkinManager, ButtonSkinSchemeIndex, True,
      isMouseMove, isMouseDown, Enabled, Focused, 1);
  end;

  DoSkin := DrawBoxBorder(Canvas, cbRect, SkinManager, EditSkinSchemeIndex, True,
    MouseIn, isMouseDown, Enabled, Focused, 1);
  if not DoSkin and (BorderColor <> clNone) then begin
    Canvas.Pen.Color := BorderColor;
    Canvas.Brush.Color := clWhite;
    Canvas.Brush.Style := bsClear;
    Canvas.Pen.Style := psSolid;
    with cbRect do
      Canvas.Rectangle(Left, Top, Right, Bottom);
  end;
end;

procedure TSRVCustomComboBox.WMPaint(var Message: TWMPaint);
var
     Canvas : TCanvas;
     DC : HDC;
     lpPaint : tagPAINTSTRUCT;
     OldRect : TRect;
     OldMapMode: Integer;
     OldWindowOrg, OldWindowExt, OldViewportOrg, OldViewportExt: TSize;
     hRegion: HRGN;
begin
  if (lockUpdate <> 0) or not Visible then
    Exit;

  If ParentSRV and (Message.DC = 0) then begin
    DC := GetWindowDC(Handle);
    ReleaseDC(Handle, DC);
    if Parent <> nil then
      PostMessage(Parent.Handle, WM_REPAINT_CONTROL, 0, 0);
    exit;
  end;

  Canvas := TCanvas.Create;
  if Message.DC = 0 then
    DC := BeginPaint(Handle, lpPaint)
  else
    DC := Message.DC;
  Canvas.Handle := DC;

  OldMapMode := GetMapMode(Canvas.Handle);

  GetWindowExtEx(Canvas.Handle, OldWindowExt);
  GetViewportExtEx(Canvas.Handle, OldViewportExt);
  if ParentSRV then begin
    GetClipBox(Canvas.Handle, OldRect);
    hRegion := CreateRectRgn(0, 0, 99999, 99999);
    SelectClipRgn(Canvas.Handle, hRegion);
    DeleteObject(hRegion);

    SetMapMode(Canvas.Handle, MM_ANISOTROPIC);
//    SetWindowOrgEx(Canvas.Handle, 0, 0, @OldWindowOrg);
    SetWindowExtEx(Canvas.Handle, SRVWidth, SRVHeight, @OldWindowExt);

//    SetViewportOrgEx(Canvas.Handle, Round(CanvasOffX*ScaleX),
//      Round(CanvasOffY*ScaleY), @OldViewportOrg);
    SetViewportExtEx(Canvas.Handle, Round(SRVWidth * ScaleX),
      Round(SRVHeight * ScaleY), @OldViewportExt);
  end;

  Edit.ParentSRV := ParentSRV;
  Edit.Printing := Printing;
  Edit.ScaleX := ScaleX;
  Edit.ScaleY := ScaleY;
  Edit.ScreenOffX := ScreenOffX;
  Edit.ScreenOffY := ScreenOffY + (Height - Edit.Height);

  if (Edit.RFormSize.cx = 0) then
    Edit.RFormSize.cx := Width;

  If (csDesigning in ComponentState) then begin
     If Color = clNone then Canvas.Brush.Color := clWhite
     else Canvas.Brush.Color := Color;
     Canvas.FillRect(ClientRect);
  end;

  if DoubleBuffered then begin
    UpdateBuffer(Buffer.Canvas);
    Canvas.Draw(0, 0, Buffer);
  end else
    UpdateBuffer(Canvas);

  if CanUpdateEdit and Edit.Visible then begin
    CanUpdateEdit := False;
    If ParentSRV then begin
      Edit.RequiredCanvasOff := True;
      Edit.CanvasOffX := Edit.Left;
      Edit.CanvasOffY := Edit.Top;
      Edit.PaintTo(DC);
    end else begin
      Edit.RequiredCanvasOff := True;
      Edit.CanvasOffX := Edit.Left;
      Edit.CanvasOffY := Edit.Top;
      Edit.PaintTo(Canvas.Handle);

      Edit.RequiredCanvasOff := False;
      Edit.CanvasOffX := 3;
      Edit.CanvasOffY := Edit.Top;
//      Edit.Repaint;
    end;
//    Edit.PaintTo(DC);
//    SendMessage(Edit.Handle, WM_PAINT, Message.DC, 0);
    CanUpdateEdit := True;
  end;

  if ParentSRV then begin
    SetViewportOrgEx(Canvas.Handle, OldViewportOrg.cx, OldViewportOrg.cy, nil);
    SetViewportExtEx(Canvas.Handle, OldViewportExt.cx, OldViewportExt.cy, nil);
    SetWindowOrgEx(Canvas.Handle, OldWindowOrg.cx, OldWindowOrg.cy, nil);
    SetWindowExtEx(Canvas.Handle, OldWindowExt.cx, OldWindowExt.cy, nil);
    SetMapMode(Canvas.Handle, OldMapMode);

    with OldRect do
      hRegion := CreateRectRgn(Left, Top, Right, Bottom);
    SelectClipRgn(Canvas.Handle, hRegion);
    DeleteObject(hRegion);
  end;

  Canvas.Handle := 0;
  Canvas.Free;

  if Message.DC = 0 then
    EndPaint(Handle, lpPaint);
end;

procedure TSRVCustomComboBox.WMDblClick(var Message: TWMMouse);
var
     p : TPoint;
begin
  if (lockUpdate <> 0) or not Visible then
    Exit;
  p := Point(Message.XPos, Message.YPos);
  isEditMouswDown := ParentSRV and Edit.Visible and PtInRect(Edit.BoundsRect, p);
  if isEditMouswDown then begin
    with Message do begin
      XPos := XPos - Edit.Left;
      YPos := YPos + Edit.Top;
    end;
    Edit.WindowProc(TMessage(Message));
    Edit.CaretPos;
    Exit;
  end;

  if Edit.Visible and PtInRect(Edit.BoundsRect, p) then begin
    Edit.SetFocus;
    Exit;
  end else
    SetFocus;

  inherited;

  If LBVisible and
     not (FScrollBar.Visible and (p.X >= Width-1 - FScrollBar.Width)) and
     (MouseMoveIndex > -1) and (MouseMoveIndex < Items.Count) and
     (srvioCanSelect in TSRVCBoxItem(Items.Items[MouseMoveIndex]).Option) and
     (srvioCanHaveChildren in TSRVCBoxItem(Items.Items[MouseMoveIndex]).Option) then begin
    TSRVCBoxItem(Items.Items[MouseMoveIndex]).Expanded := not
      TSRVCBoxItem(Items.Items[MouseMoveIndex]).Expanded;
    Repaint;
  end;
end;

procedure TSRVCustomComboBox.MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer);
var
     p : TPoint;
     SBHeight, PageSize, MaxPos, W, H, edtH : Integer;
     Message: TWMMouse;
begin
  if (lockUpdate <> 0) or not Visible or (csDesigning in ComponentState) then
    Exit;
  isEditMouswDown := ParentSRV and Edit.Visible and PtInRect(Edit.BoundsRect, Point(X, Y));
  if isEditMouswDown then begin
    with Message do begin
      Msg := WM_LBUTTONDOWN;
      Keys := 0;
      if Button = mbLeft then
        Keys := Keys + MK_LBUTTON;
      if Button = mbRight then
        Keys := Keys + MK_RBUTTON;
      if Button = mbMiddle then
        Keys := Keys + MK_MBUTTON;
      if ssCtrl in Shift then
        Keys := Keys + MK_CONTROL;
      if ssShift in Shift then
        Keys := Keys + MK_SHIFT;
      XPos := X - Edit.Left;
      YPos := Y + Edit.Top;
    end;
    Edit.WindowProc(TMessage(Message));
    Edit.CaretPos;
    Exit;
  end;

  if Edit.Visible and
    PtInRect(Edit.BoundsRect, Point(X, Y)) then begin
//    ((FStyle = csSimple) or (X < Width - SBButtonHeight)) then begin
    Edit.SetFocus;
    Exit;
  end else
    SetFocus;

  inherited;

  if LBVisible then
    LBMouseDown(Button, Shift, X, Y);

  if (FStyle = csSimple) or
     (FStyle <> csDropDownList) and (not Edit.Visible and (X < Width - GetButtonHeight)) then
    Exit;

  if not Assigned(FSRVCBList) then begin
    Application.CreateForm(TFSRVCBList, FSRVCBList);
  end;

  CheckOpenTree(ItemIndex);
  if (Y = -1) and Edit.Visible then
    FSRVCBList.AutoDropDown := AutoDropDown
  else
    FSRVCBList.AutoDropDown := False;
  FCanvasList := FSRVCBList.Buffer.Canvas;
  FSRVCBList.GetItemHeight := GetItemHeight;
  FSRVCBList.CalculateDropItemCount := CalculateDropItemCount;
  FSRVCBList.CalculateShowItemCount := CalculateShowItemCount;
  FSRVCBList.CalculateItemCountToHeight := CalculateItemCountToHeight;
  FSRVCBList.CalculateItemCount := CalculateItemCount;
  FSRVCBList.GetItem := GetItem;
  FSRVCBList.BeginUpdate := BeginUpdate;
  FSRVCBList.EndUpdate := EndUpdate;
  FSRVCBList.ImgList := ImageList;
  FSRVCBList.SelectedItemBorderColor := SelectedItemBorderColor;
  FSRVCBList.SelectedItemBackColor := SelectedItemBackColor;
  FSRVCBList.SelectedItemTextColor := SelectedItemTextColor;
  FSRVCBList.HotItemBorderColor := HotItemBorderColor;
  FSRVCBList.HotItemBackColor := HotItemBackColor;
  FSRVCBList.HotItemTextColor := HotItemTextColor;

  FSRVCBList.ScaleX := ScaleX;
  FSRVCBList.ScaleY := ScaleY;
  FSRVCBList.OffX := ListMarginWidth;
  FSRVCBList.OffY := ListMarginHeight;
  FSRVCBList.OnClose := CBListClose;
  FSRVCBList.Option := Option;
  FSRVCBList.SetItemIndex := CBSetItemIndex;
  FSRVCBList.ItemHasParent := ItemHasParent;
  FSRVCBList.ItemHint := ItemHint;
  FSRVCBList.ShowHint := ShowHint;
  FSRVCBList.Hint := Hint;
  FSRVCBList.GetParent := GetParent;
  FSRVCBList.Font := Font;

  FSRVCBList.AControl := Self;
  FSRVCBList.ItemIndex := FItemIndex;
  FSRVCBList.CurItemIndex := FItemIndex;
  FSRVCBList.MouseMoveIndex := FItemIndex;
  FSRVCBList.UseItemFontNames := FUseItemFontNames;

  if (FStyle = csOwnerDrawFixed) or (FStyle = csOwnerDrawVariable) then
    FSRVCBList.FOnDrawItem := FOnDrawItem
  else
    FSRVCBList.FOnDrawItem := nil;

  if (FStyle = csOwnerDrawVariable) and Assigned(FOnMeasureItem) then begin
    FSRVCBList.ItemHeight := ItemHeight;
    if Assigned(FOnMeasureItem) then
      SBHeight := GetScrollBarHeight
    else
      SBHeight := Min(CalculateItemCount, DropDownCount) * ItemHeight;
  end else begin
    FSRVCBList.ItemHeight := FSRVCBList.Canvas.TextHeight('Text') + FSRVCBList.OffY;
    If Assigned(FSRVCBList.ImgList) then
      FSRVCBList.ItemHeight := Max(FSRVCBList.ImgList.Height, FSRVCBList.ItemHeight);
    FSRVCBList.ItemHeight := FSRVCBList.ItemHeight + FSRVCBList.OffY;
    SBHeight :=
      Min(CalculateItemCount, DropDownCount) * FSRVCBList.ItemHeight + FSRVCBList.OffY;
  end;
  SBHeight := SBHeight + ListMarginHeight*2;

  if ParentSRV then
    p := Point(ScreenOffX, ScreenOffY)
  else
    p := ClientToScreen(Point(0, 0));

  if FItemWidth <> 0 then
    W := Round(FItemWidth * ScaleX)
  else
    W := Round(Width * ScaleX);

  H := Max(Round(SBHeight * ScaleY), ItemHeight);
  edtH := Round(Height * ScaleY);
{$IFDEF RICHVIEWDEF6}
  if (p.x + W > Screen.WorkAreaRect.Right) then
    p.x := Max(Screen.WorkAreaRect.Right - W, Screen.WorkAreaRect.Left);
  if (p.y + edtH + H > Screen.WorkAreaRect.Bottom) and
     (p.y > Screen.WorkAreaRect.Bottom - p.y - edtH) then begin
{$ELSE}
  if p.x + W > Screen.DesktopLeft + Screen.DesktopWidth then
    p.x := Max(Screen.DesktopLeft + Screen.DesktopWidth - W, Screen.DesktopLeft);
  if (p.y + edtH + H > Screen.DesktopTop + Screen.DesktopHeight) and
     (p.y > Screen.DesktopTop + Screen.DesktopHeight - p.y - edtH) then begin
{$ENDIF}
    If p.y < H then
      H := p.y;
    SBHeight := Min(SBHeight,H);
    p.y := p.y - H;
  end else begin
{$IFDEF RICHVIEWDEF6}
    If p.y + H > Screen.WorkAreaRect.Bottom then
      Screen.WorkAreaRect.Bottom - p.y - edtH;
{$ELSE}
    If p.y + H > Screen.DesktopTop + Screen.DesktopHeight then
      H := Screen.DesktopTop + Screen.DesktopHeight - p.y - edtH;
{$ENDIF}
    SBHeight := Min(SBHeight, H);
    p.y := p.y + edtH;
  end;

  FSRVCBList.Items := Items;
  FSRVCBList.ScrollBar.IsSkin := True;
  FSRVCBList.ScrollBar.SkinManager := SkinManager;
  FSRVCBList.ScrollBar.SkinSchemeIndex := ScrollBarSkinSchemeIndex;
  FSRVCBList.SkinManager := SkinManager;
  FSRVCBList.ItemSkinSchemeIndex := ItemSkinSchemeIndex;
  FSRVCBList.SkinSchemeIndex := SkinSchemeIndex;

  MaxPos := CalculateItemCount;
  PageSize := MaxPos - Max(CalculateItemCountToHeight(SBHeight), 1);
  PageSize := Max(PageSize, MaxPos - DropDownCount);
  PageSize := Max(PageSize, 0);
  FSRVCBList.ScrollBar.PageSize := 0;
  FSRVCBList.ScrollBar.Max := MaxPos;
  FSRVCBList.ScrollBar.PageSize := FSRVCBList.ScrollBar.Max - PageSize + 1;

  FSRVCBList.ScrollBar.Visible := PageSize > 0;
  FSRVCBList.ScrollBar.Height := Round(SBHeight * ScaleY);
  if FSRVCBList.ScrollBar.Visible then begin
    FSRVCBList.ScrollBar.SmallChange := 1;
//    FSRVCBList.ScrollBar.LargeChange := DropDownCount-1;
    FSRVCBList.ScrollBar.LargeChange := Max(Min(MaxPos div 10, 10), 1);
    FSRVCBList.FirstItem := Min(Max(FSRVCBList.FirstItem, 0), FSRVCBList.ScrollBar.Max);
    FSRVCBList.ScrollBar.Position := FSRVCBList.FirstItem;
  end;

  FSRVCBList.DropDownCount := Min(Max(CalculateItemCountToHeight(Round(H / ScaleY)), 1), DropDownCount);
  FSRVCBList.FirstItem := FItemIndex - (FSRVCBList.DropDownCount div 2);
  FSRVCBList.FirstItem := Min(Max(FSRVCBList.FirstItem, 0), Max(CalculateItemCount - FSRVCBList.DropDownCount, 0));
  FDropingDown := True;

  FSRVCBList.SetBounds(p.x, p.y, W, H);
  FSRVCBList.ScrollBar.Height := Round(H / ScaleY) - 2;
  FSRVCBList.ScrollBar.Left := -FSRVCBList.ScrollBar.Width;
//  FSRVCBList.SetBounds(p.x, p.y + Round(Height * ScaleY), Round(Width * ScaleX) + 2, ListHeight+2);

//  FSRVCBList.ScrollBar.PageSize := MaxPos * FSRVCBList.ScrollBar.Height div CalculateItemsHeight;
//  FSRVCBList.ScrollBar.PageSize := (MaxPos-1) * FSRVCBList.ScrollBar.Height div (CalculateItemsHeight + FSRVCBList.ScrollBar.Height);

  if not FSRVCBList.Visible then
    FSRVCBList.Show
  else
    FSRVCBList.Paint;

  if (Y = -1) and FAutoDropDown and (FStyle <> csSimple) and Edit.Visible and
     not Edit.Focused then begin
    Edit._CanSelectAll := False;
    Edit.SetFocus;
    Edit._CanSelectAll := True;
  end;

  isMouseDown := FSRVCBList.Visible;
  Repaint;
  if Assigned(FOnDropDown) then
    FOnDropDown(Self);
end;

procedure TSRVCustomComboBox.MouseUp(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer);
var
     Message: TWMMouse;
begin
  if isEditMouswDown then begin
    with Message do begin
      Msg := WM_LBUTTONUP;
      Keys := 0;
      if Button = mbLeft then
        Keys := Keys + MK_LBUTTON;
      if Button = mbRight then
        Keys := Keys + MK_RBUTTON;
      if Button = mbMiddle then
        Keys := Keys + MK_MBUTTON;
      if ssCtrl in Shift then
        Keys := Keys + MK_CONTROL;
      if ssShift in Shift then
        Keys := Keys + MK_SHIFT;
      XPos := X - Edit.Left;
      YPos := Y + Edit.Top;
    end;
    Edit.WindowProc(TMessage(Message));
    Edit.CaretPos;

    isEditMouswDown := False;
    If Assigned(FSRVCBList) then
      isMouseDown := FSRVCBList.Visible
    else
      isMouseDown := False;
    exit;
  end;

  If Assigned(FSRVCBList) then
    isMouseDown := FSRVCBList.Visible
  else
    isMouseDown := False;
  isEditMouswDown := False;
  Repaint;
  inherited;
end;

procedure TSRVCustomComboBox.MouseMove(Shift: TShiftState; X, Y: Integer);
var
     NewMouseMove : Boolean;
     Message: TWMMouse;
begin
  if (csDesigning in ComponentState) then
    exit;

  if ParentSRV and Edit.Visible and PtInRect(Edit.BoundsRect, Point(X, Y)) then begin
    If not IsByse and ParentSRV and FScrollBar.InMouse then begin
      IsByse := True;
      with Message do
        SendMessage(FScrollBar.Handle, CM_MOUSELEAVE, 0, 0);
      IsByse := False;
    end;

    with Message do begin
      Msg := WM_MOUSEMOVE;
      Keys := 0;
      if ssCtrl in Shift then
        Keys := Keys + MK_CONTROL;
      if ssShift in Shift then
        Keys := Keys + MK_SHIFT;
      XPos := X - Edit.Left;
      YPos := Y + Edit.Top;
    end;
    Edit.WindowProc(TMessage(Message));
    Edit.CaretPos;
    Exit;
  end;

  if LBVisible then
    LBMouseMove(Shift, X, Y);

  NewMouseMove := PtInRect(Bounds(Width - GetButtonHeight, 0,
                                  GetButtonHeight, Height),
                           Point(X, Y));

  if isMouseMove <> NewMouseMove then begin
    isMouseMove := NewMouseMove;
    Repaint;
  end;
  inherited;
end;

procedure TSRVCustomComboBox.CMMouseEnter(var Message: TMessage);
begin
  inherited;
  Repaint;
end;

procedure TSRVCustomComboBox.CMMouseLeave(var Message: TMessage);
begin
  If IsByse and ParentSRV then
    Exit;

  inherited;

  If not IsByse and ParentSRV and FScrollBar.InMouse  then begin
    IsByse := True;
    with Message do
      SendMessage(FScrollBar.Handle, CM_MOUSELEAVE, 0, 0);
    IsByse := False;
  end;

  MouseMoveIndex := -1;
  isMouseMove := False;

  Repaint;
end;

procedure TSRVCustomComboBox.SetStyle(Value: TComboBoxStyle);
begin
  FStyle := Value;
  Edit.ReadOnly := Value = csDropDownList;
  Edit.Visible := (Value <> csDropDownList) and
                  (Value <> csOwnerDrawFixed) and
                  (Value <> csOwnerDrawVariable);
  if Value = csSimple then
    Edit.DropDownHints := 0
  else
    Edit.DropDownHints := DropDownHints;

  if Parent <> nil then
    if (Value = csDropDownList) then
      HideCaret(Edit.Handle)
    else
      ShowCaret(Edit.Handle);
  ResizeCB;
  If FDropDownCount = 0 then
    FDropDownCount := 10;
  if Value <> csSimple then
    AutoSize := AutoSize;
end;

procedure TSRVCustomComboBox.SetItemHeight(Value: Integer);
begin
  FItemHeight := Value;
  if AutoSize then
    if FStyle = csSimple then
      Height := Max(Value, Height)
    else
      Height := Value;
  ResizeCB;
end;

procedure TSRVCustomComboBox.SetItemWidth(Value: Integer);
begin
  FItemWidth := Value;
  if Assigned(FSRVCBList) and (Value <> 0) then
    FSRVCBList.Width := Round(FItemWidth * ScaleX);
end;

function TSRVCustomComboBox.GetItemWidth: Integer;
begin
  Result := FItemWidth;
  if Assigned(FSRVCBList) and (Result <> 0) then
    Result := Round(Result / ScaleX)
  else
    FSRVCBList.Width := Result;
end;

procedure TSRVCustomComboBox.CheckOpenTree(Value: Integer);
var
     i, Indent : Integer;
begin
  if (Value < 0) or (Value >= Items.Count) then Exit;
  // открываем все списки в которые вложен элемент
  Indent := TSRVCBoxItem(Items.Items[Value]).Indent;
  BeginUpdate;
  for i := Value downto 0 do
    if Indent = 0 then break
    else if TSRVCBoxItem(Items.Items[i]).Indent < Indent then begin
      if not TSRVCBoxItem(Items.Items[i]).Expanded then
        TSRVCBoxItem(Items.Items[i]).Expanded := True;
      Indent := TSRVCBoxItem(Items.Items[i]).Indent;
    end;
  EndUpdate;
end;

procedure TSRVCustomComboBox.SetItemIndex(Value: Integer);
begin
  if (Value < -1) or (Value >= Items.Count) or (FItemIndex = Value) then Exit;

  BeginUpdate;
  if (FItemIndex >= 0) and (FItemIndex < Items.Count) and (Value = -1) then
    TSRVCBoxItem(Items.Items[FItemIndex]).Selected := False;

  if Value <> -1 then begin
    if TSRVCBoxItem(Items.Items[Value]).Enabled then begin
      FItemIndex := Value;
      LockChange;
      Edit.BeginUpdate;
      Edit.Text := TSRVCBoxItem(Items.Items[FItemIndex]).Caption;
      Edit.EndUpdate;
      CheckOpenTree(Value);
      UnlockChange;
    end;
  end else
    FItemIndex := -1;

  if (Value >= 0) and (Value < Items.Count) then
    TSRVCBoxItem(Items.Items[Value]).Selected := True;

  EndUpdate;
  if (LockChangeCount = 0) and Assigned(FOnChange) then
    FOnChange(Self);
  Repaint;
end;

procedure TSRVCustomComboBox.KeyDown(var Key: Word; Shift: TShiftState);
var
     NewItemIndex : Integer;
begin
  NewItemIndex := ItemIndex;
  if (Key = VK_UP) then
    if ssAlt in Shift then
      MouseDown(mbLeft, [], Width, -1)
    else
      NewItemIndex := Max(GetPriorItem(FItemIndex, -1, False), 0);

  if (Key = VK_DOWN) then
    if ssAlt in Shift then
      MouseDown(mbLeft, [], Width, -1)
    else
      NewItemIndex := Min(GetNextItem(FItemIndex, 1, False), Items.Count-1);

  If (Key = VK_LEFT) then
    if (NewItemIndex > -1) and
        TSRVCBoxItem(Items.Items[NewItemIndex]).Expanded and
        ItemHasChild(NewItemIndex) then
      TSRVCBoxItem(Items.Items[NewItemIndex]).Expanded := False
    else if ItemHasParent(NewItemIndex) then
      NewItemIndex := GetParent(NewItemIndex)
    else
      NewItemIndex := Max(GetPriorItem(FItemIndex, -1, False), 0);

  If (Key = VK_RIGHT) then
    if (NewItemIndex > -1) and
        not TSRVCBoxItem(Items.Items[NewItemIndex]).Expanded and
        ItemHasChild(NewItemIndex) then
      TSRVCBoxItem(Items.Items[NewItemIndex]).Expanded := True
    else
      NewItemIndex := Min(GetNextItem(FItemIndex, 1, False), Items.Count-1);

  if (Key = VK_PRIOR) then
    NewItemIndex := Max(GetPriorItem(FItemIndex, - DropDownCount-1, False), 0);

  if (Key = VK_NEXT) then
    NewItemIndex := Min(GetNextItem(FItemIndex, DropDownCount-1, False), Items.Count-1);

  if (Key = VK_F4) and (FStyle <> csSimple) then
    If FSRVCBList.Visible then
      FSRVCBList.Close
    else
      MouseDown(mbLeft, [], Width, -1);

  if (NewItemIndex >= 0) and
     (not TSRVCBoxItem(Items.Items[NewItemIndex]).Enabled) then
    NewItemIndex := ItemIndex;

  if (Key = VK_HOME) then
    NewItemIndex := Min(GetNextItem(-1, 1, False), Items.Count-1);;

  if (Key = VK_END) then
    NewItemIndex := Max(GetPriorItem(Items.Count, -1, False), 0);

  if (NewItemIndex <> -1) and (FItemIndex <> NewItemIndex) then begin
    Key := 0;
    ItemIndex := NewItemIndex;
    If Style = csSimple then
      ResizeLB;
  end;

  If ParentSRV and (Parent <> nil) and (Parent.ClassName <> 'TSRichViewEdit') then
    PostMessage(Parent.Handle, WM_REPAINT_CONTROL, 0, 0);

  inherited;
end;

procedure TSRVCustomComboBox.HookOnChange(Sender: TObject);
var
     i, index : Integer;
begin
  if (LockChangeCount <> 0) then
    exit;
  index := ItemIndex;
  LockChange;

  if Assigned(FSRVCBList) and (FItemWidth <> 0) then
    FItemWidth := Round(FItemWidth / ScaleX);

  for i:= 0 to Items.Count-1 do
    if TSRVCBoxItem(Items.Items[i]).Caption = Edit.Text then begin
      ItemIndex := i;
      Break;
    end;
  if i = Items.Count then
    ItemIndex := -1;
  if isUpdateAutoText then
    UpdateAutoText;
  isUpdateAutoText := False;

  if FAutoDropDown and (FStyle <> csSimple) then
    MouseDown(mbLeft, [], Width, -1);

  if LBVisible then
    ResizeLB;
  if index = ItemIndex then
    Repaint;
  UnlockChange;
  if (LockChangeCount = 0) and Assigned(FOnChange) then
    FOnChange(Self);
end;

function TSRVCustomComboBox.GetScrollBarHeight : Integer;
var
     index, NewItemHeight : Integer;
begin
  Result := 0;
  for index := 0 to DropDownCount-1 do begin
    NewItemHeight := ItemHeight;
    if Assigned(FOnMeasureItem) then
      FOnMeasureItem(Self, FSRVCBList.FirstItem + index, NewItemHeight);
    Inc(Result, NewItemHeight);
  end;
end;

procedure TSRVCustomComboBox.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and (AComponent = FImageList) then
    FImageList := nil;
end;

procedure TSRVCustomComboBox.HookOnClick(Sender: TObject);
begin
  Repaint;
end;

procedure TSRVCustomComboBox.HookOnKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if (Key <> VK_DELETE) and (Key <> VK_BACK) then
    isUpdateAutoText := True;
  if (Key = VK_F4) and (FStyle <> csSimple) and not FDropingDown then
    MouseDown(mbLeft, [], Width, -1)
  else if FAutoDropDown and (FStyle <> csSimple) and Edit.Visible and
     Assigned(FSRVCBList) and FSRVCBList.Visible and
    ((Key = VK_UP) or (Key = VK_DOWN) or
     (Key = VK_PRIOR) or (Key = VK_NEXT) or
     ((Key = VK_SPACE) and (ssCtrl in Shift)) or (Key = VK_F4) or
     (Key = VK_RETURN) or (Key = VK_ESCAPE)) then begin
    FSRVCBList.FormKeyDown(nil, Key, Shift);
    Key := 0;
  end else If not Edit.Visible then
    KeyDown(Key, Shift);
end;

function  TSRVCustomComboBox.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint) : Boolean;
var
     NewItemIndex : Integer;
begin
  inherited DoMouseWheel(Shift, WheelDelta, MousePos);

  if LBVisible and ScrollBar.Visible then
    LBMouseWheel(Shift, WheelDelta, MousePos, Result)
  else begin
    if WheelDelta > 0 then
      NewItemIndex := Max(GetPriorItem(FItemIndex, -1, False), 0)
    else
      NewItemIndex := Min(GetNextItem(FItemIndex, 1, False), Items.Count-1);

    if (NewItemIndex >= 0) and
       TSRVCBoxItem(Items.Items[NewItemIndex]).Enabled then
      ItemIndex := NewItemIndex;
  end;

  Result := True;
end;

procedure TSRVCustomComboBox.SetImageList(Value: TCustomImageList);
begin
  FImageList := Value;
  ResizeCB;
end;

procedure TSRVCustomComboBox.WMSize(var Message: TWMSize);
begin
  inherited;
  If Assigned(Buffer) then begin
    Buffer.Width := Round(Width * ScaleX);
    Buffer.Height := Round(Height * ScaleY);
  end;
  Font := Font;
  ResizeLB;
  if not isResizeHints then
    Edit.RFormSize.cx := Message.Width + 6;
end;

procedure TSRVCustomComboBox.SetColor(Value: TColor);
begin
  FColor := Value;
{  If Assigned(Edit) then
    Edit.Color := Value;}
  Invalidate;
end;

procedure TSRVCustomComboBox.Invalidate;
begin
{  If HasParent and (Parent <> nil) and HandleAllocated then
    SendMessage(Handle, WM_PAINT, 0, 0)
  else}
    inherited;
end;

function TSRVCustomComboBox.GetText : String;
begin
  If Assigned(Edit) then
    Result := Edit.Text
  else
    Result := '';
end;

procedure TSRVCustomComboBox.SetText(Value: String);
begin
  If Assigned(Edit) then begin
    Edit.BeginUpdate;
    Edit.Text := Value;
    Edit.EndUpdate;
  end;
end;

function TSRVCustomComboBox.GetCharCase : TSRVEditCharCase;
begin
  If Assigned(Edit) then
    Result := Edit.CharCase
  else
    Result := srvecNormal;
end;

function TSRVCustomComboBox.GetReadOnly : Boolean;
begin
  If Assigned(Edit) then
    Result := Edit.ReadOnly
  else
    Result := False;
end;

procedure TSRVCustomComboBox.SetCharCase(Value: TSRVEditCharCase);
begin
  If Assigned(Edit) then
    Edit.CharCase := Value;
end;

procedure TSRVCustomComboBox.SetReadOnly(Value: Boolean);
begin
  If Assigned(Edit) then
    Edit.ReadOnly := Value;
end;

function TSRVCustomComboBox.GetMaxLength : Integer;
begin
  If Assigned(Edit) then
    Result := Edit.MaxLength
  else
    Result := 0;
end;

procedure TSRVCustomComboBox.SetMaxLength(Value: Integer);
begin
  If Assigned(Edit) then
    Edit.MaxLength := Value;
end;

function TSRVCustomComboBox.GetModified: Boolean;
begin
  If Assigned(Edit) then
    Result := Edit.Modified
  else
    Result := False;
end;

procedure TSRVCustomComboBox.SetModified(Value: Boolean);
begin
  If Assigned(Edit) then
    Edit.Modified := Value;
end;

function TSRVCustomComboBox.GetFont : TFont;
begin
  Result := inherited Font;
end;

procedure TSRVCustomComboBox.SetFont(Value: TFont);
begin
  inherited Font.Assign(Value);
  If Assigned(Edit) then
    Edit.Font.Assign(Value);
  AutoSize := AutoSize;
  ResizeCB;
end;

procedure TSRVCustomComboBox.SetAutoSize(Value: Boolean);
begin
  FAutoSize := Value;
  if Value then begin
    Edit.AutoSize := True;
    Edit.AutoSize := False;
    If Assigned(ImageList) then
      ItemHeight := Max(Edit.Height + 2, ImageList.Height + 2)
    else
      ItemHeight := Edit.Height + 2;
  end;
end;

procedure TSRVCustomComboBox.Loaded;
begin
  inherited;
  Font := Font;
  LockChange;
  Edit.BeginUpdate;
  Edit.Change;
  Edit.EndUpdate;
  UnlockChange;
end;

procedure TSRVCustomComboBox.HookOnExit(Sender: TObject);
begin
  if Handle <> GetFocus then
    isMouseMove := False;
  Repaint;
end;

procedure TSRVCustomComboBox.WMSetFocus(var Message: TMessage);
begin
  inherited;
  if ParentSRV then
    PostMessage(Parent.Handle, WM_REPAINT_CONTROL, 0, 0)
  else
    Repaint;
end;

procedure TSRVCustomComboBox.WMKillFocus(var Message: TMessage);
begin
  if (Edit.Handle = THandle(Message.WParam)) then begin
    inherited;
    Exit;
  end;
  if Edit.Visible then
    HideCaret(Edit.Handle);
  isMouseMove := False;
  isMouseDown := False;
  if ParentSRV then
    PostMessage(Parent.Handle, WM_REPAINT_CONTROL, 0, 0)
  else
    Repaint;
end;

procedure TSRVCustomComboBox.HookOnAppend(Sender: TObject);
var
     OldPosition : Integer;
begin
  if lockUpdate <> 0 then exit;
  if LBVisible then
    ResizeLB;
  If not Assigned(FSRVCBList) then exit;
  OldPosition := FSRVCBList.ScrollBar.Position;
  FSRVCBList.Reset;
  FSRVCBList.ScrollBar.Position := OldPosition;
  FSRVCBList.FirstItem := GetItem(FSRVCBList.ScrollBar.Position);
  FSRVCBList.Repaint;
end;

procedure TSRVCustomComboBox.HookOnModify(Sender: TObject);
var
     OldPosition : Integer;
begin
  if lockUpdate <> 0 then exit;
  if LBVisible then
    ResizeLB;
  If not Assigned(FSRVCBList) then exit;
  OldPosition := FSRVCBList.ScrollBar.Position;
  FSRVCBList.Reset;
  FSRVCBList.ScrollBar.Position := OldPosition;
  FSRVCBList.FirstItem := GetItem(FSRVCBList.ScrollBar.Position);
  FSRVCBList.Repaint;
end;

procedure TSRVCustomComboBox.HookOnRemove(Sender: TObject);
var
     OldPosition : Integer;
begin
  if lockUpdate <> 0 then exit;
  if LBVisible then
    ResizeLB;
  If not Assigned(FSRVCBList) then exit;
  OldPosition := FSRVCBList.ScrollBar.Position;
  FSRVCBList.Reset;
  FSRVCBList.ScrollBar.Position := OldPosition;
  FSRVCBList.FirstItem := GetItem(FSRVCBList.ScrollBar.Position);

  if (FSRVCBList.MouseMoveIndex >= Items.Count) then
    FSRVCBList.MouseMoveIndex := -1;

  if (ItemIndex >= Items.Count) then
    ItemIndex := -1;

  FSRVCBList.Repaint;
end;

function TSRVCustomComboBox.GetCaretPos: TPoint;
begin
  Result := Point(-1, -1);
  if Edit.Visible and CBFocused or Edit.Focused then begin
    Result := Edit.GetCaretPos;
    Result.X := Result.X + Edit.Left;
    Result.Y := Result.Y + Edit.Top;
  end;
end;

function TSRVCustomComboBox.GetCaretHeight: Integer;
begin
  Result := -1;
  if Edit.Visible and CBFocused or Edit.Focused then
    Result := Edit.CaretHeight;
end;

function TSRVCustomComboBox.GetSelected: Boolean;
begin
  Result := False;
  if Edit.Visible and CBFocused or Edit.Focused then
    Result := Edit.Selected;
end;

function TSRVCustomComboBox.GetSelLength: Integer;
begin
  Result := Edit.SelLength;
end;

function TSRVCustomComboBox.CBFocused: Boolean;
begin
  Result := inherited Focused;
end;

function TSRVCustomComboBox.Focused: Boolean;
begin
  if Edit.Visible  then
    Result := Edit.Focused
  else
    Result := CBFocused;
end;

procedure TSRVCustomComboBox.SetUseItemFontNames(const Value : Boolean);
begin
  FUseItemFontNames := Value;
  Repaint;
end;

function TSRVCustomComboBox.GetItemHeight(Index : Integer) : Integer;
begin
  if (Style <> csSimple) and Assigned(FSRVCBList) then
    Result := FSRVCBList.ItemHeight
  else
    Result := ItemHeight;
  if (Index = -1) or (Index >= Items.Count) then Exit;
  if (FStyle = csOwnerDrawVariable) and Assigned(FOnMeasureItem) then
    FOnMeasureItem(Self, Index, Result);
  if (srvioCanHaveChildren in TSRVCBoxItem(Items.Items[Index]).Option) and
     not TSRVCBoxItem(Items.Items[Index]).OpenParent then
    Result := 0;
end;

procedure TSRVCustomComboBox.UpdateListBox(ACanvas : TCanvas; ARect : TRect);
var
     i, X, Y, OffImgY, OffTextY, ItemHeight, ItemsHeight, ImgIndex, LBWidth,
     PosX, Step : Integer;
     RClient, RItem : TRect;
     DoSkin : Boolean;

  procedure GetOffset;
  begin
    case TSRVCBoxItem(Items.Items[i]).Alignment of
      taCenter : begin
          PosX := FListMarginWidth + TSRVCBoxItem(Items.Items[i]).Indent;

          If Assigned(ImageList) and
            (srvioShowImage in TSRVCBoxItem(Items.Items[i]).Option) then
            PosX := PosX + (ImageList.Width + 2);

          if (srvioShowText in TSRVCBoxItem(Items.Items[i]).Option) then begin
            if UseItemFontNames then
              ACanvas.Font.Name := TSRVCBoxItem(Items.Items[i]).FontName;
            ACanvas.Font.Style := TSRVCBoxItem(Items.Items[i]).Style;
            PosX := PosX + (ACanvas.TextWidth(TSRVCBoxItem(Items.Items[i]).Caption) + 2);
          end;

          X := (RClient.Left + RClient.Right - PosX) div 2;
          Step := 1;
        end;
      taRightJustify : begin
        X := RClient.Right;
        Step := -1;
      end;
    else
      X := 1;
      Step := 1;
    end;
    X := ARect.Left + X;
  end;

  procedure DrawImage;
  begin
      // draw image
      If Assigned(ImageList) and
         (srvioShowImage in TSRVCBoxItem(Items.Items[i]).Option) then begin
        OffImgY := (ItemHeight - ImageList.Height) div 2;
        If Step > 0 then
          PosX := X + FListMarginWidth + TSRVCBoxItem(Items.Items[i]).Indent
        else
          PosX := X - FListMarginWidth - TSRVCBoxItem(Items.Items[i]).Indent -
            ImageList.Width;
        ImageList.Draw(ACanvas, PosX, Y + OffImgY, ImgIndex);
        X := X + (ImageList.Width + 2) * Step;
      end;
  end;

begin
  DrawBoxBG(ACanvas, ARect, SkinManager, SkinSchemeIndex, True,
    MouseIn, isMouseDown, Enabled, Focused, 1, Color);

  If FScrollBar.Visible then
    RClient := Bounds(0, 0, ARect.Right-FScrollBar.Width, ARect.Bottom)
  else
    RClient := Bounds(0, 0, ARect.Right, ARect.Bottom);

  Y := ARect.Top + 1;
  ItemsHeight := 0;
  LBWidth := ARect.Right - ARect.Left;
  ACanvas.Font.Size := -1;
  ACanvas.Font := Font;
  for i:=FirstItem to Items.Count-1 do begin
    if not TSRVCBoxItem(Items.Items[i]).OpenParent then
      continue;
    ItemHeight := GetItemHeight(i);
    If ItemsHeight + ItemHeight > LBHeight then
      break;

    GetOffset;

    if TSRVCBoxItem(Items.Items[i]).Selected then begin
      // draw ItemIndex
      ACanvas.Pen.Color := FSelectedItemBorderColor;
      ACanvas.Brush.Color := FSelectedItemBackColor;
      ACanvas.Font.Color := FSelectedItemTextColor;
      ImgIndex := TSRVCBoxItem(Items.Items[i]).ImageIndex;
    end else if (MouseMoveIndex = i) then begin
      // draw select
      ACanvas.Pen.Color := FHotItemBorderColor;
      ACanvas.Brush.Color := FHotItemBackColor;
      ACanvas.Font.Color := FHotItemTextColor;
      ImgIndex := TSRVCBoxItem(Items.Items[i]).SelectedImageIndex;
      If ImgIndex = -1 then
        ImgIndex := TSRVCBoxItem(Items.Items[i]).ImageIndex;
    end else begin
      // draw normal
      ACanvas.Pen.Color := TSRVCBoxItem(Items.Items[i]).BackColor;
      ACanvas.Brush.Color := ACanvas.Pen.Color;
      ACanvas.Font.Color := TSRVCBoxItem(Items.Items[i]).Color;
      ImgIndex := TSRVCBoxItem(Items.Items[i]).ImageIndex;
    end;
    if ScrollBar.Visible then
      RItem := Bounds(RClient.Left, Y, LBWidth - 1 - ScrollBar.Width, ItemHeight)
    else
      RItem := Bounds(RClient.Left, Y, LBWidth - 1, ItemHeight);

    DoSkin := DrawBoxBG(ACanvas, RItem, SkinManager, ItemSkinSchemeIndex, True,
      MouseMoveIndex = i, ItemIndex = i,
      Enabled and TSRVCBoxItem(Items.Items[i]).Enabled,
      Focused, 1, clNone);

    if not DoSkin then
      with RItem do
        ACanvas.Rectangle(Left, Top, Right, Bottom);

    if UseItemFontNames then
      ACanvas.Font.Name := TSRVCBoxItem(Items.Items[i]).FontName;
    ACanvas.Font.Style := TSRVCBoxItem(Items.Items[i]).Style;

    if not Assigned(FOnDrawItem) then begin
      // draw image LeftJustify
      If ((TSRVCBoxItem(Items.Items[i]).AlignImage = tlraLeftJustify) and (Step > 0)) or
         ((TSRVCBoxItem(Items.Items[i]).AlignImage = tlraRightJustify) and (Step < 0)) then
        DrawImage;

      // draw text
      if (srvioShowText in TSRVCBoxItem(Items.Items[i]).Option) then begin
        OffTextY := (ItemHeight - ACanvas.TextHeight('Text')) div 2;
        ACanvas.Brush.Style := bsClear;
        If Step > 0 then
          PosX := FListMarginWidth + X + TSRVCBoxItem(Items.Items[i]).Indent
        else
          PosX := X - (FListMarginWidth + TSRVCBoxItem(Items.Items[i]).Indent +
            ACanvas.TextWidth(TSRVCBoxItem(Items.Items[i]).Caption));

        ACanvas.TextOut(PosX, Y + OffTextY, TSRVCBoxItem(Items.Items[i]).Caption);
        X := X + (ACanvas.TextWidth(TSRVCBoxItem(Items.Items[i]).Caption) + 2) * Step;
      end;

      // draw image RightJustify
      If ((TSRVLBoxItem(Items.Items[i]).AlignImage = tlraRightJustify) and (Step > 0)) or
         ((TSRVLBoxItem(Items.Items[i]).AlignImage = tlraLeftJustify) and (Step < 0)) then
        DrawImage;
    end else
      if (MouseMoveIndex = i) then
        FOnDrawItem(Self, i, RItem, [odSelected])
      else
        FOnDrawItem(Self, i, RItem, []);

    DrawBoxBorder(ACanvas, RItem, SkinManager, ItemSkinSchemeIndex, True,
      MouseMoveIndex = i, ItemIndex = i,
      Enabled and TSRVCBoxItem(Items.Items[i]).Enabled, Focused, 1);

    Y := Y + ItemHeight;
    ItemsHeight := ItemsHeight + ItemHeight;
  end;

  If ParentSRV and (FScrollBar.Left <> Width - FScrollBar.Width-1) then
    FScrollBar.Left := Width - FScrollBar.Width-1;
  FScrollBar.ParentSRV := ParentSRV;
  FScrollBar.Printing := Printing;
  FScrollBar.ScaleX := ScaleX;
  FScrollBar.ScaleY := ScaleY;

  FScrollBar.ScreenOffX := ScreenOffX + Round((ARect.right - FScrollBar.Width-1) * ScaleX);
  FScrollBar.ScreenOffY := ScreenOffY - Round(ARect.Top * ScaleY);
  FScrollBar.CanvasOffX := CanvasOffX + ARect.right - FScrollBar.Width-1;
  FScrollBar.CanvasOffY := CanvasOffY + ARect.Top+1;
  FScrollBar.MouseOffX_ := FScrollBar.Left + Round((ScreenOffX - FScrollBar.ClientToScreen(Point(0, 0)).x) / ScaleX);
  FScrollBar.MouseOffY_ := FScrollBar.Top + Round((ScreenOffY - FScrollBar.ClientToScreen(Point(0, 0)).y) / ScaleY);

  FScrollBar.IsSkin := True;
  If not ParentSRV and FScrollBar.Visible then
    FScrollBar.PaintTo(ACanvas.Handle, ARect.right - FScrollBar.Width-1, ARect.Top);

  DoSkin := DrawBoxBorder(Canvas, ARect, SkinManager, SkinSchemeIndex, True,
    MouseIn, isMouseDown, Enabled, Focused, 1);

  If not DoSkin then begin
    ACanvas.Brush.Color := clBlack;
    ACanvas.FrameRect(ARect);
  end;
end;

procedure TSRVCustomComboBox.LBMouseMove(Shift: TShiftState; X,
  Y: Integer);
var
     ItemH, yItem, index, OldMouseMoveIndex : Integer;
     Message: TWMMouse;
begin
  Y := Y - ItemHeight;

  if FScrollBar.Visible and
    (X >= Width-1 - FScrollBar.Width) and (Y >= 0) then begin
    // in scrollbar
    Message.XPos := X - (Width - FScrollBar.Width-1);
    Message.YPos := Y;
    with TMessage(Message) do
      PostMessage(FScrollBar.Handle, WM_MOUSEMOVE, WParam, LParam);
    Repaint;
    Exit;
  end else begin
    If not IsByse and ParentSRV and FScrollBar.InMouse then begin
      IsByse := True;
      with Message do
        SendMessage(FScrollBar.Handle, CM_MOUSELEAVE, 0, 0);
      IsByse := False;
    end;

    // Items
    OldMouseMoveIndex := MouseMoveIndex;
    yItem:= 0;
    for index := FirstItem to CalculateShowItemCount(FirstItem, 1, Height)-1 do begin
      if not TSRVCBoxItem(Items.Items[index]).OpenParent then
        continue;
      ItemH := GetItemHeight(index);
      if (Y >= yItem) and (Y < yItem + ItemH) then begin
        MouseMoveIndex := index;
        break;
      end;
      yItem := yItem + ItemH;
    end;

    if (MouseMoveIndex < -1) or (MouseMoveIndex >= Items.Count) then
      MouseMoveIndex := OldMouseMoveIndex
    else if (MouseMoveIndex >= 0) and
       not TSRVCBoxItem(Items.Items[MouseMoveIndex]).Enabled then
      MouseMoveIndex := OldMouseMoveIndex;
  end;
  Repaint;
  ItemHint(Self, MouseMoveIndex);
end;

procedure TSRVCustomComboBox.LBMouseDown(Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
     Message: TWMMouse;
begin
  Y := Y - ItemHeight;
  // ScrollBar
  if FScrollBar.Visible and
    (X >= Width-1 - FScrollBar.Width) then begin
    // in scrollbar
    Message.XPos := X - (Width - FScrollBar.Width-1);
    Message.YPos := Y;
    with TMessage(Message) do
      PostMessage(FScrollBar.Handle, WM_LBUTTONDOWN, WParam, LParam);
    Repaint;
    Exit;
  end else begin
    // choice
    if (MouseMoveIndex > -1) and (MouseMoveIndex < Items.Count) then begin
      if (srvioCanHaveChildren in TSRVCBoxItem(Items.Items[MouseMoveIndex]).Option) then begin
        if (srvioCanSelect in TSRVCBoxItem(Items.Items[MouseMoveIndex]).Option) then
          ItemIndex := MouseMoveIndex;
        if not (srvioCanSelect in TSRVCBoxItem(Items.Items[MouseMoveIndex]).Option) then
          TSRVCBoxItem(Items.Items[MouseMoveIndex]).Expanded := not
            TSRVCBoxItem(Items.Items[MouseMoveIndex]).Expanded;
      end;
    end else begin
      // Items
      ItemIndex := MouseMoveIndex;
    end;
  end;
  Repaint;
end;

procedure TSRVCustomComboBox.LBMouseWheel(Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
  Handled := True;
  If ScrollBar.Visible then begin
    BeginUpdate;
    if WheelDelta <= 0 then
      FScrollBar.Position := FScrollBar.Position + Mouse.WheelScrollLines
    else
      FScrollBar.Position := FScrollBar.Position - Mouse.WheelScrollLines;
    FirstItem := GetItem(FScrollBar.Position);
    EndUpdate;
  end;
  Repaint;
end;

procedure TSRVCustomComboBox.SetSelectedItemBorderColor(const Value : TColor);
begin
  FSelectedItemBorderColor := Value;
  Repaint;
end;

procedure TSRVCustomComboBox.SetSelectedItemBackColor(const Value : TColor);
begin
  FSelectedItemBackColor := Value;
  Repaint;
end;

procedure TSRVCustomComboBox.SetSelectedItemTextColor(const Value : TColor);
begin
  FSelectedItemTextColor := Value;
  Repaint;
end;

function TSRVCustomComboBox.CalculateShowItemCount(FirstItem, OffY, Height : Integer) : Integer;
var
     i, H, Y : Integer;
begin
  Result := Items.Count;
  Y := OffY;
  for i:=FirstItem to Items.Count-1 do begin
    if not TSRVCBoxItem(Items.Items[i]).OpenParent then
      continue;
    H := GetItemHeight(i);
    if (Y > Height - ListMarginHeight) then begin
      Result := i;
      Break;
    end;
    Y := Y + H;
  end;
end;

function TSRVCustomComboBox.CalculateDrawItemCount(FirstItem, OffY, Height : Integer) : Integer;
var
     i, H, Y : Integer;
begin
  Result := 0;
  Y := OffY;
  for i:=FirstItem to Items.Count-1 do begin
    H := GetItemHeight(i);
    Y := Y + H;
    if (Y > Height - ListMarginHeight) then
      Break;
    if H > 0 then
      Result := Result + 1;
  end;
end;

function TSRVCustomComboBox.CalculateDropItemCount(FirstItem, OffY, Height : Integer) : Integer;
var
     i, H, Y : Integer;
begin
  Result := 0;
  Y := OffY;
  for i:=FirstItem to Items.Count-1 do begin
    H := GetItemHeight(i);
    Y := Y + H;
    if (Y > Height - ListMarginHeight) then
      Break;
    Result := Result + 1;
  end;
end;

function TSRVCustomComboBox.CalculateItemCount : Integer;
var
     i : Integer;
begin
  Result := 0;
  for i:= 0 to Items.Count-1 do begin
    if GetItemHeight(i) > 0 then
      Result := Result + 1;
  end;
end;

function TSRVCustomComboBox.GetItem(Position : Integer) : Integer;
var
     i, index : Integer;
begin
  Result := 0;
  index := 0;
  for i:= 0 to Items.Count-1 do begin
    if index = Position then begin
      Result := i;
      Exit;
    end;
    if GetItemHeight(i) > 0 then
      index := index + 1;
  end;
end;

function TSRVCustomComboBox.GetPosition(ItemIndex : Integer) : Integer;
var
     i, index : Integer;
begin
  Result := 0;
  index := 0;
  for i:= 0 to Items.Count-1 do begin
    if i = ItemIndex then begin
      Result := index;
      Exit;
    end;
    if GetItemHeight(i) > 0 then
      index := index + 1;
  end;
end;

procedure TSRVCustomComboBox.ResizeLB;
var
     PageSize, MaxPos : Integer;
begin
  LBVisible := (Height > (ItemHeight + GetItemHeight(0))) and (Style = csSimple);
  if not LBVisible then
    exit;

  LBHeight := Height - ItemHeight;
  DropDownCount := CalculateDrawItemCount(0, ListMarginHeight, LBHeight);
  If FRestrictListHeight then
    LBHeight := (LBHeight div GetItemHeight(0)) * GetItemHeight(0) + ListMarginHeight;
  If Assigned(Buffer) then
    Buffer.Height := ItemHeight + LBHeight;

  MaxPos := CalculateItemCount;
  PageSize := MaxPos - Max(CalculateItemCountToHeight(LBHeight), 1);
  PageSize := Max(PageSize, MaxPos - DropDownCount);
  PageSize := Max(PageSize, 0);
  FScrollBar.PageSize := 0;
  FScrollBar.Max := MaxPos;
  FScrollBar.PageSize := ScrollBar.Max - PageSize + 1;

  if (FItemIndex < FirstItem) or
     (FItemIndex >= FirstItem + CalculateDropItemCount(FirstItem, ListMarginHeight, LBHeight)) then begin
    if (FItemIndex < FirstItem) then
      FirstItem := FItemIndex - (DropDownCount div 2)
    else
      FirstItem := FItemIndex - CalculateDropItemCount(FirstItem, ListMarginHeight, LBHeight) + 1;
    FirstItem := Min(Max(FirstItem, 0), FScrollBar.Max);
  end;

  FScrollBar.Visible := PageSize > 0;
  if LBVisible and FScrollBar.Visible then begin
    if ParentSRV then
      FScrollBar.Left := Width - FScrollBar.Width-1;
    FScrollBar.Top := ItemHeight + 1;
    FScrollBar.Height := LBHeight - 2;
    FScrollBar.SmallChange := 1;
    FScrollBar.LargeChange := DropDownCount-1;
    FScrollBar.Position := GetPosition(FirstItem);
  end;

  if (csDesigning in ComponentState) then
    If FScrollBar.Max > 0 then
      ScrollBar.Left := Width - FScrollBar.Width-1
    else
      ScrollBar.Left := -ScrollBar.Width;
end;

procedure TSRVCustomComboBox.BeginUpdate;
begin
  Inc(lockUpdate);
  If Assigned(FSRVCBList) then
    FSRVCBList.lockUpdate := lockUpdate;
end;

procedure TSRVCustomComboBox.EndUpdate;
begin
  Dec(lockUpdate);
  If Assigned(FSRVCBList) then
    FSRVCBList.lockUpdate := lockUpdate;
end;

procedure TSRVCustomComboBox.LockChange;
begin
  Inc(LockChangeCount);
end;

procedure TSRVCustomComboBox.UnlockChange;
begin
  Dec(LockChangeCount);
end;

procedure TSRVCustomComboBox.UpdateAutoText;
var
     i, l : Integer;
     strItem : String;
begin
  if FAutoComplete and Edit.Visible and (ItemIndex = -1) then begin
    // ищем первый похожий элемент
    l := Length(Edit.Text);
    strItem := Edit.Text;
    for i:=0 to FItems.Count-1 do
      if (Copy(TSRVCBoxItem(FItems.Items[i]).Caption, 1, l) = strItem) then begin
        ItemIndex := i;
        // выделяем текст
        Edit.SelStart := l;
        Edit.SelLength := Length(Edit.Text) - l;
        Exit;
      end;
  end;
end;

procedure TSRVCustomComboBox.SetAutoComplete(Value: Boolean);
begin
  FAutoComplete := Value;
  UpdateAutoText;
  Repaint;
end;

procedure TSRVCustomComboBox.SetAutoDropDown(Value: Boolean);
begin
  FAutoDropDown := Value;
  if Value then
    Edit.OnEditHints := nil
  else
    Edit.OnEditHints := FOnEditHints;
  Repaint;
end;

procedure TSRVCustomComboBox.SetHideSelection(Value: Boolean);
begin
  FHideSelection := Value;
  Repaint;
end;

{ алгоритм быстрой сортировки для символьных строк }
procedure TSRVCustomComboBox.QsString(var PItems : array of TSRVCBoxItem; Count : Integer);
var
    PItem : TSRVCBoxItem;

  procedure qs(l, r: integer);
  var
       i, j : integer;
       s : String;
  begin
    i := l;
    j := r;
    s := PItems[(l+r) div 2].Caption;
    repeat
      while PItems[i].Caption < s do
        i := i+1;
      while s < PItems[j].Caption do
        j := j-1;
      if (i <= j) then
      begin
        PItem := PItems[i];
        PItems[i] := PItems[j];
        PItems[j] := PItem;
        i := i+1;
        j := j-1;
      end;
    until i>j;
    if l<j then
      qs(l, j);
    if l<r then
      qs(i, r);
  end;
begin
  if (Count > 1) then
    qs(0, Count-1);
end; { конец быстрой сортировки }

procedure TSRVCustomComboBox.SetSorted(Value: Boolean);
var
   NewItems : TSRVCBoxItemCollection;

  function Sort(Index, NewIndex : Integer) : Integer;
  var
       i, k, j, Indent : integer;
       PItems, PItems2 : array of TSRVCBoxItem;
       HasChild : Boolean;
  begin
    result :=0;
    // выделяем список PItems
    SetLength(PItems, 10);

    PItems[0] := TSRVCBoxItem(Items.Items[Index]);
    Indent := PItems[0].Indent;
    HasChild := srvioCanHaveChildren in PItems[0].Option;
    i := Index+1;
    k := 1;
    while (i < Items.Count) do begin
      if TSRVCBoxItem(Items.Items[i]).Indent < Indent then
        Break;
      if ((TSRVCBoxItem(Items.Items[i]).Indent > Indent) and not HasChild) or
          (TSRVCBoxItem(Items.Items[i]).Indent = Indent) then begin
        if Length(PItems) <= k then
          SetLength(PItems, k * 2);
        PItems[k] := TSRVCBoxItem(Items.Items[i]);
        HasChild := srvioCanHaveChildren in PItems[k].Option;
        k := k + 1;
      end;
      i := i + 1;
    end;

    QsString(PItems, k);
    // Добавляем новые элементы
    SetLength(PItems2, k);
    for j := 0 to k-1 do begin
      PItems2[j] := TSRVCBoxItem(NewItems.Insert(NewIndex + j));
      PItems2[j].Assign(PItems[j]);
    end;

    // ищем детей сортируем их
    for i:=0 to k-1 do begin
      Index := PItems[i].Index + 1;
      if (Index < Items.Count) and
         (srvioCanHaveChildren in PItems[i].Option) and
         (TSRVCBoxItem(Items.Items[Index]).Indent > PItems[i].Indent) then
        Sort(Index, PItems2[i].Index+1);
    end;

    Finalize(PItems);
    Finalize(PItems2);
  end;

begin
  BeginUpdate;
  FSorted := Value;
  NewItems := TSRVCBoxItemCollection.Create(TSRVCBoxItem, Self);
  if (Items.Count > 0) and Value then
    Sort(0, 0);
  FItems.Destroy;
  NewItems.UpdateTree;
  FItems := NewItems;
  FItems.OnAppend := HookOnAppend;
  FItems.OnModify := HookOnModify;
  FItems.OnRemove := HookOnRemove;
  EndUpdate;
end;

procedure TSRVCustomComboBox.SetOnEditHints(const Value : TSRVEditHintsEvent);
begin
  FOnEditHints := Value;
  if FAutoDropDown then
    Edit.OnEditHints := nil
  else
    Edit.OnEditHints := FOnEditHints;
end;

procedure TSRVCustomComboBox.FormHintsClose(Sender: TObject;
  FormWidth, FormHeight : Integer; var NewText : String);
begin
  isResizeHints := isResizeHints or
                   (Edit.RFormSize.cx <> Round(FormWidth / ScaleX)) or
                   (Edit.RFormSize.cy <> Round(FormHeight / ScaleY));
end;

procedure TSRVCustomComboBox.SetDropDownHints(const Value: Integer);
begin
  FDropDownHints := Value;
  if (FStyle <> csSimple) and Assigned(Edit) then
    Edit.DropDownHints := Value;
end;

procedure TSRVCustomComboBox.HookOnScroll(Sender: TObject; ScrollCode: TScrollCode;
  var ScrollPos: Integer);
begin
  FirstItem := GetItem(ScrollPos);
  Repaint;
end;

procedure TSRVCustomComboBox.SetItemSkinSchemeIndex(Value : Integer);
begin
  FItemSkinSchemeIndex := Value;
  If Assigned(FSRVCBList) and FSRVCBList.Visible then begin
    FSRVCBList.ItemSkinSchemeIndex := Value;
    FSRVCBList.Repaint;
  end;

  Repaint;
end;

procedure TSRVCustomComboBox.SetSkinSchemeIndex(Value : Integer);
begin
  FSkinSchemeIndex := Value;
  If Assigned(FSRVCBList) and FSRVCBList.Visible then begin
    FSRVCBList.SkinSchemeIndex := Value;
    FSRVCBList.Repaint;
  end;

  Repaint;
end;

procedure TSRVCustomComboBox.SetScrollBarSkinSchemeIndex(Value : Integer);
begin
  FScrollBarSkinSchemeIndex := Value;
  FScrollBar.SkinSchemeIndex := Value;
  If Assigned(FSRVCBList) and FSRVCBList.Visible then begin
    FSRVCBList.ScrollBar.SkinSchemeIndex := Value;
    FSRVCBList.Repaint;
  end;

  Repaint;
end;

procedure TSRVCustomComboBox.SetSkinManager(Value : TSRVSkinManager);
begin
    FScrollBar.SkinManager := Value;
    If Assigned(FSRVCBList) and FSRVCBList.Visible then begin
      FSRVCBList.SkinManager := Value;
      FSRVCBList.ScrollBar.SkinManager := Value;
      FSRVCBList.Repaint;
    end;
  inherited;
end;

function TSRVCustomComboBox.GetButtonHeight : Integer;
begin
  Result := 18;
end;

function TSRVCustomComboBox.CalculateItemsHeight : Integer;
var
     i : Integer;
begin
  Result := ListMarginHeight * 2;
  for i:= 0 to Items.Count-1 do
    Result := Result + GetItemHeight(i);
end;

function TSRVCustomComboBox.CalculateItemsHeightTo(FirstIndex, ItemCount : Integer) : Integer;
var
     H : Integer;
begin
  Result := ListMarginHeight * 2;
  while (ItemCount > 0) and (FirstIndex < Items.Count) do begin
    H := GetItemHeight(FirstIndex);
    if (H > 0) then begin
      Result := Result + H;
      Dec(ItemCount);
    end;
    Inc(FirstIndex);
  end;
end;

function TSRVCustomComboBox.CalculateItemCountToHeight(Height : Integer) : Integer;
var
     i, nH, H : Integer;
begin
  Result := 0;
  nH := ListMarginHeight;
  for i:= 0 to Items.Count-1 do begin
    H := GetItemHeight(i);
    if H > 0 then begin
      nH := nH + H;
      If nH <= Height - ListMarginHeight then
        Result := Result + 1
      else
        Break;
    end;
  end;
end;

procedure TSRVCustomComboBox.WMGetDlgCode(var Message: TMessage);
begin
  Message.Result := DLGC_WANTARROWS or DLGC_WANTCHARS;
end;

procedure TSRVCustomComboBox.SetDoubleBuffered(Value: Boolean);
begin
  if FDoubleBuffered = Value then
    Exit;
  FDoubleBuffered := Value;
  If Value then begin
    Buffer := TBitmap.Create;
    Buffer.Width := Round(Width * ScaleX);
    If FRestrictListHeight then
      Buffer.Height := ItemHeight + LBHeight
    else
      Buffer.Height := Round(Height * ScaleY);
  end else
    Buffer.Free;
  Repaint;
end;

procedure TSRVCustomComboBox.SetRestrictListHeight(Value: Boolean);
begin
  FRestrictListHeight := Value;
  if LBVisible then
    ResizeLB;
  Repaint;
end;

procedure TSRVCustomComboBox.SetOption(Value: TSRVCBOptions);
begin
  FOption := Value;
  If Assigned(FSRVCBList) and FSRVCBList.Visible then
    FSRVCBList.Option := Value;
end;

function TSRVCustomComboBox.ItemHasChild(Index : Integer) : Boolean;
begin
  Result := False;
  If (Index < 0) or (Index >= Items.Count-1) then
    exit;

  Result := (srvioCanHaveChildren in TSRVCBoxItem(Items.Items[Index]).Option) and
    (TSRVCBoxItem(Items.Items[Index]).Indent < TSRVCBoxItem(Items.Items[Index+1]).Indent);
end;

function TSRVCustomComboBox.ItemHasParent(Index : Integer) : Boolean;
var
     Indent : Integer;
begin
  Result := False;
  If (Index < 0) or (Index >= Items.Count) then
    exit;

  Indent := TSRVCBoxItem(Items.Items[Index]).Indent;
  Dec(Index);

  while (Index >= 0) and (TSRVCBoxItem(Items.Items[Index]).Indent = Indent) do begin
    Indent := TSRVCBoxItem(Items.Items[Index]).Indent;
    Dec(Index);
  end;

  Result := (Index >= 0) and
    (TSRVCBoxItem(Items.Items[Index]).Indent > Indent) and
    (srvioCanHaveChildren in TSRVCBoxItem(Items.Items[Index]).Option) and
    (srvioCanSelect in TSRVCBoxItem(Items.Items[Index]).Option);
end;

function TSRVCustomComboBox.GetParent(Index : Integer) : Integer;
var
     Indent : Integer;
begin
  Result := -1;
  If (Index < 0) or (Index >= Items.Count) then
    exit;

  Indent := TSRVCBoxItem(Items.Items[Index]).Indent;
  Dec(Index);

  while (Index < 0) and (TSRVCBoxItem(Items.Items[Index]).Indent = Indent) do begin
    Indent := TSRVCBoxItem(Items.Items[Index]).Indent;
    Dec(Index);
  end;

  if (Index >= 0) and
     (TSRVCBoxItem(Items.Items[Index]).Indent > Indent) and
     (srvioCanHaveChildren in TSRVCBoxItem(Items.Items[Index]).Option) and
     (srvioCanSelect in TSRVCBoxItem(Items.Items[Index]).Option) then
    Result := Index;
end;

procedure TSRVCustomComboBox.SetListMarginWidth(Value: Integer);
begin
  FListMarginWidth := Value;
  if LBVisible then
    ResizeLB;
  Repaint;
end;

procedure TSRVCustomComboBox.SetListMarginHeight(Value: Integer);
begin
  FListMarginHeight := Value;
  if LBVisible then
    ResizeLB;
  Repaint;
end;

{-----------------------------------------------------------------------}
procedure TSRVCustomComboBox.WMRepaintControl(var Message: TMessage);
begin
  If ParentSRV then begin
    if Parent <> nil then
      PostMessage(Parent.Handle, WM_REPAINT_CONTROL, 0, 0);
  end else
    Repaint;
end;

{-----------------------------------------------------------------------}
procedure TSRVCustomComboBox.SetHintsSkinSchemeIndex(Value : Integer);
begin
  FHintsSkinSchemeIndex := Value;
  Edit.SkinSchemeIndex := Value;
  Repaint;
end;

{-----------------------------------------------------------------------}
procedure TSRVCustomComboBox.SetHintsScrollBarSkinSchemeIndex(Value : Integer);
begin
  FHintsScrollBarSkinSchemeIndex := Value;
  Edit.ScrollBarSkinSchemeIndex := Value;
  Repaint;
end;

{-----------------------------------------------------------------------}
procedure TSRVCustomComboBox.SetHintsItemSkinSchemeIndex(Value : Integer);
begin
  FHintsItemSkinSchemeIndex := Value;
  Edit.ItemSkinSchemeIndex := Value;
  Repaint;
end;

{-----------------------------------------------------------------------}
procedure TSRVCustomComboBox.ItemHint(Sender : TControl; Index : Integer);
var
  NewHint : String;
{$IFDEF RICHVIEWDEF5}
  pt: Tpoint;
{$ENDIF}
begin
  If (Index >= 0) and (Index < Items.Count) then
    NewHint := TSRVCBoxItem(Items.Items[Index]).Hint
  else
    NewHint := '';

  if Sender.ShowHint and (Sender.Hint <> NewHint) then begin
    Sender.Hint := NewHint;

    if Sender.Hint = '' then
    begin
{$IFDEF RICHVIEWDEF2009}
      if CustomHint <> nil then
        CustomHint.HideHint;
{$ENDIF}
      Application.CancelHint;
    end else
{$IFDEF RICHVIEWDEF5}
{$IFDEF RICHVIEWDEF2009}
    if CustomHint <> nil then
      CustomHint.ShowHint(Self)
    else
{$ENDIF}
    begin
      GetCursorPos(pt);
      Application.ActivateHint(pt);
    end;
{$ENDIF}
  end;
end;

{-----------------------------------------------------------------------}

end.

