如何加多选属性呢??我想添加“start+方向键”多选dode

如何加多选属性呢??我想添加“start+方向键”多选dode

 

unit RealICQContacterTreeView;

interface

uses
  RealICQHoverImage,
  RealICQUIColor, RealICQColors, RealICQClient, Messages, Forms, CommCtrl,
  SysUtils, Classes, Controls, ComCtrls, Graphics, Windows, ExtCtrls,
  RealICQContacterListView, SingleBorderHintWindow;

type
  TRealICQNoScrollBarTreeView = class;
  TTreeViewScrollBar = class;
  TRealICQBranch = class;
  TRealICQEmployee = class;
  TRealICQBranchListItems = class;
  TRealICQEmployeeListItems = class;

  TRealICQContacterTreeNodeNotifyEvent = procedure(Employee: TRealICQEmployee) of object;

  TRealICQContacterTreeNodeIconButtonType = (itCamera, itTel, itMobile, itEmail, itSMS, itHeadImage);
  TRealICQContacterTreeNodeIconButtonEvent = procedure(Sender: TObject;
    Employee: TRealICQEmployee; IconButtonType: TRealICQContacterTreeNodeIconButtonType) of object;
  TRealICQContacterTreeView = class(TPanel, IRealICQUIColor)
  private
    FNoScrollBarTreeView: TRealICQNoScrollBarTreeView;
    FTreeViewScrollBar: TTreeViewScrollBar;

    FBranchs: TStringList;
    FEmployees: TStringList;
    FBranchItems: TRealICQBranchListItems;
    FEmployeeItems: TRealICQEmployeeListItems;

    FTimer: TTimer;
    FHintWindow: TSingleBorderHintWindow;
    FTimerItemIndex: Integer;
   
    FOnSelectItemChanged: TRealICQContacterTreeNodeNotifyEvent;
    FOnItemClick: TRealICQContacterTreeNodeNotifyEvent;
    FOnItemDoubleClick: TRealICQContacterTreeNodeNotifyEvent;
    FOnItemMouseEnter: TRealICQContacterTreeNodeNotifyEvent;
    FOnItemMouseLeave: TRealICQContacterTreeNodeNotifyEvent;
    FOnItemFlashCaption: TRealICQContacterTreeNodeNotifyEvent;
    FOnItemOnline: TRealICQContacterTreeNodeNotifyEvent;
    FOnItemOffline: TRealICQContacterTreeNodeNotifyEvent;
    FOnItemIconButtonClick: TRealICQContacterTreeNodeIconButtonEvent;
    FOnItemIconButtonDblClick: TRealICQContacterTreeNodeIconButtonEvent;

    FAdjustPosition: Boolean;
    FShowLine: Boolean;
    FShowBranchImage: Boolean;
    FFlashCaptionOnOnline: Boolean;
    FOnlineNumeric: Cardinal;

    FStyle: TRealICQContacterListItemStyle;
    FCaptionStyle: TRealICQContacterListItemCaptionStyle;
    FSelectedItemBorderColor: TColor;
    FSelectedItemBorderInnerColor: TColor;
    FSelectedItemBackColor: TColor;
    FHeadImageBorderColor: TColor;
    FHeadImageBackColor: TColor;
    FSelectedItemBackgroud: TPicture;

    FBranchExpandedPicture: TPicture;
    FBranchCollapsedPicture: TPicture;

    FBranchClosedButtonPicture: TPicture;
    FBranchOpenedButtonPicture: TPicture;

    FDefaultPicture: TPicture;
    FDefaultPictureOffline: TPicture;
    FLeavePicture: TPicture;

    FCameraIcon :TIcon;
    FTelephoneIcon :TIcon;
    FMobilePhoneIcon :TIcon;
    FEmailIcon :TIcon;
    FSMSIcon :TIcon;

    FShowHeadImageButton: Boolean;
    FShowTelButton: Boolean;
    FShowMobileButton: Boolean;
    FShowCameraButton: Boolean;
    FShowEmailButton: Boolean;
    FShowSMSButton: Boolean;

    FIconBtnDefaultColor,
    FIconBtnLightColor,
    FIconBtnShadownColor: TColor;

    FScrollTopButtonPictureNormal: TPicture;
    FScrollTopButtonPictureHover: TPicture;
    FScrollTopButtonPictureDown: TPicture;

    FScrollBottomButtonPictureNormal: TPicture;
    FScrollBottomButtonPictureHover: TPicture;
    FScrollBottomButtonPictureDown: TPicture;

    FScrollBarButtonTopPictureNormal: TPicture;
    FScrollBarButtonTopPictureHover: TPicture;
    FScrollBarButtonTopPictureDown: TPicture;

    FScrollBarButtonMiddlePictureNormal: TPicture;
    FScrollBarButtonMiddlePictureHover: TPicture;
    FScrollBarButtonMiddlePictureDown: TPicture;

    FScrollBarButtonBottomPictureNormal: TPicture;
    FScrollBarButtonBottomPictureHover: TPicture;
    FScrollBarButtonBottomPictureDown: TPicture;

    FScrollBackgroundPictureNormal: TPicture;
    FScrollBackgroundPictureHover: TPicture;
    FScrollBackgroundPictureDown: TPicture;

    procedure SetScrollTopButtonPictureNormal(Value: TPicture);
    procedure SetScrollTopButtonPictureHover(Value: TPicture);
    procedure SetScrollTopButtonPictureDown(Value: TPicture);

    procedure SetScrollBottomButtonPictureNormal(Value: TPicture);
    procedure SetScrollBottomButtonPictureHover(Value: TPicture);
    procedure SetScrollBottomButtonPictureDown(Value: TPicture);

    procedure SetScrollBarButtonTopPictureNormal(Value: TPicture);
    procedure SetScrollBarButtonTopPictureHover(Value: TPicture);
    procedure SetScrollBarButtonTopPictureDown(Value: TPicture);

    procedure SetScrollBarButtonMiddlePictureNormal(Value: TPicture);
    procedure SetScrollBarButtonMiddlePictureHover(Value: TPicture);
    procedure SetScrollBarButtonMiddlePictureDown(Value: TPicture);

    procedure SetScrollBarButtonBottomPictureNormal(Value: TPicture);
    procedure SetScrollBarButtonBottomPictureHover(Value: TPicture);
    procedure SetScrollBarButtonBottomPictureDown(Value: TPicture);

    procedure SetScrollBackgroundPictureNormal(Value: TPicture);
    procedure SetScrollBackgroundPictureHover(Value: TPicture);
    procedure SetScrollBackgroundPictureDown(Value: TPicture);
    procedure SetCaptionStyle(Value: TRealICQContacterListItemCaptionStyle);

    procedure SetSelectedItemBorderColor(Value: TColor);
    procedure SetSelectedItemBorderInnerColor(Value: TColor);
    procedure SetSelectedItemBackColor(Value: TColor);
    procedure SetHeadImageBorderColor(Value: TColor);
    procedure SetHeadImageBackColor(Value: TColor);
    procedure SetSelectedItemBackgroud(Value: TPicture);
    procedure SetDefaultPicture(Value: TPicture);
    procedure SetDefaultPictureOffline(Value: TPicture);
    procedure SetLeavePicture(Value: TPicture);
   
    procedure SetCameraIcon(Value: TIcon);
    procedure SetTelephoneIcon(Value: TIcon);
    procedure SetMobilePhoneIcon(Value: TIcon);
    procedure SetEmailIcon(Value: TIcon);
    procedure SetSMSIcon(Value: TIcon);

    procedure SetBranchExpandedPicture(Value: TPicture);
    procedure SetBranchCollapsedPicture(Value: TPicture);
    procedure SetBranchClosedButtonPicture(Value: TPicture);
    procedure SetBranchOpenedButtonPicture(Value: TPicture);

    function GetScrollBarTop: Integer;
    procedure SetScrollBarTop(Value: Integer);

    function GetCount: Integer;
   
    procedure WhenResize(Sender: TObject);
    procedure TimerOnTimer(Sender: TObject);
    procedure ShowCustomHint(Node: TTreeNode);
   
    function GetCopyRight: String;
  protected
    procedure DoSelectItemChanged(Employee: TRealICQEmployee);
    procedure DoItemClick(Employee: TRealICQEmployee);
    procedure DoItemDoubleClick(Employee: TRealICQEmployee);
    procedure DoItemMouseEnter(Employee: TRealICQEmployee);
    procedure DoItemMouseLeave(Employee: TRealICQEmployee);
    procedure DoItemFlashCaption(Employee: TRealICQEmployee);
    procedure DoItemOnline(Employee: TRealICQEmployee);
    procedure DoItemOffline(Employee: TRealICQEmployee);
    procedure DoItemIconButtonClick(Employee: TRealICQEmployee; IconButtonType: TRealICQContacterTreeNodeIconButtonType);
    procedure DoItemIconButtonDblClick(Employee: TRealICQEmployee; IconButtonType: TRealICQContacterTreeNodeIconButtonType);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    procedure ChangeUIColor(AColor: TColor);
    procedure HideSystemScrollBar;
   
    procedure AddBranch(ABranch: TRealICQBranch);
    procedure AddEmployee(AEmployee: TRealICQEmployee);
    function GetEmployee(ALoginName: String): TRealICQEmployee;
    function GetSelectedEmployee: TRealICQEmployee;
   
    procedure BeginUpdate;
    procedure EndUpdate;
    procedure Clear;
    procedure ReDrawAll;
    procedure ReAlignBranchs;
    procedure MoveScrollBarToTop;
    procedure ExpandAllBranch(AExpanded: Boolean);

    property Count: Integer read GetCount;
  published
    property CopyRight: String read GetCopyRight;
    property ScrollBarTop: Integer read GetScrollBarTop write SetScrollBarTop;
    property EmployeeItems: TRealICQEmployeeListItems read FEmployeeItems;

    property AdjustPosition: Boolean read FAdjustPosition write FAdjustPosition;
    property ShowLine: Boolean read FShowLine write FShowLine;
    property ShowBranchImage: Boolean read FShowBranchImage write FShowBranchImage;
    property FlashCaptionOnOnline: Boolean read FFlashCaptionOnOnline write FFlashCaptionOnOnline;
    property OnlineNumeric: Cardinal read FOnlineNumeric write FOnlineNumeric;
    property Style: TRealICQContacterListItemStyle read FStyle write FStyle;
    property CaptionStyle: TRealICQContacterListItemCaptionStyle read FCaptionStyle write SetCaptionStyle;
    property SelectedItemBorderInnerColor: TColor read FSelectedItemBorderInnerColor write SetSelectedItemBorderInnerColor;
    property SelectedItemBorderColor: TColor read FSelectedItemBorderColor write SetSelectedItemBorderColor;
    property SelectedItemBackColor: TColor read FSelectedItemBackColor write SetSelectedItemBackColor;
    property HeadImageBorderColor: TColor read FHeadImageBorderColor write SetHeadImageBorderColor;
    property HeadImageBackColor: TColor read FHeadImageBackColor write SetHeadImageBackColor;
    property SelectedItemBackgroud: TPicture read FSelectedItemBackgroud write SetSelectedItemBackgroud;
    property DefaultPicture: TPicture read FDefaultPicture write SetDefaultPicture;
    property DefaultPictureOffline: TPicture read FDefaultPictureOffline write SetDefaultPictureOffline;
    property LeavePicture: TPicture read FLeavePicture write SetLeavePicture;

    property CameraIcon :TIcon read FCameraIcon write SetCameraIcon;
    property TelephoneIcon :TIcon read FTelephoneIcon write SetTelephoneIcon;
    property MobilePhoneIcon :TIcon read FMobilePhoneIcon write SetMobilePhoneIcon;
    property EmailIcon :TIcon read FEmailIcon write SetEmailIcon;
    property SMSIcon :TIcon read FSMSIcon write SetSMSIcon;

    property ShowHeadImageButton: Boolean read FShowHeadImageButton write FShowHeadImageButton;
    property ShowTelButton: Boolean read FShowTelButton write FShowTelButton;
    property ShowMobileButton: Boolean read FShowMobileButton write FShowMobileButton;
    property ShowCameraButton: Boolean read FShowCameraButton write FShowCameraButton;
    property ShowEmailButton: Boolean read FShowEmailButton write FShowEmailButton;
    property ShowSMSButton: Boolean read FShowSMSButton write FShowSMSButton;

    property BranchExpandedPicture: TPicture read FBranchExpandedPicture write SetBranchExpandedPicture;
    property BranchCollapsedPicture: TPicture read FBranchCollapsedPicture write SetBranchCollapsedPicture;
    property BranchClosedButtonPicture: TPicture read FBranchClosedButtonPicture write SetBranchClosedButtonPicture;
    property BranchOpenedButtonPicture: TPicture read FBranchOpenedButtonPicture write SetBranchOpenedButtonPicture;

    property ScrollTopButtonPictureNormal: TPicture read FScrollTopButtonPictureNormal write SetScrollTopButtonPictureNormal;
    property ScrollTopButtonPictureHover: TPicture read FScrollTopButtonPictureHover write SetScrollTopButtonPictureHover;
    property ScrollTopButtonPictureDown: TPicture read FScrollTopButtonPictureDown write SetScrollTopButtonPictureDown;

    property ScrollBottomButtonPictureNormal: TPicture read FScrollBottomButtonPictureNormal write SetScrollBottomButtonPictureNormal;
    property ScrollBottomButtonPictureHover: TPicture read FScrollBottomButtonPictureHover write SetScrollBottomButtonPictureHover;
    property ScrollBottomButtonPictureDown: TPicture read FScrollBottomButtonPictureDown write SetScrollBottomButtonPictureDown;

    property ScrollBarButtonTopPictureNormal: TPicture read FScrollBarButtonTopPictureNormal write SetScrollBarButtonTopPictureNormal;
    property ScrollBarButtonTopPictureHover: TPicture read FScrollBarButtonTopPictureHover write SetScrollBarButtonTopPictureHover;
    property ScrollBarButtonTopPictureDown: TPicture read FScrollBarButtonTopPictureDown write SetScrollBarButtonTopPictureDown;

    property ScrollBarButtonMiddlePictureNormal: TPicture read FScrollBarButtonMiddlePictureNormal write SetScrollBarButtonMiddlePictureNormal;
    property ScrollBarButtonMiddlePictureHover: TPicture read FScrollBarButtonMiddlePictureHover write SetScrollBarButtonMiddlePictureHover;
    property ScrollBarButtonMiddlePictureDown: TPicture read FScrollBarButtonMiddlePictureDown write SetScrollBarButtonMiddlePictureDown;

    property ScrollBarButtonBottomPictureNormal: TPicture read FScrollBarButtonBottomPictureNormal write SetScrollBarButtonBottomPictureNormal;
    property ScrollBarButtonBottomPictureHover: TPicture read FScrollBarButtonBottomPictureHover write SetScrollBarButtonBottomPictureHover;
    property ScrollBarButtonBottomPictureDown: TPicture read FScrollBarButtonBottomPictureDown write SetScrollBarButtonBottomPictureDown;

    property ScrollBackgroundPictureNormal: TPicture read FScrollBackgroundPictureNormal write SetScrollBackgroundPictureNormal;
    property ScrollBackgroundPictureHover: TPicture read FScrollBackgroundPictureHover write SetScrollBackgroundPictureHover;
    property ScrollBackgroundPictureDown: TPicture read FScrollBackgroundPictureDown write SetScrollBackgroundPictureDown;

    property OnSelectItemChanged: TRealICQContacterTreeNodeNotifyEvent read FOnSelectItemChanged write FOnSelectItemChanged;
    property OnItemClick: TRealICQContacterTreeNodeNotifyEvent read FOnItemClick write FOnItemClick;
    property OnItemDoubleClick: TRealICQContacterTreeNodeNotifyEvent read FOnItemDoubleClick write FOnItemDoubleClick;
    property OnItemMouseEnter: TRealICQContacterTreeNodeNotifyEvent read FOnItemMouseEnter write FOnItemMouseEnter;
    property OnItemMouseLeave: TRealICQContacterTreeNodeNotifyEvent read FOnItemMouseLeave write FOnItemMouseLeave;
    property OnItemFlashCaption: TRealICQContacterTreeNodeNotifyEvent read FOnItemFlashCaption write FOnItemFlashCaption;
    property OnItemOnline: TRealICQContacterTreeNodeNotifyEvent read FOnItemOnline write FOnItemOnline;
    property OnItemOffline: TRealICQContacterTreeNodeNotifyEvent read FOnItemOffline write FOnItemOffline;
    property OnItemIconButtonClick: TRealICQContacterTreeNodeIconButtonEvent read FOnItemIconButtonClick write FOnItemIconButtonClick;
    property OnItemIconButtonDblClick: TRealICQContacterTreeNodeIconButtonEvent read FOnItemIconButtonDblClick write FOnItemIconButtonDblClick;
  end;

  TTreeViewScrollBar = class(TCustomPanel)
  private
    FContacterTreeView: TRealICQContacterTreeView;

    //ListBox的可滚动的高度
    FClientRange: Integer;

    //滚动条可移动的高度
    FScrollRange: Integer;
   
    FTrackingBarTopRange: Integer;
    FAssignedPicture: Boolean;
    FButtonDown: Boolean;
    FTrackingBarDown: Boolean;
    FTrackingBarDonwY: Integer;
    FMovedYValue: Integer;

    FTopButtonImage: TRealICQHoverImage;
    FBottomButtonImage: TRealICQHoverImage;
    FBarButtonTopImage: TRealICQHoverImage;
    FBarButtonMiddleImage: TRealICQHoverImage;
    FBarButtonBottomImage: TRealICQHoverImage;
    FBackgroundImage: TRealICQHoverImage;

    FDrawing: Boolean;
   
    procedure DrawScrollBar;
    procedure TreeViewChange(Sender: TObject; Node: TTreeNode);
    procedure TreeViewExpanded(Sender: TObject; Node: TTreeNode);
    procedure TreeViewCollapsed(Sender: TObject; Node: TTreeNode);

    procedure TreeViewResize(Sender: TObject);
    procedure TreeViewMouseWheelUp(Sender: TObject;
      Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
    procedure TreeViewMouseWheelDown(Sender: TObject;
      Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);

    procedure TopButtonImageMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure TopButtonImageMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure TopButtonImageMouseEnter(Sender: TObject);
    procedure TopButtonImageMouseLeave(Sender: TObject);

    procedure BottomButtonImageMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure BottomButtonImageMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure BottomButtonImageMouseEnter(Sender: TObject);
    procedure BottomButtonImageMouseLeave(Sender: TObject);

    procedure BarButtonImageMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure BarButtonImageMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure BarButtonImageMouseEnter(Sender: TObject);
    procedure BarButtonImageMouseLeave(Sender: TObject);
    procedure BarButtonImageMouseMove(Sender: TObject;
      Shift: TShiftState; X, Y: Integer);
   
    procedure BackgroundImageMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure BackgroundImageMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure BackgroundImageMouseEnter(Sender: TObject);
    procedure BackgroundImageMouseLeave(Sender: TObject);
  protected
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
  end;

  TRealICQNoScrollBarTreeView = class(TCustomTreeView)
  private
    FContacterTreeView: TRealICQContacterTreeView;
    FItemHeight: Integer;
    FBufferedBitmap: Graphics.TBitmap;
    FMouseInDown: Boolean;
    procedure DrawContacterItem(ACanvas: TCanvas; Node: TTreeNode; Rect: TRect; State: TCustomDrawState);
    procedure DrawButton(ACanvas: TCanvas; ARect: TRect; Node: TTreeNode);
    procedure DrawImage(var ACanvas: TCanvas; NodeRect: TRect; Node: TTreeNode);

    function GetExpandedItemCount: Integer;
    procedure TreeViewCustomDrawItem(Sender: TCustomTreeView;
      Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
    procedure TreeViewMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure TreeViewMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure TreeViewDblClick(Sender: TObject);
    procedure TreeViewMouseLeave(Sender: TObject);
    procedure TreeViewMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
  protected
    procedure WMEraseBKGND(var Message: TWMEraseBKGND); message WM_ERASEBKGND;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property ItemHeight: Integer read FItemHeight;
    property ExpandedItemCount: Integer read GetExpandedItemCount;
  end;

  TRealICQBranchListItems = class(TStrings)
  private
    FContacterTreeView: TRealICQContacterTreeView;
  protected
    function GetObject(Index: Integer): TObject; override;
    procedure Put(Index: Integer; const S: string); override;
    function Get(Index: Integer): string; override;
    function GetCount: Integer; override;
  public
    constructor Create(AContacterTreeView: TRealICQContacterTreeView);
    destructor Destroy; override;
    function Add(const S: string): Integer; override;
    function AddObject(const S: string; AObject: TObject): Integer; override;
    procedure Insert(Index: Integer; const S: string); override;
    procedure Clear; override;
    procedure Delete(Index: Integer); override;
    function IndexOf(const S: string): Integer; override;
    procedure Move(CurIndex, NewIndex: Integer); override;
  end;

  TRealICQEmployeeListItems = class(TStrings)
  private
    FContacterTreeView: TRealICQContacterTreeView;
  protected
    function GetObject(Index: Integer): TObject; override;
    procedure Put(Index: Integer; const S: string); override;
    function Get(Index: Integer): string; override;
    function GetCount: Integer; override;
  public
    constructor Create(AContacterTreeView: TRealICQContacterTreeView);
    destructor Destroy; override;
    function Add(const S: string): Integer; override;
    function AddObject(const S: string; AObject: TObject): Integer; override;
    procedure Insert(Index: Integer; const S: string); override;
    procedure Clear; override;
    procedure Delete(Index: Integer); override;
    function IndexOf(const S: string): Integer; override;
    procedure Move(CurIndex, NewIndex: Integer); override;
  end;

  TRealICQBranch = class
  private
    FContacterTreeView: TRealICQContacterTreeView;
    FBranchName: String;
    FBranchID: String;
    FParentID: String;
   
    FNode: TTreeNode;
    FOnlineEmployee,
    FEmployeeCount: Cardinal;
  protected
  public
    constructor Create(ABranchName: String);
    destructor Destroy; override;

    procedure Update;

    property BranchName: String read FBranchName write FBranchName;
    property BranchID: String read FBranchID write FBranchID;
    property ParentID: String read FParentID write FParentID;
    property Node: TTreeNode read FNode;
  end;
 
  TRealICQEmployee = class
  private
    FContacterTreeView: TRealICQContacterTreeView;
    FLoginName: String;
    FBranchID: String;
    FDisplayName: String;
    FWatchword: String;
    FLoginState: TRealICQLoginState;
    FLeaveMessage: String;
    FHeadImagePicture: TPicture;   
    FNode: TTreeNode;

    FAdjustPositioned: Boolean;

    FFlashCaptionThread: TThread;
    FFlashImageThread: TThread;
    FMouseInRect: Boolean;
    FMouseInTextRect: Boolean;
   
    FCaptionColor: TColor;
    FHeadImagePosition: Integer;
    FFlashStyle: TRealICQFlashStyle;
   
    FHasCamera: Boolean;
    FHasTelephone: Boolean;
    FHasMobilePhone: Boolean;
    FHasEmail: Boolean;
    FHasSMS: Boolean;

    FHeadImageRect: TRect;
    FCameraRect: TRect;
    FTelephoneRect: TRect;
    FMobilePhoneRect: TRect;
    FEmailRect: TRect;
    FSMSRect: TRect;
    FTextRect: TRect;

    FMouseInHeadImageRect: Boolean;
    FMouseInCameraRect: Boolean;
    FMouseInTelephoneRect: Boolean;
    FMouseInMobilePhoneRect: Boolean;
    FMouseInEmailRect: Boolean;
    FMouseInSMSRect: Boolean;

    FHeadImageHint,
    FCameraHint,
    FTelephoneHint,
    FMobilePhoneHint,
    FEmailHint,
    FSMSHint: String;

    procedure AdjustPosition;
    function GetStatePosition(ALoginState: TRealICQLoginState): Integer;
    procedure SetLoginState(Value: TRealICQLoginState);
  protected
  public
    Data: Pointer;

    constructor Create(ALoginName: String);
    destructor Destroy; override;
   
    procedure Update;
    procedure Flash(AStyle: TRealICQFlashStyle);
    procedure StopFlash;

    property LoginName: String read FLoginName;
    property BranchID: String read FBranchID write FBranchID;
    property DisplayName: String read FDisplayName write FDisplayName;
    property Watchword: String read FWatchword write FWatchword;
    property LoginState: TRealICQLoginState read FLoginState write SetLoginState;
    property LeaveMessage: String read FLeaveMessage write FLeaveMessage;
    property HeadImagePicture: TPicture read FHeadImagePicture write FHeadImagePicture;
    property Node: TTreeNode read FNode;

    property HasCamera: Boolean read FHasCamera write FHasCamera;
    property HasTelephone: Boolean read FHasTelephone write FHasTelephone;
    property HasMobilePhone: Boolean read FHasMobilePhone write FHasMobilePhone;
    property HasEmail: Boolean read FHasEmail write FHasEmail;
    property HasSMS: Boolean read FHasSMS write FHasSMS;
   
    property HeadImageHint: String read FHeadImageHint write FHeadImageHint;
    property CameraHint: String read FCameraHint write FCameraHint;
    property TelephoneHint: String read FTelephoneHint write FTelephoneHint;
    property MobilePhoneHint: String read FMobilePhoneHint write FMobilePhoneHint;
    property EmailHint: String read FEmailHint write FEmailHint;
    property SMSHint: String read FSMSHint write FSMSHint;
  end;

  TRealICQFlashCaption = class(TThread)
  private
    FEmployee: TRealICQEmployee;
    FColorIndex:Integer;
    procedure FlashCaptionColor;
  protected
    procedure Execute; override;
  public
    constructor Create(AEmployee: TRealICQEmployee);
    destructor Destroy;override;
  end;
 
  TRealICQFlashImage = class(TThread)
  private
    FEmployee: TRealICQEmployee;
    FPosition: Integer;
    procedure FlashImagePosition;
  protected
    procedure Execute; override;
  public
    constructor Create(AEmployee: TRealICQEmployee);
    destructor Destroy;override;
  end;

procedure Register;

implementation
//------------------------------------------------------------------------------
function TRealICQContacterTreeView.GetCopyRight: String;
begin
  Result := ‘’;
end;

//------------------------------------------------------------------------------
procedure SetComCtlStyle(Ctl: TWinControl; Value: Integer; UseStyle: Boolean);
var
    Style: Integer;
begin
    if Ctl.HandleAllocated then
    begin
      Style := GetWindowLong(Ctl.Handle, GWL_STYLE);
      if not UseStyle then Style := Style and not Value
      else Style := Style or Value;
      SetWindowLong(Ctl.Handle, GWL_STYLE, Style);
    end;
end;

{TRealICQEmployee}
//------------------------------------------------------------------------------
procedure TRealICQEmployee.Flash(AStyle: TRealICQFlashStyle);
begin
  FFlashStyle := AStyle;
  if FFlashImageThread = nil then
  begin
    FFlashImageThread := TRealICQFlashImage.Create(Self);
  end;
end;

//------------------------------------------------------------------------------
procedure TRealICQEmployee.StopFlash;
var
  iWaitTimes: Integer;
begin
  if FFlashImageThread <> nil then
  begin
    FFlashImageThread.Terminate;
    iWaitTimes := 0;
    while FFlashImageThread <> nil do
    begin
      Inc(iWaitTimes);
      if iWaitTimes > 5000 then Exit;
     
      Sleep(10);
      Application.ProcessMessages;
    end;
  end;
end;

//------------------------------------------------------------------------------
procedure TRealICQEmployee.Update;
var
  Rect: TRect;
begin
  Rect := Node.DisplayRect(False);
  InvalidateRect(Node.TreeView.Handle, @Rect, False);
  AdjustPosition;
  FContacterTreeView.FTreeViewScrollBar.DrawScrollBar;
end;

//------------------------------------------------------------------------------
function TRealICQEmployee.GetStatePosition(ALoginState: TRealICQLoginState): Integer;
begin
  Result := 0;
  case ALoginState of
    stOnline: Result := 3;
    stLeave: Result := 2;
    stOffline,stHidden: Result := 1;
  end;
end;

//------------------------------------------------------------------------------
procedure TRealICQEmployee.AdjustPosition;
var
  RealICQEmployee: TRealICQEmployee;
  CurrentItemStatePosition,
  LoopItemStatePosition: Integer;

  CurrentItemString,
  LoopItemString: String;

  ParentNode,
  SiblingNode: TTreeNode;
begin
  FAdjustPositioned := True;
  if not FContacterTreeView.FAdjustPosition then Exit;

  CurrentItemStatePosition := GetStatePosition(FLoginState);

  if Length(Trim(FDisplayName)) = 0 then
    CurrentItemString := Chr(255) + FLoginName  //如果没有呢称,则排到最后面
  else
    CurrentItemString := FDisplayName;

  ParentNode := FNode.Parent;
  if ParentNode = nil then Exit;

  SiblingNode := ParentNode.getFirstChild;
  while (SiblingNode <> nil) do
  begin
    if (SiblingNode = FNode) or (SiblingNode.StateIndex <> FNode.StateIndex) then
    begin
      SiblingNode := SiblingNode.getNextSibling;
      continue;
    end;
   
    if SiblingNode.Level <> FNode.Level then Break;
    RealICQEmployee := SiblingNode.Data;
   
    if Length(Trim(RealICQEmployee.FDisplayName)) = 0 then
      LoopItemString := Chr(255) + RealICQEmployee.FLoginName  //如果没有呢称,则排到最后面
    else
      LoopItemString := RealICQEmployee.FDisplayName;

    LoopItemStatePosition := GetStatePosition(RealICQEmployee.FLoginState);
    if CurrentItemStatePosition < LoopItemStatePosition then
    begin
      if (SiblingNode.getNextSibling = nil) or (SiblingNode.getNextSibling.Level <> FNode.Level) then
      begin
        FNode.MoveTo(SiblingNode, naAdd);
        break;
      end
      else
      begin
        SiblingNode := SiblingNode.getNextSibling;
        continue;
      end;
    end
    else if LoopItemStatePosition = CurrentItemStatePosition then
    begin
      if AnsiCompareStr(CurrentItemString , LoopItemString) < 0 then
      begin
        FNode.MoveTo(SiblingNode, naInsert);
        Break;
      end;

      if (SiblingNode.getNextSibling = nil) or (SiblingNode.getNextSibling.Level <> FNode.Level) then
      begin
        FNode.MoveTo(SiblingNode, naAdd);
        Break;
      end;
    end
    else if CurrentItemStatePosition > LoopItemStatePosition  then
    begin
      FNode.MoveTo(SiblingNode, naInsert);
      Break;
    end;
    SiblingNode := SiblingNode.getNextSibling;
  end;
end;

//------------------------------------------------------------------------------
constructor TRealICQEmployee.Create(ALoginName: String);
begin
  FLoginName := ALoginName;
  FDisplayName := '';
  FWatchword := '';
  FHasCamera := False;
  FLoginState := stOffline;
  FHeadImagePicture := TPicture.Create;
 
  FAdjustPositioned := False;
  FCaptionColor := $00FFFFFF;
  FHeadImagePosition := 0;
  FMouseInRect := False;

  FMouseInHeadImageRect := False;
  FMouseInCameraRect := False;
  FMouseInTelephoneRect := False;
  FMouseInMobilePhoneRect := False;
  FMouseInEmailRect := False;
  FMouseInSMSRect := False;
 
  FHeadImageHint := '';
  FCameraHint := '';
  FTelephoneHint := '';
  FMobilePhoneHint := '';
  FEmailHint := '';
  FSMSHint := '';
 
  FHeadImageRect.Left := 0;
  FHeadImageRect.Top := 0;
  FHeadImageRect.Right := 0;
  FHeadImageRect.Bottom := 0;

  FCameraRect.Left := 0;
  FCameraRect.Top := 0;
  FCameraRect.Right := 0;
  FCameraRect.Bottom := 0;
 
  FTelephoneRect.Left := 0;
  FTelephoneRect.Top := 0;
  FTelephoneRect.Right := 0;
  FTelephoneRect.Bottom := 0;

  FMobilePhoneRect.Left := 0;
  FMobilePhoneRect.Top := 0;
  FMobilePhoneRect.Right := 0;
  FMobilePhoneRect.Bottom := 0;

  FEmailRect.Left := 0;
  FEmailRect.Top := 0;
  FEmailRect.Right := 0;
  FEmailRect.Bottom := 0;

  FSMSRect.Left := 0;
  FSMSRect.Top := 0;
  FSMSRect.Right := 0;
  FSMSRect.Bottom := 0;
end;

//------------------------------------------------------------------------------
destructor TRealICQEmployee.Destroy;
var
  iWaitTimes: Integer;

  ParentNode: TTreeNode;
  TmpBranch: TRealICQBranch;
begin
  try
    if FFlashCaptionThread <> nil then
    begin
      FFlashCaptionThread.Terminate;
      iWaitTimes := 0;
      while FFlashCaptionThread <> nil do
      begin
        Sleep(100);
        Application.ProcessMessages;
        Inc(iWaitTimes);
        if iWaitTimes > 100 then break; //最多等待10s时间
      end;
    end;

    if FFlashImageThread <> nil then
    begin
      FFlashImageThread.Terminate;
      iWaitTimes := 0;
      while FFlashImageThread <> nil do
      begin
        Sleep(100);
        Application.ProcessMessages;
        Inc(iWaitTimes);
        if iWaitTimes > 100 then break; //最多等待10s时间
      end;
    end;

    //调整在线人数的值
    if  (FLoginState <> stOffline) and (FLoginState <> stHidden) then
    begin
      Dec(FContacterTreeView.FOnlineNumeric);
     
      ParentNode := FNode.Parent;
      while ParentNode <> nil do
      begin
        TmpBranch := ParentNode.Data;
        Dec(TmpBranch.FOnlineEmployee, 1);
        TmpBranch.Update;
        ParentNode := ParentNode.Parent;
      end;
    end;

    //调整节点成员数值
    ParentNode := FNode.Parent;
    while ParentNode <> nil do
    begin
      TmpBranch := ParentNode.Data;
      Dec(TmpBranch.FEmployeeCount, 1);
      TmpBranch.Update;
      ParentNode := ParentNode.Parent;
    end;

    FreeAndNil(FHeadImagePicture);
    FreeAndNil(FNode);
  finally
    inherited Destroy;
  end;
end;

//------------------------------------------------------------------------------
procedure TRealICQEmployee.SetLoginState(Value: TRealICQLoginState);
var
  OldLoginState: TRealICQLoginState;
  iWaitTimes: Integer;

  ParentNode: TTreeNode;
  TmpBranch: TRealICQBranch;
begin
  if (FLoginState = Value) and FAdjustPositioned then Exit;
  OldLoginState := FLoginState;
  FLoginState := Value;

  //调整在线人数的值
  if ((Value <> stOffline) and (Value <> stHidden)) and
     ((OldLoginState = stOffline) or (OldLoginState = stHidden)) then
  begin
    Inc(FContacterTreeView.FOnlineNumeric);
    FContacterTreeView.DoItemOnline(Self);

    ParentNode := FNode.Parent;
    while ParentNode <> nil do
    begin
      TmpBranch := ParentNode.Data;
      Inc(TmpBranch.FOnlineEmployee, 1);
      TmpBranch.Update;
      ParentNode := ParentNode.Parent;
    end;
  end;

  //调整在线人数的值
  if ((Value = stOffline) or (Value = stHidden)) and
     ((OldLoginState <> stOffline) and (OldLoginState <> stHidden)) then
  begin
    Dec(FContacterTreeView.FOnlineNumeric);
    FContacterTreeView.DoItemOffline(Self);
   
    ParentNode := FNode.Parent;
    while ParentNode <> nil do
    begin
      TmpBranch := ParentNode.Data;
      Dec(TmpBranch.FOnlineEmployee, 1);
      TmpBranch.Update;
      ParentNode := ParentNode.Parent;
    end;
  end;

  AdjustPosition;

  if (FLoginState <> stOnline) and (FFlashCaptionThread <> nil) then
  begin
    FFlashCaptionThread.Terminate;
    iWaitTimes := 0;
    while FFlashCaptionThread <> nil do
    begin
      Sleep(100);
      Application.ProcessMessages;
      Inc(iWaitTimes);
      if iWaitTimes > 100 then break; //最多等待连接线程结束10s时间
    end;
  end;
 
  if (FLoginState = stOnline) and (FContacterTreeView.FFlashCaptionOnOnline) then
  begin
    if FFlashCaptionThread = nil then FFlashCaptionThread := TRealICQFlashCaption.Create(Self);
    FContacterTreeView.DoItemFlashCaption(Self);
  end;
end;

{TRealICQBranch}

//------------------------------------------------------------------------------
constructor TRealICQBranch.Create(ABranchName: String);
begin
  FBranchName := ABranchName;
  FOnlineEmployee := 0;
  FEmployeeCount := 0;
end;

//------------------------------------------------------------------------------
destructor TRealICQBranch.Destroy;
begin
  try
  finally
    inherited Destroy;
  end;
end;

//------------------------------------------------------------------------------
procedure TRealICQBranch.Update;
var
  Rect: TRect;
begin
  Rect := Node.DisplayRect(False);
  InvalidateRect(Node.TreeView.Handle, @Rect, False);
end;

{TRealICQContacterTreeView}

{$region 'TRealICQContacterTreeView'}

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetCaptionStyle(Value: TRealICQContacterListItemCaptionStyle);
begin
  FCaptionStyle := Value;
  FNoScrollBarTreeView.Width := FNoScrollBarTreeView.Width - 1;
  FNoScrollBarTreeView.Width := FNoScrollBarTreeView.Width + 1;
  FNoScrollBarTreeView.Invalidate;
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetSelectedItemBorderInnerColor(Value: TColor);
begin
  if FSelectedItemBorderInnerColor = Value then Exit;
  FSelectedItemBorderInnerColor := Value;
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetSelectedItemBorderColor(Value: TColor);
begin
  if FSelectedItemBorderColor = Value then Exit;
  FSelectedItemBorderColor := Value;
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetSelectedItemBackColor(Value: TColor);
begin
  if FSelectedItemBackColor = Value then Exit;
  FSelectedItemBackColor := Value;
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetHeadImageBorderColor(Value: TColor);
begin
  if FHeadImageBorderColor = Value then Exit;
  FHeadImageBorderColor := Value;
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetHeadImageBackColor(Value: TColor);
begin
  if FHeadImageBackColor = Value then Exit;
  FHeadImageBackColor := Value;
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetSelectedItemBackgroud(Value: TPicture);
begin
  FSelectedItemBackgroud.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetDefaultPicture(Value: TPicture);
begin
  FDefaultPicture.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetDefaultPictureOffline(Value: TPicture);
begin
  FDefaultPictureOffline.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetLeavePicture(Value: TPicture);
begin
  FLeavePicture.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetCameraIcon(Value: TIcon);
begin
  FCameraIcon.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetTelephoneIcon(Value: TIcon);
begin
  FTelephoneIcon.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetMobilePhoneIcon(Value: TIcon);
begin
  FMobilePhoneIcon.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetEmailIcon(Value: TIcon);
begin
  FEmailIcon.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetSMSIcon(Value: TIcon);
begin
  FSMSIcon.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetBranchExpandedPicture(Value: TPicture);
begin
  FBranchExpandedPicture.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetBranchCollapsedPicture(Value: TPicture);
begin
  FBranchCollapsedPicture.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetBranchClosedButtonPicture(Value: TPicture);
begin
  FBranchClosedButtonPicture.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetBranchOpenedButtonPicture(Value: TPicture);
begin
  FBranchOpenedButtonPicture.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.AddBranch(ABranch: TRealICQBranch);
begin
  FBranchItems.AddObject(ABranch.FBranchName, ABranch);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.AddEmployee(AEmployee: TRealICQEmployee);
begin
  FEmployeeItems.AddObject(AEmployee.FLoginName, AEmployee);
end;

//------------------------------------------------------------------------------
function TRealICQContacterTreeView.GetSelectedEmployee: TRealICQEmployee;
begin
  Result := nil;
  if FNoScrollBarTreeView.Selected = nil then Exit;
  if FNoScrollBarTreeView.Selected.StateIndex = 0 then Exit;
 
  Result := FNoScrollBarTreeView.Selected.Data;
end;

//------------------------------------------------------------------------------
function TRealICQContacterTreeView.GetEmployee(ALoginName: String): TRealICQEmployee;
var
  iIndex: Integer;
begin
  iIndex := FEmployeeItems.IndexOf(ALoginName);
  if iIndex = -1 then
    Result := nil
  else
    Result := FEmployeeItems.Objects[iIndex] as TRealICQEmployee;
end;

//------------------------------------------------------------------------------
function TRealICQContacterTreeView.GetCount: Integer;
var
  Node: TTreeNode;
begin
  Result := 0;
 
  Node := FNoScrollBarTreeView.Items.GetFirstNode;
  while Node <> nil do
  begin
    if Node.StateIndex = 1 then Inc(Result, 1);
    Node := Node.GetNext;
  end;
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.TimerOnTimer(Sender: TObject);
var
  P: TPoint;
  Node: TTreeNode;
begin
  FTimer.Enabled := False;
 
  P := FNoScrollBarTreeView.ScreenToClient(Mouse.CursorPos);
  Node := FNoScrollBarTreeView.GetNodeAt(P.X, P.Y);
  if Node = nil then Exit;
  if FTimerItemIndex <> Node.Index then Exit;
  ShowCustomHint(Node);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.ShowCustomHint(Node: TTreeNode);
var
  P: TPoint;
  Rect: TRect;
  Employee: TRealICQEmployee;
  HintStr: String;
  TextWidth,
  TextHeight: Integer;
begin
  if not ShowHint then Exit;

  HintStr := '';
  Employee := Node.Data;

  if Employee.FMouseInTextRect then
  begin
    HintStr := Employee.LoginName;
    if Employee.FLoginState = stLeave then
      HintStr := HintStr + '(' + Employee.FLeaveMessage + ')'
    else
      HintStr := HintStr + '(' + StateValues[Integer(Employee.FLoginState) mod 3] + ')';

    TextWidth := FHintWindow.Canvas.TextWidth(HintStr);
    if TextWidth < FHintWindow.Canvas.TextWidth(Employee.DisplayName) then
      TextWidth := FHintWindow.Canvas.TextWidth(Employee.DisplayName);
    if TextWidth < FHintWindow.Canvas.TextWidth(Employee.Watchword) then
      TextWidth := FHintWindow.Canvas.TextWidth(Employee.Watchword);

    TextHeight := FHintWindow.Canvas.TextHeight(Employee.LoginName);
    if Length(Trim(Employee.DisplayName)) > 0 then
    begin
      TextHeight := TextHeight + FHintWindow.Canvas.TextHeight(Employee.DisplayName);
      HintStr := HintStr + #$D#$A + Employee.DisplayName;
     end;
 
    if Length(Trim(Employee.Watchword)) > 0 then
    begin
      TextHeight := TextHeight + FHintWindow.Canvas.TextHeight(Employee.Watchword);
      HintStr := HintStr + #$D#$A + Employee.Watchword;
    end;
  end
  else
  begin
    if Employee.FMouseInHeadImageRect then HintStr := Employee.FHeadImageHint;
    if Employee.FMouseInCameraRect then HintStr := Employee.FCameraHint;
    if Employee.FMouseInTelephoneRect then HintStr := Employee.FTelephoneHint;
    if Employee.FMouseInMobilePhoneRect then HintStr := Employee.FMobilePhoneHint;
    if Employee.FMouseInEmailRect then HintStr := Employee.FEmailHint;
    if Employee.FMouseInSMSRect then HintStr := Employee.FSMSHint;
     
    TextWidth := FHintWindow.Canvas.TextWidth(HintStr);
    TextHeight := FHintWindow.Canvas.TextHeight(HintStr);
  end;
 
  if Length(Trim(HintStr)) = 0 then Exit;
 
  P.X := 0;
  P.Y := 0;
  P := FNoScrollBarTreeView.ClientToScreen(P);
  Rect.Left := Mouse.CursorPos.X + 20;
  Rect.Top := Node.DisplayRect(True).Top + FNoScrollBarTreeView.FItemHeight + P.Y + 10;
  Rect.Right := Rect.Left + TextWidth + 10;
  Rect.Bottom := Rect.Top + TextHeight + 5;

  FHintWindow.Color := clInfoBk;
  FHintWindow.ActivateHint(Rect, HintStr);
  FHintWindow.Visible := True;
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.WhenResize(Sender: TObject);
begin
  FTreeViewScrollBar.TreeViewResize(FNoScrollBarTreeView);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.BeginUpdate;
begin
  Parent.DisableAlign;
  FNoScrollBarTreeView.Items.BeginUpdate;
  FNoScrollBarTreeView.DisableAlign;
  FNoScrollBarTreeView.Enabled := False;
  FNoScrollBarTreeView.OnCustomDrawItem := nil;
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.EndUpdate;
begin
  FNoScrollBarTreeView.OnCustomDrawItem := FNoScrollBarTreeView.TreeViewCustomDrawItem;
  FNoScrollBarTreeView.Enabled := True;
  FNoScrollBarTreeView.EnableAlign;
  FNoScrollBarTreeView.Items.EndUpdate;
  Parent.EnableAlign;
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.Clear;
begin
  FEmployeeItems.Clear;
  FBranchItems.Clear;
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.HideSystemScrollBar;
begin
  SetComCtlStyle(FNoScrollBarTreeView, TVS_NOSCROLL, True);
  ShowScrollbar(FNoScrollBarTreeView.Handle, SB_BOTH, False);

  FNoScrollBarTreeView.Font.Name := '宋体';
  FNoScrollBarTreeView.Font.Size := 10;
  FNoScrollBarTreeView.FItemHeight := 22;
  TreeView_SetItemHeight(FNoScrollBarTreeView.Handle, FNoScrollBarTreeView.FItemHeight);
  FTreeViewScrollBar.FDrawing := False;
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.MoveScrollBarToTop;
begin
  ScrollBarTop := 0;
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.ExpandAllBranch(AExpanded: Boolean);
var
  iLoop: Integer;
  Branch: TRealICQBranch;
begin
  for iLoop := 0 to FBranchItems.Count - 1 do
  begin
    Branch := FBranchItems.Objects[iLoop] as TRealICQBranch;
    Branch.Node.Expanded := AExpanded;
  end; 
end;

//------------------------------------------------------------------------------
function TRealICQContacterTreeView.GetScrollBarTop: Integer;
begin
  Result := FNoScrollBarTreeView.Top;
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollBarTop(Value: Integer);
begin
  FNoScrollBarTreeView.Top := Value;
  FTreeViewScrollBar.DrawScrollBar;
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.ReAlignBranchs;
var
  Branch,
  TmpBranch: TRealICQBranch;
  iLoop, jLoop: Integer;
begin
  with FBranchs do
  begin
    for iLoop := 0 to Count - 1 do
    begin 
      Branch := TRealICQBranch(Objects[iLoop]);
      for jLoop := 0 to Count - 1 do {添加至父部门}
      begin
        if iLoop = jLoop then continue;
       
        TmpBranch := TRealICQBranch(Objects[jLoop]);
        if AnsiSameText(Branch.ParentID, TmpBranch.BranchID) then
        begin
          if Branch.Node.Parent = TmpBranch.Node then continue;
         
          Branch.Node.MoveTo(TmpBranch.Node, naAddChild);
          TmpBranch.Node.Expanded := False;
          Break;
        end;
      end;
    end;
  end;
 
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.ReDrawAll;
begin
  FNoScrollBarTreeView.Repaint;
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollTopButtonPictureNormal(Value: TPicture);
begin
  FScrollTopButtonPictureNormal.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollTopButtonPictureHover(Value: TPicture);
begin
  FScrollTopButtonPictureHover.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollTopButtonPictureDown(Value: TPicture);
begin
  FScrollTopButtonPictureDown.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollBottomButtonPictureNormal(Value: TPicture);
begin
  FScrollBottomButtonPictureNormal.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollBottomButtonPictureHover(Value: TPicture);
begin
  FScrollBottomButtonPictureHover.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollBottomButtonPictureDown(Value: TPicture);
begin
  FScrollBottomButtonPictureDown.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollBarButtonTopPictureNormal(Value: TPicture);
begin
  FScrollBarButtonTopPictureNormal.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollBarButtonTopPictureHover(Value: TPicture);
begin
  FScrollBarButtonTopPictureHover.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollBarButtonTopPictureDown(Value: TPicture);
begin
  FScrollBarButtonTopPictureDown.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollBarButtonMiddlePictureNormal(Value: TPicture);
begin
  FScrollBarButtonMiddlePictureNormal.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollBarButtonMiddlePictureHover(Value: TPicture);
begin
  FScrollBarButtonMiddlePictureHover.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollBarButtonMiddlePictureDown(Value: TPicture);
begin
  FScrollBarButtonMiddlePictureDown.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollBarButtonBottomPictureNormal(Value: TPicture);
begin
  FScrollBarButtonBottomPictureNormal.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollBarButtonBottomPictureHover(Value: TPicture);
begin
  FScrollBarButtonBottomPictureHover.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollBarButtonBottomPictureDown(Value: TPicture);
begin
  FScrollBarButtonBottomPictureDown.Assign(Value);
end;

procedure TRealICQContacterTreeView.SetScrollBackgroundPictureNormal(Value: TPicture);
begin
  FScrollBackgroundPictureNormal.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollBackgroundPictureHover(Value: TPicture);
begin
  FScrollBackgroundPictureHover.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.SetScrollBackgroundPictureDown(Value: TPicture);
begin
  FScrollBackgroundPictureDown.Assign(Value);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.DoSelectItemChanged(Employee: TRealICQEmployee);
begin
  if Assigned(FOnSelectItemChanged) then FOnSelectItemChanged(Employee);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.DoItemClick(Employee: TRealICQEmployee);
begin
  if Assigned(FOnItemClick) then FOnItemClick(Employee);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.DoItemDoubleClick(Employee: TRealICQEmployee);
begin
  if Assigned(FOnItemDoubleClick) then FOnItemDoubleClick(Employee);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.DoItemMouseEnter(Employee: TRealICQEmployee);
begin
  if Assigned(FOnItemMouseEnter) then FOnItemMouseEnter(Employee);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.DoItemMouseLeave(Employee: TRealICQEmployee);
begin
  if Assigned(FOnItemMouseLeave) then FOnItemMouseLeave(Employee);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.DoItemFlashCaption(Employee: TRealICQEmployee);
begin
  if Assigned(FOnItemFlashCaption) then FOnItemFlashCaption(Employee);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.DoItemOnline(Employee: TRealICQEmployee);
begin
  if Assigned(FOnItemOnline) then FOnItemOnline(Employee);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.DoItemOffline(Employee: TRealICQEmployee);
begin
  if Assigned(FOnItemOffline) then FOnItemOffline(Employee);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.DoItemIconButtonClick(Employee: TRealICQEmployee; IconButtonType: TRealICQContacterTreeNodeIconButtonType);
begin
  if Assigned(FOnItemIconButtonClick) then FOnItemIconButtonClick(Self, Employee, IconButtonType);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.DoItemIconButtonDblClick(Employee: TRealICQEmployee; IconButtonType: TRealICQContacterTreeNodeIconButtonType);
begin
  if Assigned(FOnItemIconButtonDblClick) then FOnItemIconButtonDblClick(Self, Employee, IconButtonType);
end;

//------------------------------------------------------------------------------
procedure TRealICQContacterTreeView.ChangeUIColor(AColor: TColor);
begin
  FIconBtnDefaultColor := ConvertColorToColor(FIconBtnDefaultColor, AColor);
  FIconBtnLightColor := ConvertColorToColor(FIconBtnLightColor, AColor);
  FIconBtnShadownColor := ConvertColorToColor(FIconBtnShadownColor, AColor);

  FHeadImageBorderColor := ConvertColorToColor(HeadImageBorderColor, AColor);
  FHeadImageBackColor := ConvertColorToColor(HeadImageBackColor, AColor);
  FSelectedItemBorderColor := ConvertColorToColor(SelectedItemBorderColor, AColor);
  FSelectedItemBorderInnerColor := ConvertColorToColor(SelectedItemBorderInnerColor, AColor);
  FSelectedItemBackColor := ConvertColorToColor(SelectedItemBackColor, AColor);

  ConvertBitmapToColor(FBranchClosedButtonPicture.Bitmap, AColor);
  ConvertBitmapToColor(FBranchOpenedButtonPicture.Bitmap, AColor);

  ConvertBitmapToColor(FSelectedItemBackgroud.Bitmap, AColor);
 
  ConvertBitmapToColor(FScrollTopButtonPictureNormal.Bitmap, AColor);
  ConvertBitmapToColor(FScrollTopButtonPictureHover.Bitmap, AColor);
  ConvertBitmapToColor(FScrollTopButtonPictureDown.Bitmap, AColor);

  ConvertBitmapToColor(FScrollBottomButtonPictureNormal.Bitmap, AColor);
  ConvertBitmapToColor(FScrollBottomButtonPictureHover.Bitmap, AColor);
  ConvertBitmapToColor(FScrollBottomButtonPictureDown.Bitmap, AColor);

  ConvertBitmapToColor(FScrollBarButtonTopPictureNormal.Bitmap, AColor);
  ConvertBitmapToColor(FScrollBarButtonTopPictureHover.Bitmap, AColor);
  ConvertBitmapToColor(FScrollBarButtonTopPictureDown.Bitmap, AColor);

  ConvertBitmapToColor(FScrollBarButtonMiddlePictureNormal.Bitmap, AColor);
  ConvertBitmapToColor(FScrollBarButtonMiddlePictureHover.Bitmap, AColor);
  ConvertBitmapToColor(FScrollBarButtonMiddlePictureDown.Bitmap, AColor);

  ConvertBitmapToColor(FScrollBarButtonBottomPictureNormal.Bitmap, AColor);
  ConvertBitmapToColor(FScrollBarButtonBottomPictureHover.Bitmap, AColor);
  ConvertBitmapToColor(FScrollBarButtonBottomPictureDown.Bitmap, AColor);

  ConvertBitmapToColor(FScrollBackgroundPictureNormal.Bitmap, AColor);
  ConvertBitmapToColor(FScrollBackgroundPictureHover.Bitmap, AColor);
  ConvertBitmapToColor(FScrollBackgroundPictureDown.Bitmap, AColor);

  FTreeViewScrollBar.FAssignedPicture := False;
  FTreeViewScrollBar.DrawScrollBar;

  FNoScrollBarTreeView.Repaint;
end;

//------------------------------------------------------------------------------
constructor TRealICQContacterTreeView.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Color := clWhite;
  DoubleBuffered := True;
  BevelInner := bvNone;
  BevelOuter := bvNone;
  AutoSize := True;
 
  Width := 200;
  Height := 300;

  FBranchs := TStringList.Create;
  FEmployees := TStringList.Create;
  FBranchItems := TRealICQBranchListItems.Create(Self);
  FEmployeeItems := TRealICQEmployeeListItems.Create(Self);

  FTimer := TTimer.Create(Self);
  FTimer.Interval := 600;
  FTimer.Enabled := False;
  FTimer.OnTimer := TimerOnTimer;
  FHintWindow := TSingleBorderHintWindow.Create(Self);
  FHintWindow.Visible := False;
  FTimerItemIndex := -1;
 
  FSelectedItemBackgroud := TPicture.Create;
  FDefaultPicture := TPicture.Create;
  FDefaultPictureOffline := TPicture.Create;
  FLeavePicture := TPicture.Create;
 
  FCameraIcon := TIcon.Create;
  FTelephoneIcon := TIcon.Create;
  FMobilePhoneIcon := TIcon.Create;
  FEmailIcon := TIcon.Create;
  FSMSIcon := TIcon.Create;

  FShowHeadImageButton := True;
  FShowEmailButton := True;
  FShowSMSButton := True;
  FShowTelButton := True;
  FShowMobileButton := True;
  FShowCameraButton := True;

  FIconBtnDefaultColor := clWhite;
  FIconBtnLightColor := clSilver;
  FIconBtnShadownColor := cl3DDkShadow;

  FBranchExpandedPicture := TPicture.Create;
  FBranchCollapsedPicture := TPicture.Create;

  FBranchClosedButtonPicture := TPicture.Create;
  FBranchOpenedButtonPicture := TPicture.Create;

  FStyle := lsSmallHeadImage;
  FCaptionStyle := csDisplayName;
  FAdjustPosition := False;
  FShowLine := True;
  FShowBranchImage := True;
  FFlashCaptionOnOnline := False;
  FOnlineNumeric := 0;
 
  FScrollTopButtonPictureNormal := TPicture.Create;
  FScrollTopButtonPictureHover := TPicture.Create;
  FScrollTopButtonPictureDown := TPicture.Create;

  FScrollBottomButtonPictureNormal := TPicture.Create;
  FScrollBottomButtonPictureHover := TPicture.Create;
  FScrollBottomButtonPictureDown := TPicture.Create;

  FScrollBarButtonTopPictureNormal := TPicture.Create;
  FScrollBarButtonTopPictureHover := TPicture.Create;
  FScrollBarButtonTopPictureDown := TPicture.Create;

  FScrollBarButtonMiddlePictureNormal := TPicture.Create;
  FScrollBarButtonMiddlePictureHover := TPicture.Create;
  FScrollBarButtonMiddlePictureDown := TPicture.Create;

  FScrollBarButtonBottomPictureNormal := TPicture.Create;
  FScrollBarButtonBottomPictureHover := TPicture.Create;
  FScrollBarButtonBottomPictureDown := TPicture.Create;

  FScrollBackgroundPictureNormal := TPicture.Create;
  FScrollBackgroundPictureHover := TPicture.Create;
  FScrollBackgroundPictureDown := TPicture.Create;

  FNoScrollBarTreeView := TRealICQNoScrollBarTreeView.Create(Self);
  FNoScrollBarTreeView.Parent := Self;
  FNoScrollBarTreeView.Left := 0;
  FNoScrollBarTreeView.Top := 0;
  FNoScrollBarTreeView.Width := Width;
  FNoScrollBarTreeView.Height := 0;
  FNoScrollBarTreeView.Anchors := [akLeft, akTop, akRight];
  FNoScrollBarTreeView.FContacterTreeView := Self;
  FNoScrollBarTreeView.BorderStyle := bsNone;
  FNoScrollBarTreeView.ReadOnly := True;
  FNoScrollBarTreeView.HideSelection := False;
  FNoScrollBarTreeView.RightClickSelect := False;
  FNoScrollBarTreeView.MultiSelect := False;

  FTreeViewScrollBar := TTreeViewScrollBar.Create(Self);
  FTreeViewScrollBar.Parent := Self;
  FTreeViewScrollBar.Align := alRight;
  FTreeViewScrollBar.DoubleBuffered := True;
  FTreeViewScrollBar.FContacterTreeView := Self;

  OnResize := WhenResize;

  FNoScrollBarTreeView.OnChange := FTreeViewScrollBar.TreeViewChange;
  FNoScrollBarTreeView.OnExpanded := FTreeViewScrollBar.TreeViewExpanded;
  FNoScrollBarTreeView.OnCollapsed := FTreeViewScrollBar.TreeViewCollapsed;

  FNoScrollBarTreeView.OnResize := FTreeViewScrollBar.TreeViewResize;
  FNoScrollBarTreeView.OnMouseWheelDown := FTreeViewScrollBar.TreeViewMouseWheelDown;
  FNoScrollBarTreeView.OnMouseWheelUp := FTreeViewScrollBar.TreeViewMouseWheelUp;
end;

//------------------------------------------------------------------------------
destructor TRealICQContacterTreeView.Destroy;
begin
  try
    FNoScrollBarTreeView.OnChange := nil;
    FNoScrollBarTreeView.OnExpanded := nil;
    FNoScrollBarTreeView.OnCollapsed := nil;

    FNoScrollBarTreeView.OnResize := nil;
    FNoScrollBarTreeView.OnMouseWheelDown := nil;
    FNoScrollBarTreeView.OnMouseWheelUp := nil;

    FreeAndNil(FTimer);
    FreeAndNil(FBranchs);
    FreeAndNil(FEmployees);
    FreeAndNil(FBranchItems);
    FreeAndNil(FEmployeeItems);

    FreeAndNil(FScrollBackgroundPictureDown);
    FreeAndNil(FScrollBackgroundPictureHover);
    FreeAndNil(FScrollBackgroundPictureNormal);

    FreeAndNil(FScrollBarButtonBottomPictureDown);
    FreeAndNil(FScrollBarButtonBottomPictureHover);
    FreeAndNil(FScrollBarButtonBottomPictureNormal);

    FreeAndNil(FScrollBarButtonMiddlePictureDown);
    FreeAndNil(FScrollBarButtonMiddlePictureHover);
    FreeAndNil(FScrollBarButtonMiddlePictureNormal);

    FreeAndNil(FScrollBarButtonTopPictureDown);
    FreeAndNil(FScrollBarButtonTopPictureHover);
    FreeAndNil(FScrollBarButtonTopPictureNormal);

    FreeAndNil(FScrollBottomButtonPictureDown);
    FreeAndNil(FScrollBottomButtonPictureHover);
    FreeAndNil(FScrollBottomButtonPictureNormal);

    FreeAndNil(FScrollTopButtonPictureDown);
    FreeAndNil(FScrollTopButtonPictureHover);
    FreeAndNil(FScrollTopButtonPictureNormal);

    FreeAndNil(FBranchClosedButtonPicture);
    FreeAndNil(FBranchOpenedButtonPicture);

    FreeAndNil(FBranchExpandedPicture);
    FreeAndNil(FBranchCollapsedPicture);

    FreeAndNil(FSelectedItemBackgroud);
    FreeAndNil(FDefaultPicture);
    FreeAndNil(FDefaultPictureOffline);
    FreeAndNil(FLeavePicture);
   
    FreeAndNil(FCameraIcon);
    FreeAndNil(FTelephoneIcon);
    FreeAndNil(FMobilePhoneIcon);
    FreeAndNil(FEmailIcon);
    FreeAndNil(FSMSIcon);

    FreeAndNil(FTreeViewScrollBar);
    FreeAndNil(FNoScrollBarTreeView);
   
    FHintWindow.ReleaseHandle;
    FHintWindow.Free;
  finally
    inherited Destroy;
  end;
end;
{$endregion}

{TRealICQNoScrollBarTreeView}

{$region 'TRealICQNoScrollBarTreeView'}

//------------------------------------------------------------------------------
procedure TRealICQNoScrollBarTreeView.TreeViewMouseLeave(Sender: TObject);
var
  iLoop: Integer;
  Employee: TRealICQEmployee;
begin
  FContacterTreeView.FTimerItemIndex := -1;
  FContacterTreeView.FTimer.Enabled := False;
  FContacterTreeView.FHintWindow.ReleaseHandle;
  FContacterTreeView.FHintWindow.Visible := False;

  for iLoop := 0 to FContacterTreeView.FEmployees.Count - 1 do
  begin
    Employee := FContacterTreeView.FEmployees.Objects[iLoop] as TRealICQEmployee;
    if Employee.FMouseInRect then
    begin
      Employee.FMouseInRect := False;
      FContacterTreeView.DoItemMouseLeave(Employee);
    end;
   
    if Employee.FMouseInHeadImageRect then
    begin
      Employee.FMouseInHeadImageRect := False;
      Employee.Update;
    end;

    if Employee.FMouseInCameraRect then
    begin
      Employee.FMouseInCameraRect := False;
      Employee.Update;
    end;

    if Employee.FMouseInTelephoneRect then
    begin
      Employee.FMouseInTelephoneRect := False;
      Employee.Update;
    end;

    if Employee.FMouseInMobilePhoneRect then
    begin
      Employee.FMouseInMobilePhoneRect := False;
      Employee.Update;
    end;

    if Employee.FMouseInEmailRect then
    begin
      Employee.FMouseInEmailRect := False;
      Employee.Update;
    end;

    if Employee.FMouseInSMSRect then
    begin
      Employee.FMouseInSMSRect := False;
      Employee.Update;
    end;
  end;
end;

//------------------------------------------------------------------------------
procedure TRealICQNoScrollBarTreeView.TreeViewMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  P: TPoint;
  iLoop: Integer;
  Node: TTreeNode;
  Employee: TRealICQEmployee;
  procedure OpenHint;
  begin
    FContacterTreeView.FTimerItemIndex := Node.Index;
    if FContacterTreeView.FHintWindow.Visible then
    begin
      FContacterTreeView.ShowCustomHint(Node);
    end
    else
    begin
      FContacterTreeView.FTimer.Enabled := False;
      FContacterTreeView.FTimer.Enabled := True;
    end;
  end;
  procedure CloseHint;
  begin
    FContacterTreeView.FTimerItemIndex := -1;
    FContacterTreeView.FTimer.Enabled := False;
    FContacterTreeView.FHintWindow.ReleaseHandle;
    FContacterTreeView.FHintWindow.Visible := False;
  end;
  procedure ResetMouseInRectState;
  begin
    Employee.FMouseInTextRect := False;
    Employee.FMouseInHeadImageRect := False;
    Employee.FMouseInCameraRect := False;
    Employee.FMouseInTelephoneRect := False;
    Employee.FMouseInMobilePhoneRect := False;
    Employee.FMouseInEmailRect := False;
    Employee.FMouseInSMSRect := False;
  end;
begin
  P.X := X;
  P.Y := Y;
  Node := GetNodeAt(P.X, P.Y);
  if Node <> nil then
  begin
    for iLoop := 0 to FContacterTreeView.FEmployees.Count - 1 do
    begin
      Employee := FContacterTreeView.FEmployees.Objects[iLoop] as TRealICQEmployee;
      if (Employee.Node = Node) then continue;

      if Employee.FMouseInRect then
      begin
        Employee.FMouseInRect := False;
      end;
     
      if Employee.FMouseInTextRect then
      begin
        Employee.FMouseInTextRect := False;
        FContacterTreeView.DoItemMouseLeave(Employee);
      end;

      if Employee.FMouseInHeadImageRect then
      begin
        Employee.FMouseInHeadImageRect := False;
        Employee.Update;
      end;

      if Employee.FMouseInCameraRect then
      begin
        Employee.FMouseInCameraRect := False;
        Employee.Update;
      end;

      if Employee.FMouseInTelephoneRect then
      begin
        Employee.FMouseInTelephoneRect := False;
        Employee.Update;
      end;

      if Employee.FMouseInMobilePhoneRect then
      begin
        Employee.FMouseInMobilePhoneRect := False;
        Employee.Update;
      end;

      if Employee.FMouseInEmailRect then
      begin
        Employee.FMouseInEmailRect := False;
        Employee.Update;
      end;

      if Employee.FMouseInSMSRect then
      begin
        Employee.FMouseInSMSRect := False;
        Employee.Update;
      end;
    end;
   
    if Node.StateIndex = 1 then
    begin
      Employee := Node.Data;

      {$region '是否在文字区间'}
      if PtInRect(Employee.FTextRect, P) then
      begin
        if not Employee.FMouseInTextRect then
        begin
          ResetMouseInRectState;
          Employee.FMouseInTextRect := True;
          FContacterTreeView.DoItemMouseEnter(Employee);
          OpenHint;
          Exit;
        end;
      end
      else
      begin
        if Employee.FMouseInTextRect then
        begin
          Employee.FMouseInTextRect := False;
          CloseHint;
        end;
      end;
      {$endregion}

      {$region '是否在头像图标区间'}
      if PtInRect(Employee.FHeadImageRect, P) then
      begin
        if not Employee.FMouseInHeadImageRect then
        begin
          ResetMouseInRectState;
          Employee.FMouseInHeadImageRect := True;
          DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FHeadImageRect, ibUp);
          OpenHint;
          Exit;
        end;
      end
      else
      begin
        if Employee.FMouseInHeadImageRect then
        begin
          Employee.FMouseInHeadImageRect := False;
          Employee.Update;
          CloseHint;
        end;
      end;
      {$endregion}

      {$region '是否在摄像头图标区间'}
      if (Employee.HasCamera) and (Employee.LoginState <> stHidden) then
      begin
        if PtInRect(Employee.FCameraRect, P) then
        begin
          if not Employee.FMouseInCameraRect then
          begin
            ResetMouseInRectState;
            Employee.FMouseInCameraRect := True;
            DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FCameraRect, ibUp);
            OpenHint;
            Exit;
          end;
        end
        else
        begin
          if Employee.FMouseInCameraRect then
          begin
            Employee.FMouseInCameraRect := False;
            Employee.Update;
            CloseHint;
          end;
        end;
      end;
      {$endregion}

      {$region '是否在坐机图标区间'}
      if (Employee.HasTelephone) then
      begin
        if PtInRect(Employee.FTelephoneRect, P) then
        begin
          if not Employee.FMouseInTelephoneRect then
          begin
            ResetMouseInRectState;
            Employee.FMouseInTelephoneRect := True;
            DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FTelephoneRect, ibUp);
            OpenHint;
            Exit;
          end;
        end
        else
        begin
          if Employee.FMouseInTelephoneRect then
          begin
            Employee.FMouseInTelephoneRect := False;
            Employee.Update;
            CloseHint;
          end;
        end;
      end;
      {$endregion}
        
      {$region '是否在手机图标区间'}
      if (Employee.HasMobilePhone) then
      begin
        if PtInRect(Employee.FMobilePhoneRect, P) then
        begin
          if not Employee.FMouseInMobilePhoneRect then
          begin
            ResetMouseInRectState;
            Employee.FMouseInMobilePhoneRect := True;
            DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FMobilePhoneRect, ibUp);
            OpenHint;
            Exit;
          end;
        end
        else
        begin
          if Employee.FMouseInMobilePhoneRect then
          begin
            Employee.FMouseInMobilePhoneRect := False;
            Employee.Update;
            CloseHint;
          end;
        end;
      end;
      {$endregion}

      {$region '是否在邮箱图标区间'}
      if (Employee.HasEmail) then
      begin
        if PtInRect(Employee.FEmailRect, P) then
        begin
          if not Employee.FMouseInEmailRect then
          begin
            ResetMouseInRectState;
            Employee.FMouseInEmailRect := True;
            DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FEmailRect, ibUp);
            OpenHint;
            Exit;
          end;
        end
        else
        begin
          if Employee.FMouseInEmailRect then
          begin
            Employee.FMouseInEmailRect := False;
            Employee.Update;
            CloseHint;
          end;
        end;
      end;
      {$endregion}
     
      {$region '是否在短信图标区间'}
      if (Employee.HasSMS) then
      begin
        if PtInRect(Employee.FSMSRect, P) then
        begin
          if not Employee.FMouseInSMSRect then
          begin
            ResetMouseInRectState;
            Employee.FMouseInSMSRect := True;
            DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FSMSRect, ibUp);
            OpenHint;
            Exit;
          end;
        end
        else
        begin
          if Employee.FMouseInSMSRect then
          begin
            Employee.FMouseInSMSRect := False;
            Employee.Update;
            CloseHint;
          end;
        end;
      end;
      {$endregion}
    end
    else
    begin
      CloseHint;
    end;

  end;
end;

//------------------------------------------------------------------------------
procedure TRealICQNoScrollBarTreeView.TreeViewMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  Node: TTreeNode;
  Employee: TRealICQEmployee;
begin
  FContacterTreeView.FTimerItemIndex := -1;
  FContacterTreeView.FTimer.Enabled := False;
  FContacterTreeView.FHintWindow.ReleaseHandle;
  FContacterTreeView.FHintWindow.Visible := False;
 
  if Button = mbLeft then FMouseInDown := True;

  Node := GetNodeAt(X, Y);
  if Node <> nil then
  begin
    //if PtInRect(Node.DisplayRect(True), Point(X, Y)) then   
    Node.Selected:=True;
   
    if Node.StateIndex = 1 then
    begin
      FContacterTreeView.DoItemClick(Node.Data);

      if Button = mbLeft then
      begin
        Employee := Node.Data;
        if Employee.FMouseInHeadImageRect then
        begin
          DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FHeadImageRect, ibDown);
        end;

        if Employee.FMouseInCameraRect then
        begin
          DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FCameraRect, ibDown);
        end;

        if Employee.FMouseInTelephoneRect then
        begin
          DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FTelephoneRect, ibDown);
        end;

        if Employee.FMouseInMobilePhoneRect then
        begin
          DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FMobilePhoneRect, ibDown);
        end;

        if Employee.FMouseInEmailRect then
        begin
          DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FEmailRect, ibDown);
        end;

        if Employee.FMouseInSMSRect then
        begin
          DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FSMSRect, ibDown);
        end;
      end;
    end;
  end;
end;

//------------------------------------------------------------------------------
procedure TRealICQNoScrollBarTreeView.TreeViewMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  Node: TTreeNode;
  Employee: TRealICQEmployee;
begin
  FMouseInDown := False;

  Node := GetNodeAt(X, Y);
  if Node <> nil then
  begin
    if Node.StateIndex = 1 then
    begin
      if Button = mbLeft then
      begin
        Employee := Node.Data;
        if Employee.FMouseInHeadImageRect then
        begin
          DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FHeadImageRect, ibUp);
          FContacterTreeView.DoItemIconButtonClick(Employee, itHeadImage);
        end;

        if Employee.FMouseInCameraRect then
        begin
          DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FCameraRect, ibUp);
          FContacterTreeView.DoItemIconButtonClick(Employee, itCamera);
        end;

        if Employee.FMouseInTelephoneRect then
        begin
          DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FTelephoneRect, ibUp);
          FContacterTreeView.DoItemIconButtonClick(Employee, itTel);
        end;

        if Employee.FMouseInMobilePhoneRect then
        begin
          DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FMobilePhoneRect, ibUp);
          FContacterTreeView.DoItemIconButtonClick(Employee, itMobile);
        end;

        if Employee.FMouseInEmailRect then
        begin
          DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FEmailRect, ibUp);
          FContacterTreeView.DoItemIconButtonClick(Employee, itEmail);
        end;

        if Employee.FMouseInSMSRect then
        begin
          DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FSMSRect, ibUp);
          FContacterTreeView.DoItemIconButtonClick(Employee, itSMS);
        end;
      end;
    end;
  end;
end;

//------------------------------------------------------------------------------
procedure TRealICQNoScrollBarTreeView.TreeViewDblClick(Sender: TObject);
var
  Node: TTreeNode;
  P: TPoint;
  Employee: TRealICQEmployee;
begin
  P.X := Mouse.CursorPos.X;
  P.Y := Mouse.CursorPos.Y;
  P := ScreenToClient(P);
  Node := GetNodeAt(P.X, P.Y);
  if Node <> nil then
  begin
    if Node.StateIndex = 1 then
    begin
      Employee := Node.Data;
     
      if Employee.FMouseInHeadImageRect then
      begin
        FContacterTreeView.DoItemIconButtonDblClick(Employee, itHeadImage);
        Exit;
      end;

      if Employee.FMouseInCameraRect then
      begin
        FContacterTreeView.DoItemIconButtonDblClick(Employee, itCamera);
        Exit;
      end;

      if Employee.FMouseInTelephoneRect then
      begin
        FContacterTreeView.DoItemIconButtonDblClick(Employee, itTel);
        Exit;
      end;

      if Employee.FMouseInMobilePhoneRect then
      begin
        FContacterTreeView.DoItemIconButtonDblClick(Employee, itMobile);
        Exit;
      end;

      if Employee.FMouseInEmailRect then
      begin
        FContacterTreeView.DoItemIconButtonDblClick(Employee, itEmail);
        Exit;
      end;

      if Employee.FMouseInSMSRect then
      begin
        FContacterTreeView.DoItemIconButtonDblClick(Employee, itSMS);
        Exit;
      end;
     
      Employee.StopFlash;
      FContacterTreeView.DoItemDoubleClick(Employee);
    end;
  end;
end;

//------------------------------------------------------------------------------
procedure TRealICQNoScrollBarTreeView.DrawButton(ACanvas: TCanvas; ARect: TRect; Node: TTreeNode);
var
  AButtonPicture: TPicture;
  R: TRect;
  cx, cy, FButtonSize: Integer;
begin
  cx := ARect.Left + Indent div 2 - 2;
  cy := ARect.Top + (ARect.Bottom - ARect.Top) div 2;
  FButtonSize := 0;
  with ACanvas do
  begin
    Pen.Color := RealICQColors.ConvertColorToColor($00ABABAB, FContacterTreeView.FSelectedItemBorderColor);
    Pen.Style := psDot;

    if FContacterTreeView.FShowLine then
    begin
      //画水平线.
      if Node.HasChildren then
      begin
        Pen.Mode := pmCopy;
        PenPos := Point(cx + FButtonSize, cy);
        LineTo(ARect.Left + Indent + FButtonSize - 1, cy);
     
        Pen.Mode := pmNotXor;
        PenPos := Point(cx + FButtonSize + 1, cy);
        LineTo(ARect.Left + Indent + FButtonSize - 1 + 1, cy);
     
        Pen.Mode := pmNotXor;
        PenPos := Point(cx + FButtonSize + 2, cy);
        LineTo(ARect.Left + Indent + FButtonSize - 1 + 2, cy);
      end else
      begin
        Pen.Mode := pmCopy;
        PenPos := Point(cx, cy);
        LineTo(ARect.Left + Indent + FButtonSize - 1, cy);
     
        Pen.Mode := pmNotXor;
        PenPos := Point(cx + 1, cy);
        LineTo(ARect.Left + Indent + FButtonSize - 1 + 1, cy);
     
        Pen.Mode := pmNotXor;
        PenPos := Point(cx + 2, cy);
        LineTo(ARect.Left + Indent + FButtonSize - 1 + 2, cy);
      end;

      //画至上方的竖线.
      if Node.GetPrev <> nil then
      begin
        Pen.Mode := pmCopy;
        Pen.Style := psDot;
        PenPos := Point(cx, cy);
        LineTo(cx, ARect.Top);

        Pen.Mode := pmNotXor;
        PenPos := Point(cx, cy - 1);
        LineTo(cx, ARect.Top - 1);
     
        Pen.Mode := pmNotXor;
        PenPos := Point(cx, cy - 2);
        LineTo(cx, ARect.Top - 2);
      end;

      if ((Node.GetNextVisible <> nil) and (Node.GetNextVisible.Level = Node.Level))
        or (Node.GetNextSibling <> nil) then
      //画至下方的竖线.
      begin
        Pen.Mode := pmCopy;
        PenPos := Point(cx, cy + 2);
        LineTo(cx, ARect.Bottom);
     
        Pen.Mode := pmNotXor;
        PenPos := Point(cx, cy + 2 + 1);
        LineTo(cx, ARect.Bottom);
     
        Pen.Mode := pmNotXor;
        PenPos := Point(cx, cy + 2 + 2);
        LineTo(cx, ARect.Bottom);
      end;

    end; //if FContacterTreeView.FShowLine

    if Node.HasChildren or ((Node.StateIndex = 0) and not FContacterTreeView.FShowBranchImage) then
    begin
      AButtonPicture := TPicture.Create;
      try
        if (not Node.Expanded) or (Node.Count = 0) then
          AButtonPicture.Bitmap.Assign(FContacterTreeView.FBranchClosedButtonPicture.Graphic)
        else
          AButtonPicture.Bitmap.Assign(FContacterTreeView.FBranchOpenedButtonPicture.Graphic);

        //if Node.Count = 0 then
        //  ConvertBitmapToColor(AButtonPicture.Bitmap, clWhite);

        R.Left := ARect.Left + (Indent - AButtonPicture.Bitmap.Width) div 2 - 2;
        R.Top := ARect.Top + ((ARect.Bottom - ARect.Top) - AButtonPicture.Bitmap.Height) div 2 + 1;
        R.Right := R.Left + AButtonPicture.Bitmap.Width;
        R.Bottom := R.Top + AButtonPicture.Bitmap.Height;
        ACanvas.StretchDraw(R, AButtonPicture.Graphic);
      finally
        AButtonPicture.Free;
      end;
    end;

    if FContacterTreeView.FShowLine then
    begin
      //now connect vertical lines of higher level nodes.
      Node := Node.Parent;
      while Node <> nil do
      begin
        cx := cx - Indent;
        if Node.GetNextSibling <> nil then
        begin
          Pen.Mode := pmCopy;
          PenPos := Point(cx, ARect.Top + 1);
          LineTo(cx, ARect.Bottom);
       
          Pen.Mode := pmNotXor;
          PenPos := Point(cx, ARect.Top + 1 + 1);
          LineTo(cx, ARect.Bottom);
       
          Pen.Mode := pmNotXor;
          PenPos := Point(cx, ARect.Top + 1 + 2);
          LineTo(cx, ARect.Bottom);
        end;
        Node := Node.Parent;
      end; //while
    end; //if FContacterTreeView.FShowLine
  end;
 
  ACanvas.Pen.Mode := pmCopy;
  ACanvas.Pen.Style := psSolid;
end;

//------------------------------------------------------------------------------
procedure TRealICQNoScrollBarTreeView.DrawImage(var ACanvas: TCanvas; NodeRect: TRect; Node: TTreeNode);
var
  Employee: TRealICQEmployee;
  Branch: TRealICQBranch;
  ANodePicture: TPicture;
  DrawNodePicture,
  NeedDrawPictureBorder: Boolean;
  R: TRect;
  AddLeft, AddTop: Integer;
begin
  DrawNodePicture := True;
  AddLeft := 0;
  AddTop := 0;

  {$region '计算头像的位置,头像跳动时用到'}
  if Node.StateIndex = 1 then
  begin
    Employee := Node.Data;
    if Employee.FFlashStyle = fsJump then
    begin
      case Employee.FHeadImagePosition of
        1:begin
            AddLeft := -1;
            AddTop := +1;
          end;
        2:begin
            AddLeft := 0;
            AddTop := -1;
          end;
        3:begin
            AddLeft := +1;
            AddTop := +1;
          end;
        end;
    end
    else
    begin
      if Employee.FHeadImagePosition mod 2 = 0 then
        DrawNodePicture := True
      else
        DrawNodePicture := False;
    end;
  end;
  {$endregion'}

  ANodePicture := TPicture.Create;
  try
    if Node.StateIndex = 0 then
    begin
      NeedDrawPictureBorder := False;
      Branch := Node.Data;
      Node.Text := Branch.FBranchName;
      if Node.Expanded then
        ANodePicture.Bitmap.Assign(FContacterTreeView.FBranchExpandedPicture.Graphic)
      else
        ANodePicture.Bitmap.Assign(FContacterTreeView.BranchCollapsedPicture.Graphic);
    end
    else
    begin
      Employee := Node.Data;
      Node.Text := Employee.FLoginName;
      if (Employee.FHeadImagePicture.Graphic <> nil) and (FContacterTreeView.FStyle <> lsNoHeadImage) then
      begin
        NeedDrawPictureBorder := True;
        ANodePicture.Bitmap.Assign(Employee.FHeadImagePicture.Graphic);
      end
      else
      begin
        NeedDrawPictureBorder := False;
        ANodePicture.Bitmap.Assign(FContacterTreeView.FDefaultPicture.Graphic);
      end;
     
      if (Employee.FLoginState = stOffline) or (Employee.FLoginState = stHidden) then
      begin
        if (FContacterTreeView.FDefaultPictureOffline.Graphic <> nil) and
           ((Employee.FHeadImagePicture.Graphic = nil) or (FContacterTreeView.FStyle = lsNoHeadImage)) then
          ANodePicture.Bitmap.Assign(FContacterTreeView.FDefaultPictureOffline.Graphic)
        else
          RealICQColors.Grayscale(ANodePicture.Bitmap);
      end;
    end;

    if NeedDrawPictureBorder and DrawNodePicture then
    begin
      //画头像边框
      ACanvas.Pen.Color := FContacterTreeView.FHeadImageBorderColor;
      ACanvas.Brush.Color := FContacterTreeView.FHeadImageBackColor;
      if Node.StateIndex = 1 then
      begin
        Employee := Node.Data;
        if (Employee.FLoginState = stOffline) or (Employee.FLoginState = stHidden) then
          ACanvas.Pen.Color := ConvertColorToColor(ACanvas.Pen.Color, clGray);
      end;
      R.Left := NodeRect.Left - 2 + AddLeft;
      R.Top := NodeRect.Top + ((NodeRect.Bottom - NodeRect.Top) - 20) div 2 + AddTop;
      R.Right := R.Left + 20;
      R.Bottom := R.Top + 20;
      ACanvas.Rectangle(R);
    end;
   
    R.Left := NodeRect.Left + AddLeft;
    R.Top := NodeRect.Top + ((NodeRect.Bottom - NodeRect.Top) - 16) div 2 + AddTop;
    R.Right := R.Left + 16;
    R.Bottom := R.Top + 16;
   
    if Node.StateIndex = 1 then
    begin
      Employee := Node.Data;
      Employee.FMouseInHeadImageRect := False;
      Employee.FHeadImageRect.Left := 0;
      Employee.FHeadImageRect.Top := 0;
      Employee.FHeadImageRect.Right := 0;
      Employee.FHeadImageRect.Bottom := 0;
      if DrawNodePicture then
      begin
        ACanvas.StretchDraw(R, ANodePicture.Graphic);

        if FContacterTreeView.FShowHeadImageButton then
        begin
          Employee := Node.Data;
          Employee.FHeadImageRect.Left := Node.DisplayRect(False).Left + R.Left - 2;
          Employee.FHeadImageRect.Top := Node.DisplayRect(False).Top + R.Top - 2;
          Employee.FHeadImageRect.Right := Employee.FHeadImageRect.Left + 20;
          Employee.FHeadImageRect.Bottom := Employee.FHeadImageRect.Top + 20;
        end;

        if PtInRect(Employee.FHeadImageRect, ScreenToClient(Mouse.CursorPos)) then
        begin
          if not Employee.FMouseInHeadImageRect then
          begin
            if FMouseInDown then
            begin
              Employee.FMouseInHeadImageRect := True;
              DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FHeadImageRect, ibDown);
            end;
          end;
        end;
      end;
    end
    else
    begin
      if DrawNodePicture then
        ACanvas.StretchDraw(R, ANodePicture.Graphic);
    end;

    if Node.StateIndex = 1 then
    begin
      Employee := Node.Data;
      if Employee.FLoginState = stLeave then
      begin
        R.Left := R.Right - FContacterTreeView.FLeavePicture.Width;
        R.Top := R.Bottom - FContacterTreeView.FLeavePicture.Height;
        ACanvas.StretchDraw(R, FContacterTreeView.FLeavePicture.Graphic);
      end;
    end;
  finally
    ANodePicture.Free;
  end;
end;

//------------------------------------------------------------------------------
procedure TRealICQNoScrollBarTreeView.DrawContacterItem(ACanvas: TCanvas; Node: TTreeNode; Rect: TRect; State: TCustomDrawState);
var
  R: TRect;
  ACaption,
  ALeaveMessage,
  ADisplayMessage: String;
  ACaptionWidth,
  ALeaveMessageWidth,
  ADisplayMessageWidth: Integer;

  Employee: TRealICQEmployee;
  Branch: TRealICQBranch;

  DecWidthForSmallIcon: Integer;
begin
  ACanvas.FillRect(Rect);

  //画展开收起按钮
  Rect.Left := Rect.Left + ((Node.Level) * Indent);
  DrawButton(ACanvas, Rect, Node);

  if (not FContacterTreeView.FShowLine) and
     (not FContacterTreeView.FShowBranchImage) then
  begin
    if (Node.StateIndex = 1) then
      Rect.Left := Rect.Left - ((Node.Level) * Indent) + 8
    else
      Rect.Left := Rect.Left - ((Node.Level) * Indent) - 5;    
  end;

  DecWidthForSmallIcon := 0;
  if Node.StateIndex = 1 then
  begin
    Employee := TRealICQEmployee(Node.Data);
    with Employee do
    begin
      FCameraRect.Left := 0;
      FCameraRect.Top := 0;
      FCameraRect.Right := 0;
      FCameraRect.Bottom := 0;
 
      FTelephoneRect.Left := 0;
      FTelephoneRect.Top := 0;
      FTelephoneRect.Right := 0;
      FTelephoneRect.Bottom := 0;

      FMobilePhoneRect.Left := 0;
      FMobilePhoneRect.Top := 0;
      FMobilePhoneRect.Right := 0;
      FMobilePhoneRect.Bottom := 0;

      FEmailRect.Left := 0;
      FEmailRect.Top := 0;
      FEmailRect.Right := 0;
      FEmailRect.Bottom := 0;

      FSMSRect.Left := 0;
      FSMSRect.Top := 0;
      FSMSRect.Right := 0;
      FSMSRect.Bottom := 0;

      FTextRect.Left := 0;
      FTextRect.Top := 0;
      FTextRect.Right := 0;
      FTextRect.Bottom := 0;
    end;

    {$region '绘制摄像头图标'}
    if Employee.FHasCamera then
    begin
      if (Employee.FLoginState <> stOffline) and (Employee.FLoginState <> stHidden) then
      begin
        Inc(DecWidthForSmallIcon, 24);
        R.Left := Rect.Right - DecWidthForSmallIcon + (24 - 16) div 2;
        R.Top := Rect.Top + (Rect.Bottom - Rect.Top - 16) div 2;
        R.Right := R.Left + 16;
        R.Bottom := R.Top + 16;
        DrawIconEx(ACanvas.Handle, R.Left, R.Top, FContacterTreeView.FCameraIcon.Handle, 16, 16, 0, 0, DI_NORMAL);
        //ACanvas.StretchDraw(R, FContacterTreeView.FCameraIconBitmap);
        Employee.FCameraRect.Left := Node.DisplayRect(False).Left + R.Left - 2;
        Employee.FCameraRect.Top := Node.DisplayRect(False).Top + R.Top - 2;
        Employee.FCameraRect.Right := Employee.FCameraRect.Left + 20;
        Employee.FCameraRect.Bottom := Employee.FCameraRect.Top + 20;
        if PtInRect(Employee.FCameraRect, ScreenToClient(Mouse.CursorPos)) then
        begin
          if not Employee.FMouseInCameraRect then
          begin
            if FMouseInDown then
            begin
              Employee.FMouseInCameraRect := True;
              DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FCameraRect, ibDown);
            end;
          end;
        end;
      end;
    end;
    {$endregion}

    {$region '绘制坐机图标'}
    if Employee.FHasTelephone then
    begin
        Inc(DecWidthForSmallIcon, 24);
        R.Left := Rect.Right - DecWidthForSmallIcon + (24 - 16) div 2;
        R.Top := Rect.Top + (Rect.Bottom - Rect.Top - 16) div 2;
        R.Right := R.Left + 16;
        R.Bottom := R.Top + 16;
        DrawIconEx(ACanvas.Handle, R.Left, R.Top, FContacterTreeView.FTelephoneIcon.Handle, 16, 16, 0, 0, DI_NORMAL);
        //ACanvas.StretchDraw(R, FContacterTreeView.FCameraIconBitmap);
        Employee.FTelephoneRect.Left := Node.DisplayRect(False).Left + R.Left - 2;
        Employee.FTelephoneRect.Top := Node.DisplayRect(False).Top + R.Top - 2;
        Employee.FTelephoneRect.Right := Employee.FTelephoneRect.Left + 20;
        Employee.FTelephoneRect.Bottom := Employee.FTelephoneRect.Top + 20;
        if PtInRect(Employee.FTelephoneRect, ScreenToClient(Mouse.CursorPos)) then
        begin
          if not Employee.FMouseInTelephoneRect then
          begin
            if FMouseInDown then
            begin
              Employee.FMouseInTelephoneRect := True;
              DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FTelephoneRect, ibDown);
            end;
          end;
        end;
    end;
    {$endregion}

    {$region '绘制手机图标'}
    if Employee.FHasMobilePhone then
    begin
        Inc(DecWidthForSmallIcon, 24);
        R.Left := Rect.Right - DecWidthForSmallIcon + (24 - 16) div 2;
        R.Top := Rect.Top + (Rect.Bottom - Rect.Top - 16) div 2;
        R.Right := R.Left + 16;
        R.Bottom := R.Top + 16;
        DrawIconEx(ACanvas.Handle, R.Left, R.Top, FContacterTreeView.FMobilePhoneIcon.Handle, 16, 16, 0, 0, DI_NORMAL);
        //ACanvas.StretchDraw(R, FContacterTreeView.FCameraIconBitmap);
        Employee.FMobilePhoneRect.Left := Node.DisplayRect(False).Left + R.Left - 2;
        Employee.FMobilePhoneRect.Top := Node.DisplayRect(False).Top + R.Top - 2;
        Employee.FMobilePhoneRect.Right := Employee.FMobilePhoneRect.Left + 20;
        Employee.FMobilePhoneRect.Bottom := Employee.FMobilePhoneRect.Top + 20;
        if PtInRect(Employee.FMobilePhoneRect, ScreenToClient(Mouse.CursorPos)) then
        begin
          if not Employee.FMouseInMobilePhoneRect then
          begin
            if FMouseInDown then
            begin
              Employee.FMouseInMobilePhoneRect := True;
              DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FMobilePhoneRect, ibDown);
            end;
          end;
        end;
    end;
    {$endregion}  

    {$region '绘制信箱图标'}
    if Employee.FHasEmail then
    begin
        Inc(DecWidthForSmallIcon, 24);
        R.Left := Rect.Right - DecWidthForSmallIcon + (24 - 16) div 2;
        R.Top := Rect.Top + (Rect.Bottom - Rect.Top - 16) div 2;
        R.Right := R.Left + 16;
        R.Bottom := R.Top + 16;
        DrawIconEx(ACanvas.Handle, R.Left, R.Top, FContacterTreeView.FEmailIcon.Handle, 16, 16, 0, 0, DI_NORMAL);
        Employee.FEmailRect.Left := Node.DisplayRect(False).Left + R.Left - 2;
        Employee.FEmailRect.Top := Node.DisplayRect(False).Top + R.Top - 2;
        Employee.FEmailRect.Right := Employee.FEmailRect.Left + 20;
        Employee.FEmailRect.Bottom := Employee.FEmailRect.Top + 20;
        if PtInRect(Employee.FEmailRect, ScreenToClient(Mouse.CursorPos)) then
        begin
          if not Employee.FMouseInEmailRect then
          begin
            if FMouseInDown then
            begin
              Employee.FMouseInEmailRect := True;
              DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FEmailRect, ibDown);
            end;
          end;
        end;
    end;
    {$endregion}    

    {$region '绘制短信图标'}
    if Employee.FHasSMS then
    begin
        Inc(DecWidthForSmallIcon, 24);
        R.Left := Rect.Right - DecWidthForSmallIcon + (24 - 16) div 2;
        R.Top := Rect.Top + (Rect.Bottom - Rect.Top - 16) div 2;
        R.Right := R.Left + 16;
        R.Bottom := R.Top + 16;
        DrawIconEx(ACanvas.Handle, R.Left, R.Top, FContacterTreeView.FSMSIcon.Handle, 16, 16, 0, 0, DI_NORMAL);
        Employee.FSMSRect.Left := Node.DisplayRect(False).Left + R.Left - 2;
        Employee.FSMSRect.Top := Node.DisplayRect(False).Top + R.Top - 2;
        Employee.FSMSRect.Right := Employee.FSMSRect.Left + 20;
        Employee.FSMSRect.Bottom := Employee.FSMSRect.Top + 20;
        if PtInRect(Employee.FSMSRect, ScreenToClient(Mouse.CursorPos)) then
        begin
          if not Employee.FMouseInSMSRect then
          begin
            if FMouseInDown then
            begin
              Employee.FMouseInSMSRect := True;
              DrawIconButton(Canvas, FContacterTreeView.FIconBtnDefaultColor, FContacterTreeView.FIconBtnLightColor, FContacterTreeView.FIconBtnShadownColor, Employee.FSMSRect, ibDown);
            end;
          end;
        end;
    end;
    {$endregion}

    with Employee do
    begin
      if not FContacterTreeView.FShowCameraButton then
      begin
        FCameraRect.Left := 0;
        FCameraRect.Top := 0;
        FCameraRect.Right := 0;
        FCameraRect.Bottom := 0;
      end;

      if not FContacterTreeView.FShowTelButton then
      begin
        FTelephoneRect.Left := 0;
        FTelephoneRect.Top := 0;
        FTelephoneRect.Right := 0;
        FTelephoneRect.Bottom := 0;
      end;

      if not FContacterTreeView.FShowMobileButton then
      begin
        FMobilePhoneRect.Left := 0;
        FMobilePhoneRect.Top := 0;
        FMobilePhoneRect.Right := 0;
        FMobilePhoneRect.Bottom := 0;
      end;

      if not FContacterTreeView.FShowEmailButton then
      begin
        FEmailRect.Left := 0;
        FEmailRect.Top := 0;
        FEmailRect.Right := 0;
        FEmailRect.Bottom := 0;
      end;

      if not FContacterTreeView.FShowSMSButton then
      begin
        FSMSRect.Left := 0;
        FSMSRect.Top := 0;
        FSMSRect.Right := 0;
        FSMSRect.Bottom := 0;
      end;
    end;
  end;

  //画图片
  if (Node.StateIndex = 1) or (FContacterTreeView.FShowBranchImage) then
  begin
    if not FContacterTreeView.FShowBranchImage then
      Rect.Left := Rect.Left + 8
    else
      Rect.Left := Rect.Left + 20;
    DrawImage(ACanvas, Rect, Node);
  end;

  ACanvas.Font.Name := '宋体';
  ACanvas.Font.Size := 9;
  Rect.Left := Rect.Left + 20;

  ALeaveMessageWidth := 0;
  ADisplayMessageWidth := 0;
 
  {$region '计算背景宽度,获取节点文字'}
  if Node.StateIndex = 0 then
  begin
    Branch := Node.Data;
    if (Branch.FEmployeeCount = 0) then
      ACaption := Branch.FBranchName
    else
      ACaption := Format('%s(%d/%d)',[Branch.FBranchName, Branch.FOnlineEmployee, Branch.FEmployeeCount]);
    ACaptionWidth := ACanvas.TextWidth(ACaption);
  end
  else
  begin
    Employee := Node.Data;
    if (Length(Employee.FDisplayName) = 0) or (FContacterTreeView.FCaptionStyle = csLoginName) then
      ACaption := Employee.FLoginName
    else if FContacterTreeView.FCaptionStyle = csDisplayName then
      ACaption := Employee.FDisplayName
    else if FContacterTreeView.FCaptionStyle = csDisplayNameAndLoginName then
      ACaption := Employee.FDisplayName + '<' + Employee.FLoginName + '>';
    ACaptionWidth := ACanvas.TextWidth(ACaption);

    if Employee.FLoginState = stLeave then
      ALeaveMessage := '(' + Employee.FLeaveMessage + ')'
    else
      ALeaveMessage := '';
    ALeaveMessageWidth := ACanvas.TextWidth(ALeaveMessage);

    if (Length(Employee.FWatchword) = 0) then
      ADisplayMessage := ''
    else
      ADisplayMessage:= ' - ' + Employee.FWatchword;
    ADisplayMessageWidth := ACanvas.TextWidth(ADisplayMessage);
  end;
  {$endregion}

  {$region '绘制选中状态的背景'}
  if cdsSelected in State then
  begin
    ACanvas.Pen.Color := FContacterTreeView.FSelectedItemBorderColor;
    ACanvas.Brush.Color := FContacterTreeView.FSelectedItemBackColor;
    R.Left := Rect.Left;
    R.Top := Rect.Top + 1;
    R.Right := Rect.Left + ACaptionWidth + ALeaveMessageWidth + ADisplayMessageWidth - 1 + 6;
    if R.Right >= Width - DecWidthForSmallIcon then R.Right := Width - DecWidthForSmallIcon - 1;
    R.Bottom := Rect.Bottom;
    ACanvas.RoundRect(R.Left, R.Top, R.Right, R.Bottom, 5, 5);
   
    R.Left := Rect.Left + 2;
    R.Top := Rect.Top + 3;
    R.Right := R.Right - 2;
    R.Bottom := Rect.Bottom - 2;
    ACanvas.StretchDraw(R, FContacterTreeView.FSelectedItemBackgroud.Graphic);

    ACanvas.Pen.Color := FContacterTreeView.SelectedItemBorderInnerColor;
    ACanvas.Brush.Style := bsClear;
    ACanvas.RoundRect(R.Left - 1, R.Top - 1, R.Right + 1, R.Bottom + 1, 3, 3);
  end;
  {$endregion'}

  {$region '绘制节点文字'}
  Rect.Left := Rect.Left + 3;
  R.Left := Rect.Left;
  R.Top := Rect.Top;
  R.Right := Rect.Left + ACaptionWidth + ALeaveMessageWidth + ADisplayMessageWidth - 1 + 2;
  if R.Right >= Width - DecWidthForSmallIcon then R.Right := Width - DecWidthForSmallIcon - 5;
  ACanvas.Brush.Style := bsClear;

  if Node.StateIndex = 0 then
  begin
    ACanvas.Font.Color := clBlack;
    ACanvas.TextRect(R, Rect.Left, Rect.Top + 6, ACaption);
  end
  else
  begin
    Employee := Node.Data;
    if Employee.FCaptionColor <> $00FFFFFF then
      ACanvas.Font.Color := Employee.FCaptionColor
    else if (Employee.FLoginState = stOffline) or (Employee.FLoginState = stHidden) then
      ACanvas.Font.Color := clGray
    else
      ACanvas.Font.Color := clBlack;
     
    ACanvas.TextRect(R, Rect.Left, Rect.Top + 6, ACaption);

    ACanvas.Font.Color := clGray;
    ACanvas.TextRect(R, Rect.Left + ACaptionWidth, Rect.Top + 6, ALeaveMessage);

    ACanvas.Font.Color := clGray;
    ACanvas.TextRect(R, Rect.Left + ACaptionWidth + ALeaveMessageWidth, Rect.Top + 6, ADisplayMessage);

    Employee.FTextRect.Left := Node.DisplayRect(False).Left + R.Left;
    Employee.FTextRect.Top := Node.DisplayRect(False).Top;
    Employee.FTextRect.Right := Employee.FTextRect.Left + (R.Right - R.Left);
    Employee.FTextRect.Bottom := Node.DisplayRect(False).Bottom;
  end;
  {$endregion}
end;

//------------------------------------------------------------------------------
procedure TRealICQNoScrollBarTreeView.TreeViewCustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
var
  NodeRect,
  R: TRect;

  Handle: HWND;
begin
  Handle := OpenMutex(mutex_all_access, False, '医药通2009');
  if Handle = 0 then Exit;
 
  DefaultDraw := False;
  try
    NodeRect := Node.DisplayRect(False);

//    if NodeRect.top - ABS(FContacterTreeView.FNoScrollBarTreeView.Top) > FContacterTreeView.Height then
//      Exit;
//    if NodeRect.Bottom - ABS(FContacterTreeView.FNoScrollBarTreeView.Top) < 0 then
//      Exit;

    //启用缓冲,先在 FBufferedBitmap 绘好图形
    FBufferedBitmap.Width := NodeRect.Right - NodeRect.Left;
    FBufferedBitmap.Height := NodeRect.Bottom - NodeRect.Top;
    FBufferedBitmap.Canvas.Brush.Color := clWhite;
    FBufferedBitmap.Canvas.Pen.Color := clBlack;

    R.Left:= 0;
    R.Top := 0;
    R.Right := FBufferedBitmap.Width;
    R.Bottom := FBufferedBitmap.Height;

    DrawContacterItem(FBufferedBitmap.Canvas, Node, R , State);

    Canvas.CopyRect(NodeRect, FBufferedBitmap.Canvas, R);
    //将绘好的图形复制到Canvas上去
  except
  end;
end;

//------------------------------------------------------------------------------
function TRealICQNoScrollBarTreeView.GetExpandedItemCount: Integer;
var
  Node: TTreeNode;
  ExpandedNodeCount: Integer;
begin
  ExpandedNodeCount := 0;
  Node := Items.GetFirstNode;
  while Node <> nil do
  begin
    if Node.IsVisible then Inc(ExpandedNodeCount, 1);
    Node := Node.GetNext;
  end;

  Result := ExpandedNodeCount;
end;

//------------------------------------------------------------------------------
procedure TRealICQNoScrollBarTreeView.WMEraseBKGND(var Message: TWMEraseBKGND);
begin
  Message.Result := 1; // 已处理
end;

//------------------------------------------------------------------------------
constructor TRealICQNoScrollBarTreeView.Create(AOwner: TComponent);
var
  ImageList: TImageList;
begin
  inherited Create(AOwner);
  FBufferedBitmap := Graphics.TBitMap.Create;

  ImageList := TImageList.Create(Self);
  ImageList.Width := 16;
  ImageList.Height := 16;

  Images := ImageList;
  OnCustomDrawItem := TreeViewCustomDrawItem;
  OnMouseDown := TreeViewMouseDown;
  OnMouseUp := TreeViewMouseUp;
  OnDblClick := TreeViewDblClick;
  OnMouseLeave := TreeViewMouseLeave;
  OnMouseMove := TreeViewMouseMove;
end;

//------------------------------------------------------------------------------
destructor TRealICQNoScrollBarTreeView.Destroy;
var
  ImageList: TImageList;
begin
  try
    FreeAndNil(FBufferedBitmap);
   
    ImageList := TImageList(Images);
    FreeAndNil(ImageList);
  finally
    inherited Destroy;
  end;
end;
{$endregion}

{TRealICQScrollBar}

{$region 'TRealICQScrollBar'}
//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.TopButtonImageMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  WaitTimes: Integer;
begin
  FTopButtonImage.Picture.Assign(FContacterTreeView.FScrollTopButtonPictureDown);
  FButtonDown := True;
  WaitTimes := 0;
  while FButtonDown do
  begin
    if (WaitTimes = 0) or (WaitTimes > 10) then
    begin
      if FContacterTreeView.FNoScrollBarTreeView.Top = 0 then Exit;
      FContacterTreeView.FNoScrollBarTreeView.Top := FContacterTreeView.FNoScrollBarTreeView.Top + FContacterTreeView.FNoScrollBarTreeView.ItemHeight;
      DrawScrollBar;
    end;
    Application.ProcessMessages;
    Sleep(30);
    Inc(WaitTimes);
  end;
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.TopButtonImageMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FTopButtonImage.Picture.Assign(FContacterTreeView.FScrollTopButtonPictureHover);
  FButtonDown := False;
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.TopButtonImageMouseEnter(Sender: TObject);
begin
  FTopButtonImage.Picture.Assign(FContacterTreeView.FScrollTopButtonPictureHover);
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.TopButtonImageMouseLeave(Sender: TObject);
begin
  FTopButtonImage.Picture.Assign(FContacterTreeView.FScrollTopButtonPictureNormal);
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.BottomButtonImageMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  WaitTimes: Integer;
begin
  FBottomButtonImage.Picture.Assign(FContacterTreeView.FScrollBottomButtonPictureDown);
  FButtonDown := True;
  WaitTimes := 0;
  while FButtonDown do
  begin
    if (WaitTimes = 0) or (WaitTimes > 10) then
    begin
      if FContacterTreeView.FNoScrollBarTreeView.Top <= -(FContacterTreeView.FNoScrollBarTreeView.Height - FContacterTreeView.Height) then Exit;
      FContacterTreeView.FNoScrollBarTreeView.Top := FContacterTreeView.FNoScrollBarTreeView.Top - FContacterTreeView.FNoScrollBarTreeView.ItemHeight;
      DrawScrollBar;
    end;
    Application.ProcessMessages;
    Sleep(30);
    Inc(WaitTimes);
  end;
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.BottomButtonImageMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FBottomButtonImage.Picture.Assign(FContacterTreeView.FScrollBottomButtonPictureHover);
  FButtonDown := False;
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.BottomButtonImageMouseEnter(Sender: TObject);
begin
  FBottomButtonImage.Picture.Assign(FContacterTreeView.FScrollBottomButtonPictureHover);
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.BottomButtonImageMouseLeave(Sender: TObject);
begin
  FBottomButtonImage.Picture.Assign(FContacterTreeView.FScrollBottomButtonPictureNormal);
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.BarButtonImageMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FBarButtonTopImage.Picture.Assign(FContacterTreeView.FScrollBarButtonTopPictureDown);
  FBarButtonMiddleImage.Picture.Assign(FContacterTreeView.FScrollBarButtonMiddlePictureDown);
  FBarButtonBottomImage.Picture.Assign(FContacterTreeView.FScrollBarButtonBottomPictureDown);
  FTrackingBarDown := True;
  FTrackingBarDonwY := Y;
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.BarButtonImageMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FBarButtonTopImage.Picture.Assign(FContacterTreeView.FScrollBarButtonTopPictureHover);
  FBarButtonMiddleImage.Picture.Assign(FContacterTreeView.FScrollBarButtonMiddlePictureHover);
  FBarButtonBottomImage.Picture.Assign(FContacterTreeView.FScrollBarButtonBottomPictureHover);
  FTrackingBarDown := False;
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.BarButtonImageMouseEnter(Sender: TObject);
begin
  FBarButtonTopImage.Picture.Assign(FContacterTreeView.FScrollBarButtonTopPictureHover);
  FBarButtonMiddleImage.Picture.Assign(FContacterTreeView.FScrollBarButtonMiddlePictureHover);
  FBarButtonBottomImage.Picture.Assign(FContacterTreeView.FScrollBarButtonBottomPictureHover);
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.BarButtonImageMouseLeave(Sender: TObject);
begin
  FBarButtonTopImage.Picture.Assign(FContacterTreeView.FScrollBarButtonTopPictureNormal);
  FBarButtonMiddleImage.Picture.Assign(FContacterTreeView.FScrollBarButtonMiddlePictureNormal);
  FBarButtonBottomImage.Picture.Assign(FContacterTreeView.FScrollBarButtonBottomPictureNormal);
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.BarButtonImageMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
var
  //ModeValue,
  MovedYValue, Increment: Integer;
begin
  if FTrackingBarDown then
  begin
    MovedYValue := (Y - FTrackingBarDonwY);
    FMovedYValue := FMovedYValue + MovedYValue;

    if FBarButtonTopImage.Top + MovedYValue < (FTopButtonImage.Height + 1) then
      FBarButtonTopImage.Top := (FTopButtonImage.Height + 1)
    else if FBarButtonTopImage.Top + MovedYValue > (FTopButtonImage.Height + 1) + FTrackingBarTopRange then
      FBarButtonTopImage.Top := (FTopButtonImage.Height + 1) + FTrackingBarTopRange
    else
      FBarButtonTopImage.Top := FBarButtonTopImage.Top + MovedYValue;

    FBarButtonMiddleImage.Top := FBarButtonTopImage.Top + FBarButtonTopImage.Height;
    FBarButtonBottomImage.Top := FBarButtonMiddleImage.Top + FBarButtonMiddleImage.Height;

    Increment := Round((FClientRange - FContacterTreeView.Height) * (FMovedYValue / FTrackingBarTopRange));

    if ABS(Increment) < FContacterTreeView.FNoScrollBarTreeView.ItemHeight then Exit;

    {
    ModeValue := Increment mod FContacterTreeView.FNoScrollBarTreeView.ItemHeight;
    if ModeValue <> 0 then
    begin
      if ModeValue > FContacterTreeView.FNoScrollBarTreeView.ItemHeight / 2 then
      begin
        Increment := Increment + (FContacterTreeView.FNoScrollBarTreeView.ItemHeight - ModeValue);
      end
      else
      begin
        Increment := Increment - ModeValue;
      end;
    end;
    }
   
    if FContacterTreeView.FNoScrollBarTreeView.Top - Increment > 0 then
      FContacterTreeView.FNoScrollBarTreeView.Top := 0
    else if FContacterTreeView.FNoScrollBarTreeView.Top - Increment <= -(FContacterTreeView.FNoScrollBarTreeView.Height - FContacterTreeView.Height) then
      FContacterTreeView.FNoScrollBarTreeView.Top := -(FContacterTreeView.FNoScrollBarTreeView.Height - FContacterTreeView.Height)
    else
      FContacterTreeView.FNoScrollBarTreeView.Top := FContacterTreeView.FNoScrollBarTreeView.Top - Increment;


    FMovedYValue := 0;
  end;
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.BackgroundImageMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  WaitTimes: Integer;
begin
  FBackgroundImage.Picture.Assign(FContacterTreeView.FScrollBackgroundPictureDown);
  if (Y > FBarButtonTopImage.Top - 10) and (Y < (FBarButtonBottomImage.Top + FBarButtonBottomImage.Height) + 10) then exit;
  FButtonDown := True;
  WaitTimes := 0;
  while FButtonDown do
  begin
    if (WaitTimes = 0) or (WaitTimes > 10) then
    begin
      if Y < FBarButtonTopImage.Top then
      begin
        if FContacterTreeView.FNoScrollBarTreeView.Top = 0 then Exit;
        if FContacterTreeView.FNoScrollBarTreeView.Top + FContacterTreeView.FNoScrollBarTreeView.ItemHeight*3 > 0 then
          FContacterTreeView.FNoScrollBarTreeView.Top := 0
        else
          FContacterTreeView.FNoScrollBarTreeView.Top := FContacterTreeView.FNoScrollBarTreeView.Top + FContacterTreeView.FNoScrollBarTreeView.ItemHeight*3;
      end
      else if Y > (FBarButtonBottomImage.Top + FBarButtonBottomImage.Height) then
      begin
        if FContacterTreeView.FNoScrollBarTreeView.Top <= -(FContacterTreeView.FNoScrollBarTreeView.Height - FContacterTreeView.Height) then Exit;
        if (FContacterTreeView.FNoScrollBarTreeView.Top - FContacterTreeView.FNoScrollBarTreeView.ItemHeight*3) < -(FContacterTreeView.FNoScrollBarTreeView.Height - FContacterTreeView.Height) then
          FContacterTreeView.FNoScrollBarTreeView.Top := -(FContacterTreeView.FNoScrollBarTreeView.Height - FContacterTreeView.Height)
        else
          FContacterTreeView.FNoScrollBarTreeView.Top := FContacterTreeView.FNoScrollBarTreeView.Top - FContacterTreeView.FNoScrollBarTreeView.ItemHeight*3;
      end;
     DrawScrollBar;
    end;
    Application.ProcessMessages;
    Sleep(30);
    Inc(WaitTimes);
  end;
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.BackgroundImageMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FBackgroundImage.Picture.Assign(FContacterTreeView.FScrollBackgroundPictureHover);
  FButtonDown := False;
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.BackgroundImageMouseEnter(Sender: TObject);
begin
  FBackgroundImage.Picture.Assign(FContacterTreeView.FScrollBackgroundPictureHover);
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.BackgroundImageMouseLeave(Sender: TObject);
begin
  FBackgroundImage.Picture.Assign(FContacterTreeView.FScrollBackgroundPictureNormal);
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.TreeViewChange(Sender: TObject; Node: TTreeNode);
begin
  if Node = nil then Exit;
 
  if Node.DisplayRect(False).Bottom - ABS(FContacterTreeView.FNoScrollBarTreeView.Top) > FContacterTreeView.Height then
    FContacterTreeView.FNoScrollBarTreeView.Top := FContacterTreeView.FNoScrollBarTreeView.Top - FContacterTreeView.FNoScrollBarTreeView.ItemHeight;

  if Node.DisplayRect(False).Top - ABS(FContacterTreeView.FNoScrollBarTreeView.Top) < 0 then
    FContacterTreeView.FNoScrollBarTreeView.Top := FContacterTreeView.FNoScrollBarTreeView.Top + FContacterTreeView.FNoScrollBarTreeView.ItemHeight;

  DrawScrollBar;

  if Node.StateIndex = 1 then
    FContacterTreeView.DoSelectItemChanged(Node.Data);
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.TreeViewExpanded(Sender: TObject; Node: TTreeNode);
var
  LastRange: Integer;
begin
  LastRange := FClientRange;
  DrawScrollBar;
  if Node.HasChildren then
  begin
    if Node.DisplayRect(False).Bottom - ABS(FContacterTreeView.FNoScrollBarTreeView.Top) > FContacterTreeView.Height - FContacterTreeView.FNoScrollBarTreeView.ItemHeight then
    begin
      FContacterTreeView.FNoScrollBarTreeView.Top := FContacterTreeView.FNoScrollBarTreeView.Top - (FClientRange - LastRange);
      DrawScrollBar;
    end;
  end;
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.TreeViewCollapsed(Sender: TObject; Node: TTreeNode);
begin
  DrawScrollBar;
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.TreeViewResize(Sender: TObject);
begin
  DrawScrollBar;
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.TreeViewMouseWheelUp(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
  if FContacterTreeView.FNoScrollBarTreeView.Top = 0 then Exit;
  FTrackingBarDown := True;
  FContacterTreeView.FNoScrollBarTreeView.Top := FContacterTreeView.FNoScrollBarTreeView.Top + FContacterTreeView.FNoScrollBarTreeView.ItemHeight;
  Handled := True;
  FTrackingBarDown := False;
  DrawScrollBar;
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.TreeViewMouseWheelDown(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
  if FContacterTreeView.FNoScrollBarTreeView.Top <= -(FContacterTreeView.FNoScrollBarTreeView.Height - FContacterTreeView.Height) then Exit;
  FTrackingBarDown := True;
  FContacterTreeView.FNoScrollBarTreeView.Top := FContacterTreeView.FNoScrollBarTreeView.Top - FContacterTreeView.FNoScrollBarTreeView.ItemHeight;
  Handled := True;
  FTrackingBarDown := False;
  DrawScrollBar;
end;

//------------------------------------------------------------------------------
procedure TTreeViewScrollBar.DrawScrollBar;
var
  FixedBarButtonHeight: Integer;
begin
  if FTrackingBarDown then Exit;
  if FDrawing then Exit;
  FDrawing := True;

  FClientRange := FContacterTreeView.FNoScrollBarTreeView.ExpandedItemCount * FContacterTreeView.FNoScrollBarTreeView.ItemHeight;

  FContacterTreeView.FNoScrollBarTreeView.OnResize := nil;
  DisableAlign;
  try
    FContacterTreeView.FNoScrollBarTreeView.Height := FClientRange;
    if FContacterTreeView.FNoScrollBarTreeView.Top <= -(FContacterTreeView.FNoScrollBarTreeView.Height - FContacterTreeView.Height) then
      if FContacterTreeView.FNoScrollBarTreeView.Height > FContacterTreeView.Height then
        FContacterTreeView.FNoScrollBarTreeView.Top := -(FContacterTreeView.FNoScrollBarTreeView.Height - FContacterTreeView.Height);
    if FContacterTreeView.FNoScrollBarTreeView.Top > 0 then FContacterTreeView.FNoScrollBarTreeView.Top := 0;
    if FContacterTreeView.Height >= FContacterTreeView.FNoScrollBarTreeView.Height then FContacterTreeView.FNoScrollBarTreeView.Top := 0;

    if (FClientRange <= FContacterTreeView.Height) or (FClientRange <= 0) then
    begin
      FContacterTreeView.FNoScrollBarTreeView.Width := FContacterTreeView.Width;
      Visible := False;
      Exit;
    end;
 
    FixedBarButtonHeight := FTopButtonImage.Height + FBottomButtonImage.Height;
    if (FixedBarButtonHeight >= FContacterTreeView.Height) then
    begin
      FContacterTreeView.FNoScrollBarTreeView.Width := FContacterTreeView.Width;
      Visible := False;
      Exit;
    end;

    FixedBarButtonHeight := FixedBarButtonHeight + FContacterTreeView.FScrollBarButtonTopPictureNormal.Height + FContacterTreeView.FScrollBarButtonBottomPictureNormal.Height + 2;
    if (FixedBarButtonHeight >= FContacterTreeView.Height) then
    begin
      FBarButtonTopImage.Visible := False;
      FBarButtonMiddleImage.Visible := False;
      FBarButtonBottomImage.Visible := False;
    end
    else
    begin
      FBarButtonTopImage.Visible := True;
      FBarButtonMiddleImage.Visible := True;
      FBarButtonBottomImage.Visible := True;
    end;

    FClientRange := FClientRange + FContacterTreeView.Height mod FContacterTreeView.FNoScrollBarTreeView.ItemHeight;
    FScrollRange := FContacterTreeView.Height -  FixedBarButtonHeight;

    Visible := True;
    Width := FContacterTreeView.FScrollTopButtonPictureNormal.Width;
    Height := FContacterTreeView.Height;
    FContacterTreeView.FNoScrollBarTreeView.Width := FContacterTreeView.Width - Width;

    if not FAssignedPicture then FTopButtonImage.Picture.Assign(FContacterTreeView.FScrollTopButtonPictureNormal);
    FTopButtonImage.Left := 0;
    FTopButtonImage.Top := 0;
 
    if not FAssignedPicture then FBottomButtonImage.Picture.Assign(FContacterTreeView.FScrollBottomButtonPictureNormal);
    FBottomButtonImage.Left := 0;
    FBottomButtonImage.Top := FContacterTreeView.Height - FTopButtonImage.Height;

    if not FAssignedPicture then FBarButtonTopImage.Picture.Assign(FContacterTreeView.FScrollBarButtonTopPictureNormal);
    FBarButtonTopImage.Left := 0;

    if not FAssignedPicture then FBarButtonMiddleImage.Picture.Assign(FContacterTreeView.FScrollBarButtonMiddlePictureNormal);
    FBarButtonMiddleImage.Left := 0;
    FBarButtonMiddleImage.Height := Round(FScrollRange * (FContacterTreeView.Height / FClientRange));
    FBarButtonMiddleImage.Width := FContacterTreeView.FScrollBarButtonMiddlePictureNormal.Width;

    if not FAssignedPicture then FBarButtonBottomImage.Picture.Assign(FContacterTreeView.FScrollBarButtonBottomPictureNormal);
    FBarButtonBottomImage.Left := 0;

    FTrackingBarTopRange := FScrollRange - FBarButtonMiddleImage.Height - 1;

    if FContacterTreeView.FNoScrollBarTreeView.Top = -(FContacterTreeView.FNoScrollBarTreeView.Height - FContacterTreeView.Height) then
      FBarButtonTopImage.Top := (FTopButtonImage.Height + 1) + FTrackingBarTopRange
    else
      FBarButtonTopImage.Top := (FTopButtonImage.Height + 1) + Round(FTrackingBarTopRange * (-FContacterTreeView.FNoScrollBarTreeView.Top/(FClientRange - FContacterTreeView.Height)));
    FBarButtonMiddleImage.Top := FBarButtonTopImage.Top + FBarButtonTopImage.Height;
    FBarButtonBottomImage.Top := FBarButtonMiddleImage.Top + FBarButtonMiddleImage.Height;

    if not FAssignedPicture then FBackgroundImage.Picture.Assign(FContacterTreeView.FScrollBackgroundPictureNormal);
    FBackgroundImage.SendToBack;

    FAssignedPicture := True;

  finally
    EnableAlign;
    FDrawing := False;
    FContacterTreeView.FNoScrollBarTreeView.OnResize := TreeViewResize;
    FContacterTreeView.FNoScrollBarTreeView.Repaint;
  end;
end;

//------------------------------------------------------------------------------
constructor TTreeViewScrollBar.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Width := 20;
  Height := 180;
  Caption := '';
  DoubleBuffered := True;
  ParentColor := True;
  BevelInner := bvNone;
  BevelOuter := bvNone;

  FDrawing := True;

  FTopButtonImage := TRealICQHoverImage.Create(Self);
  FTopButtonImage.Parent := Self;
  FTopButtonImage.AutoSize := True;
  FTopButtonImage.Transparent := True;
  FTopButtonImage.Anchors := [akLeft,akTop];
  FTopButtonImage.OnMouseEnter := TopButtonImageMouseEnter;
  FTopButtonImage.OnMouseLeave := TopButtonImageMouseLeave;
  FTopButtonImage.OnMouseDown := TopButtonImageMouseDown;
  FTopButtonImage.OnMouseUp := TopButtonImageMouseUp;

  FBottomButtonImage := TRealICQHoverImage.Create(Self);
  FBottomButtonImage.Parent := Self;
  FBottomButtonImage.AutoSize := True;
  FBottomButtonImage.Transparent := True;
  FBottomButtonImage.Anchors := [akLeft,akBottom];
  FBottomButtonImage.OnMouseEnter := BottomButtonImageMouseEnter;
  FBottomButtonImage.OnMouseLeave := BottomButtonImageMouseLeave;
  FBottomButtonImage.OnMouseDown := BottomButtonImageMouseDown;
  FBottomButtonImage.OnMouseUp := BottomButtonImageMouseUp;

  FBarButtonTopImage := TRealICQHoverImage.Create(Self);
  FBarButtonTopImage.Parent := Self;
  FBarButtonTopImage.AutoSize := True;
  FBarButtonTopImage.Transparent := False;
  FBarButtonTopImage.OnMouseEnter := BarButtonImageMouseEnter;
  FBarButtonTopImage.OnMouseLeave := BarButtonImageMouseLeave;
  FBarButtonTopImage.OnMouseDown := BarButtonImageMouseDown;
  FBarButtonTopImage.OnMouseUp := BarButtonImageMouseUp;
  FBarButtonTopImage.OnMouseMove := BarButtonImageMouseMove;

  FBarButtonMiddleImage := TRealICQHoverImage.Create(Self);
  FBarButtonMiddleImage.Parent := Self;
  FBarButtonMiddleImage.AutoSize := False;
  FBarButtonMiddleImage.Transparent := False;
  FBarButtonMiddleImage.Stretch := True;
  FBarButtonMiddleImage.OnMouseEnter := BarButtonImageMouseEnter;
  FBarButtonMiddleImage.OnMouseLeave := BarButtonImageMouseLeave;
  FBarButtonMiddleImage.OnMouseDown := BarButtonImageMouseDown;
  FBarButtonMiddleImage.OnMouseUp := BarButtonImageMouseUp;
  FBarButtonMiddleImage.OnMouseMove := BarButtonImageMouseMove;

  FBarButtonBottomImage := TRealICQHoverImage.Create(Self);
  FBarButtonBottomImage.Parent := Self;
  FBarButtonBottomImage.AutoSize := True;
  FBarButtonBottomImage.Transparent := False;
  FBarButtonBottomImage.OnMouseEnter := BarButtonImageMouseEnter;
  FBarButtonBottomImage.OnMouseLeave := BarButtonImageMouseLeave;
  FBarButtonBottomImage.OnMouseDown := BarButtonImageMouseDown;
  FBarButtonBottomImage.OnMouseUp := BarButtonImageMouseUp;
  FBarButtonBottomImage.OnMouseMove := BarButtonImageMouseMove;

  FBackgroundImage := TRealICQHoverImage.Create(Self);
  FBackgroundImage.Parent := Self;
  FBackgroundImage.AutoSize := False;
  FBackgroundImage.Stretch := True;
  FBackgroundImage.Transparent := False;
  FBackgroundImage.Align := alClient;
  FBackgroundImage.OnMouseEnter := BackgroundImageMouseEnter;
  FBackgroundImage.OnMouseLeave := BackgroundImageMouseLeave;
  FBackgroundImage.OnMouseDown := BackgroundImageMouseDown;
  FBackgroundImage.OnMouseUp := BackgroundImageMouseUp;

  FMovedYValue := 0;
end;

//------------------------------------------------------------------------------
destructor TTreeViewScrollBar.Destroy;
begin

  FreeAndNil(FBackgroundImage);
  FreeAndNil(FBarButtonBottomImage);
  FreeAndNil(FBarButtonMiddleImage);
  FreeAndNil(FBarButtonTopImage);
  FreeAndNil(FBottomButtonImage);
  FreeAndNil(FTopButtonImage);

  inherited Destroy;
end;

{$endregion}

{TRealICQBranchListItems}

{$region 'TRealICQBranchListItems'}
//------------------------------------------------------------------------------
constructor TRealICQBranchListItems.Create(AContacterTreeView: TRealICQContacterTreeView);
begin
  inherited Create;

  FContacterTreeView := AContacterTreeView;
end;

//------------------------------------------------------------------------------
destructor TRealICQBranchListItems.Destroy;
begin
  Clear; 
  inherited Destroy;
end;

//------------------------------------------------------------------------------
function TRealICQBranchListItems.GetObject(Index: Integer): TObject;
begin
  Result := FContacterTreeView.FBranchs.Objects[Index];
end;

//------------------------------------------------------------------------------
procedure TRealICQBranchListItems.Put(Index: Integer; const S: string);
begin
end;

//------------------------------------------------------------------------------
function TRealICQBranchListItems.Get(Index: Integer): string;
begin
  Result := FContacterTreeView.FBranchs[Index];
end;

//------------------------------------------------------------------------------
function TRealICQBranchListItems.GetCount: Integer;
begin
  Result := FContacterTreeView.FBranchs.Count;
end;

//------------------------------------------------------------------------------
function TRealICQBranchListItems.Add(const S: string): Integer;
begin
  Result := -1;
end;

//------------------------------------------------------------------------------
function TRealICQBranchListItems.AddObject(const S: string; AObject: TObject): Integer;
var
  Branch,
  TmpBranch: TRealICQBranch;
  iLoop: Integer;
begin
  Branch := AObject as TRealICQBranch;
  Branch.FContacterTreeView := FContacterTreeView;
  Branch.FNode := FContacterTreeView.FNoScrollBarTreeView.Items.AddChildObject(nil, Branch.FBranchName, Branch);
  Branch.FNode.StateIndex := 0;

  with FContacterTreeView.FBranchs do
  begin
    for iLoop :=0 to Count - 1 do {添加至父部门}
    begin
      TmpBranch := TRealICQBranch(Objects[iLoop]);
      if AnsiSameText(Branch.ParentID, TmpBranch.BranchID) then
      begin
        Branch.Node.MoveTo(TmpBranch.Node, naAddChild);
        TmpBranch.Node.Expanded := False;
        Break;
      end;
    end;
  end;
 
  //FContacterTreeView.FTreeViewScrollBar.DrawScrollBar;
  Result := FContacterTreeView.FBranchs.AddObject(S, Branch);
end;

//------------------------------------------------------------------------------
procedure TRealICQBranchListItems.Insert(Index: Integer; const S: string);
begin
end;

//------------------------------------------------------------------------------
procedure TRealICQBranchListItems.Move(CurIndex, NewIndex: Integer);
begin
  FContacterTreeView.FBranchs.Move(CurIndex, NewIndex);
end;

//------------------------------------------------------------------------------
procedure TRealICQBranchListItems.Clear;
begin
  if FContacterTreeView.FBranchs = nil then Exit;
  while Count > 0 do
  begin
    Delete(0);
  end;

  FContacterTreeView.FBranchs.Clear;
end;

//------------------------------------------------------------------------------
procedure TRealICQBranchListItems.Delete(Index: Integer);
var
  Branch: TRealICQBranch;
begin
  Branch := FContacterTreeView.FBranchs.Objects[Index] as TRealICQBranch;

  FreeAndNil(Branch);
  FContacterTreeView.FBranchs.Delete(Index);
end;

//------------------------------------------------------------------------------
function TRealICQBranchListItems.IndexOf(const S: string): Integer;
begin
  Result := FContacterTreeView.FBranchs.IndexOf(S);
end;
{$endregion}

{TRealICQEmployeeListItems}

{$region 'TRealICQEmployeeListItems'}
//------------------------------------------------------------------------------
constructor TRealICQEmployeeListItems.Create(AContacterTreeView: TRealICQContacterTreeView);
begin
  inherited Create;

  FContacterTreeView := AContacterTreeView;
end;

//------------------------------------------------------------------------------
destructor TRealICQEmployeeListItems.Destroy;
begin
  Clear; 
  inherited Destroy;
end;

//------------------------------------------------------------------------------
function TRealICQEmployeeListItems.GetObject(Index: Integer): TObject;
begin
  Result := FContacterTreeView.FEmployees.Objects[Index];
end;

//------------------------------------------------------------------------------
procedure TRealICQEmployeeListItems.Put(Index: Integer; const S: string);
begin
end;

//------------------------------------------------------------------------------
function TRealICQEmployeeListItems.Get(Index: Integer): string;
begin
  Result := FContacterTreeView.FEmployees[Index];
end;

//------------------------------------------------------------------------------
function TRealICQEmployeeListItems.GetCount: Integer;
begin
  Result := FContacterTreeView.FEmployees.Count;
end;

//------------------------------------------------------------------------------
function TRealICQEmployeeListItems.Add(const S: string): Integer;
begin
  Result := -1;
end;

function TRealICQEmployeeListItems.AddObject(const S: string; AObject: TObject): Integer;
var
  Employee: TRealICQEmployee;
  TmpBranch: TRealICQBranch;
  iLoop: Integer;

  ParentNode: TTreeNode;
begin
  Employee := AObject as TRealICQEmployee;
  Employee.FContacterTreeView := FContacterTreeView;

  with FContacterTreeView.FBranchs do
  begin
    for iLoop :=0 to Count - 1 do {添加至父部门}
    begin
      TmpBranch := TRealICQBranch(Objects[iLoop]);
      if AnsiSameText(Employee.FBranchID, TmpBranch.BranchID) then
      begin
        Employee.FNode := FContacterTreeView.FNoScrollBarTreeView.Items.AddChildObjectFirst(TmpBranch.Node, Employee.FLoginName, Employee);
        Employee.FNode.StateIndex := 1;

        ParentNode := Employee.FNode.Parent;
        //ParentNode.Expanded := False;
        while ParentNode <> nil do
        begin
          TmpBranch := ParentNode.Data;
          Inc(TmpBranch.FEmployeeCount, 1);
          ParentNode := ParentNode.Parent;
        end;
        Break;
      end;
    end;
  end;

  if Employee.FNode = nil then
  begin
    Employee.FNode := FContacterTreeView.FNoScrollBarTreeView.Items.AddChildObjectFirst(nil, Employee.FLoginName, Employee);
    Employee.FNode.StateIndex := 1;
  end;
 
  //FContacterTreeView.FTreeViewScrollBar.DrawScrollBar;
  Result := FContacterTreeView.FEmployees.AddObject(S, Employee);
end;

//------------------------------------------------------------------------------
procedure TRealICQEmployeeListItems.Insert(Index: Integer; const S: string);
begin
end;

//------------------------------------------------------------------------------
procedure TRealICQEmployeeListItems.Move(CurIndex, NewIndex: Integer);
begin
  FContacterTreeView.FEmployees.Move(CurIndex,NewIndex);
end;

//------------------------------------------------------------------------------
procedure TRealICQEmployeeListItems.Clear;
begin
  if FContacterTreeView.FEmployees = nil then Exit;
  while Count > 0 do
  begin
    Delete(0);
  end;

  FContacterTreeView.FEmployees.Clear;
end;

//------------------------------------------------------------------------------
procedure TRealICQEmployeeListItems.Delete(Index: Integer);
var
  Employee: TRealICQEmployee;
begin
  Employee := FContacterTreeView.FEmployees.Objects[Index] as TRealICQEmployee;
  FreeAndNil(Employee);
  FContacterTreeView.FEmployees.Delete(Index);
end;

//------------------------------------------------------------------------------
function TRealICQEmployeeListItems.IndexOf(const S: string): Integer;
begin
  Result := FContacterTreeView.FEmployees.IndexOf(S);
end;
{$endregion}

{ TRealICQFlashCaption }
//------------------------------------------------------------------------------
constructor TRealICQFlashCaption.Create(AEmployee: TRealICQEmployee);
begin
  inherited Create(True);
  FEmployee := AEmployee;
  FreeOnTerminate := True;
  Resume;
end;

//------------------------------------------------------------------------------
destructor TRealICQFlashCaption.Destroy;
var
  Rect: TRect;
begin
  try
    if FEmployee <> nil then
    begin
      FEmployee.FCaptionColor := $00FFFFFF;
      Rect := FEmployee.Node.DisplayRect(False);
      InvalidateRect(FEmployee.FContacterTreeView.FNoScrollBarTreeView.Handle, @Rect, False);
      FEmployee.FFlashCaptionThread := nil;
    end;
  finally
    inherited Destroy;
  end;
end;

//------------------------------------------------------------------------------
procedure TRealICQFlashCaption.FlashCaptionColor;
var
  Rect: TRect;
begin
  if Terminated then exit;

  Rect := FEmployee.Node.DisplayRect(False);
  FEmployee.FCaptionColor := FlashColors[FColorIndex];
  InvalidateRect(FEmployee.FContacterTreeView.FNoScrollBarTreeView.Handle, @Rect, False);
end;

//------------------------------------------------------------------------------
procedure TRealICQFlashCaption.Execute;
var
  iLoop,jLoop:Integer;
begin
  for iLoop:=1 to 3 do
    for jLoop:=1 to FlashColorCount do
    begin
      try
        if Terminated then exit;
        FColorIndex := jLoop;
        Synchronize(FlashCaptionColor);
        if Terminated then exit;
        Sleep(400);
      except
        Exit;
      end;
    end;
end;

{ TRealICQFlashImage }
//------------------------------------------------------------------------------
constructor TRealICQFlashImage.Create(AEmployee: TRealICQEmployee);
begin
  inherited Create(True);
  FEmployee := AEmployee;
  FreeOnTerminate := True;
  Resume;
end;

//------------------------------------------------------------------------------
destructor TRealICQFlashImage.Destroy;
var
  Rect: TRect;
begin
  try
    if FEmployee <> nil then
    begin
      FEmployee.FHeadImagePosition := 0;
      Rect := FEmployee.Node.DisplayRect(False);
      InvalidateRect(FEmployee.FContacterTreeView.FNoScrollBarTreeView.Handle, @Rect, False);
      FEmployee.FFlashImageThread := nil;
    end;
  finally
    inherited Destroy;
  end;
end;

//------------------------------------------------------------------------------
procedure TRealICQFlashImage.FlashImagePosition;
var
  Rect: TRect;
begin
  if Terminated then exit;

  Rect := FEmployee.Node.DisplayRect(False);
  FEmployee.FHeadImagePosition := FPosition;
  InvalidateRect(FEmployee.FContacterTreeView.FNoScrollBarTreeView.Handle, @Rect, False);
end;

//------------------------------------------------------------------------------
procedure TRealICQFlashImage.Execute;
var
  iAdd:Integer;
begin
  iAdd := 0;
  FPosition := 1;
  while not Terminated do
  begin
    if FPosition=3 then iAdd := -1;
    if FPosition=1 then iAdd := 1;
    FPosition := FPosition + iAdd;
    Synchronize(FlashImagePosition);
    sleep(300);
  end;
end;

procedure Register;
begin
  RegisterComponents('RealICQ UI', [TRealICQContacterTreeView]);
end;

end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值