(*
   CoolControls v 3.04h                               Registered!

   First of all, thank you for registering of the CoolControls
   package. I hope you will enjoy these components and you
   will find them useful.

   YOU MAY use the components and classes from this unit in any your
   (or your company's) FREEWARE/SHAREWARE or COMMERCIAL application.

   YOU MAY derive your own components based on components from
   this unit as you like, but ONLY with UNREGISTERED version
   of CoolControls and if someone else will decide to use it they
   will have to register CoolControls too.

   YOU MAY NOT DISTRIBUTE REGISTERED VERSION OF COOLCONTROLS.
   IT WILL BE VIOLATION OF INTERNATIONAL COPYRIGHT LAWS.

   And after all please respect my copyrigt, hours of hard
   work I spent on these components and YOURSELF.

   Copyright (c) 1997-2003 by Artem A. Berman (art@cooldev.com)
   Copyright (c) 1997-2003 by CoolDev.Com

   COMPILING THE SHAREWARE vs REGISTERED versions
   ---------------------------------------------------------------------
   This code contains both the shareware and registered, and both
   Borland Delphi and Borland C++ Builder versions of the CoolControls.

   To compile the registered version please make sure the following line
   is included below:

    {$define Registered}

   All distributed source code versions should have this line by default.
   You don't have to remove anything manually to decrease application size.

                                                                         *)
{$I versions.inc}
unit CoolCtrls;

interface

uses
  Windows, Messages, Classes, Graphics, StdCtrls, ExtCtrls, Dialogs, Controls, Forms,
  Printers, Clipbrd, Grids, Buttons, Menus, ShellApi, FileCtrl, ComCtrls, SysUtils, {$IFNDEF VER90} ToolWin, {$ENDIF}
  {$IFDEF DELPHI4_OR_ABOVE} ImgList, ActnList, {$ENDIF} CoolUtils, jpeg; // by Starenko

const
  // Sent when you end the editing of the text. Applies to the TCoolStringGrid control.
  //
  CM_ENDEDITING 	 = WM_USER + 404;
  // Sent when button being deleted. Applies to the TCoolButtonPanel control.
  //
  CM_BUTTONDESTROYED     = WM_USER + 405;
  // Sent when you release the cursor within the button. Applies to the TCoolButtonPanel control.
  //
  CM_BUTTONMOUSEUP       = WM_USER + 406;
  // Sent when color of the control changed. Applies to the TCoolButtonPanel control.
  //
  CM_PARENTBACKCOLOR     = WM_USER + 407;
  // Sent when cursor enters new button's bounds rect. Applies to the TCoolButtonPanel control.
  //
  CM_MOUSECAPTURECHANGE  = WM_USER + 408;
  // Sent when list box part of the TCoolCombobox being repainted. Applies to the TCoolComboBox control.
  //
  CM_PAINTLISTBOXPART    = WM_USER + 409;
  // Sent when one of the tray icon's related events takes place. Applies to the TCoolTrayIcon control.
  //
  CM_TRAYICONEVENT 	 = WM_USER + 410;
  {$IFDEF VER90}
  CM_CHANGED             = WM_USER + 411;
  {$ENDIF}

type
  // These flags can be used with the following meaning:
  // <P>
  // * <I>ocPaintWallpaper.</I> Whether you want to paint the wallpaper for control. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
  // * <I>ocStretchWallpaper.</I> Whether you like to stretch the image to fit all the control surface. If false image will be repeatedly painted to fill the control (tiled).
  // * <I>ocPaintSelWallpaper.</I> Whether you want to paint the wallpaper for selected items. SelWallpaper or combination of  CoolImages and idSelWallpaper properties must be assigned properly.
  // * <I>ocPaintCaptionWallpaper.</I> Whether you want to paint the wallpaper for control's caption (if the latest is visible). CaptionWallpaper or combination of  CoolImages and idCaptionWallpaper properties must be assigned properly.
  // * <I>ocPaintGradiently.</I> Whether you  want to paint the gradient background. Respective color properties define the background range colors.
  // * <I>ocInvertWallpaperAsSelect.</I> Whether you want to use the same wallpaper you use for control to highlight selected items. When presents selected items will be drawn using inverted Wallpaper image, Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
  // * <I>ocBevelOnlyIfSel.</I> Whether you like to paint bevel around all the control items or only around those selected. 
  // * <I>ocNoHighlightImage.</I> If the items have attached images determines whether those for selected items should or should not be highlighted among with the item.
  // * <I>ocNoImageAttached.</I> Whether control presumes that its items some with attached images If not there will not be extra space between border and items
  // * <I>ocUseImageList.</I> Whether images should be taken from the linked Image List component or directly from the Glyph property. 
  // * <I>ocUseGlyphAssigment.</I> Whether Glyph should be taken from the CoolImages List component or directly from the Glyph property. // by Starenko
  // * <I>oc3dMDIForm.</I> Whether MDI parent form has more 3D look.
  // * <I>ocWallpaperForMDIChildren.</I> Whether attached wallpaper should be painted for all MDI child windows. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
  // * <I>ocNoCaption.</I> Whether control has caption area. Some controls will not have caption even if this property set to True.
  // * <I>ocSmallCaption.</I> What kind of caption should be used for window (if possible) standard or small caption (like for tool windows).
  // * <I>ocNoMDIChildrensCaptions.</I> Whether MDI child windows should  be drawn with the captions.
  // * <I>ocDragUsingClientArea.</I> Is it possible to drag the form using its client area.
  // * <I>ocNoDragUsingCaption.</I> Is it possible to drag the form using its caption area.
  // * <I>ocRoundedForm.</I> Whether the form should have oval shape.
  // * <I>ocFlatBorder.</I> Whether control should be painted with the modern flat look.
  // * <I>ocPaintTransparently.</I> Whether the control should have its own background or use that of the parent container.
  TCoolOption = (ocPaintWallpaper,
                 ocStretchWallpaper,
                 ocPaintSelWallpaper,
                 ocPaintCaptionWallpaper,
                 ocInvertWallpaperAsSelect,
                 ocPaintGradiently,
                 ocBevelOnlyIfSel,
                 ocUseImageList,
                 // Permits using of notify event to assign glyph
                 ocUseGlyphAssign, // by Starenko
                 oc3dMDIForm,
                 ocWallpaperForMDIChildren,
                 ocGradientForMDIChildren,
                 ocNoCaption,
                 ocSmallCaption,
                 ocNoMDIChildrensCaptions,
                 ocDragUsingClientArea,
                 ocNoDragUsingCaption,
                 ocRoundedForm,
                 ocFlatBorder,
                 ocPaintFormSemiTransparently,
                 ocPaintTransparently);

  // Controls variety of various control's parameters, the combination of included and excluded flags  determines appearance and behavior of the control. The following items that being used separately or in combination define control's look, note that some flags can not be used together and the others can or even must, note also that not all flags can be supported by the particular control or component.  
  TCoolOptions = set of TCoolOption;

  // Defines the type of a control.
  //<TABLE>
  // Value                    Meaning
  // -----                    -------
  // ctCoolControl		"Standard" advanced control
  // ctColorControl		\Color selection control
  // ctFontControl		\Font selection control
  // ctPrinterControl		Printer selection control
  // ctCheckControl		Checkmark combobox
  // ctFolderControl		Displays folder's content
  //</TABLE>
  TCoolControlStyle = (ctCoolControl,
                       ctColorControl,
                       ctFontControl,
                       ctPrinterControl,
                       ctCheckControl,
                       ctFolderControl);

  // Determines the direction in which scrolling will occur. 
  // 
  // <TABLE>
  // Value                Meaning
  // -------------        -------------
  // sdBottomToTop        Text scrolls from bottom to top
  // sdTopToBottom        Text scrolls from top to bottom
  // sdLeftToRight        Text scrolls from left to right
  // sdRightToLeft        Text scrolls from right to left
  // </TABLE>
  TScrollDirection = (sdBottomToTop,
                      sdTopToBottom,
                      sdLeftToRight,
                      sdRightToLeft);

  // Determines the type of the gradient painting effect.
  // 
  // <TABLE>
  // Value             Meaning
  // -------------     -----------
  // gdHorizontal       Colors fill control horizontally
  // gdVertical         Colors fill control vertically
  // </TABLE>  
  TGradientDirection = (gdHorizontal, gdVertical);

  // Event occurs when TCoolBtn control is being painted.
  // <PRE>
  //   Sender  - button control that being painted.
  //   ACanvas - canvas of the button control painting occurs in.
  //   R       - bounding rectangle for the canvas.
  // </PRE>
  //
  TDrawButtonEvent = procedure(Sender: TObject; ACanvas: TCanvas; R: TRect) of Object;

  // About box class. That displays property editor for About property.
  TCCAboutBox = class
  end;

  TCoolImages = class;

  // Internal object. Works with the TCoolImages the same way TImageChangeLink
  // works with TImageList.
  TCoolChangeLink = class(TObject)
  private
    FSender: TCoolImages;
    FOnChange: TNotifyEvent;
  public
    // Destroys instance of the class and frees the occupied memory.
    destructor Destroy; override;
    // procedure that makes calls to the OnChange event.
    //
    // See Also:
    //   OnChange
    procedure Change; dynamic;
    // Event fired when attached TCoolImages object or is properties changed.
    //
    // See Also:
    //   Sender
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
    // TCoolImages object the current instance of the TCoolChangeLink linked to.
    property Sender: TCoolImages read FSender write FSender;
  end;

  // TImageItem is a collection type for TImages collection.
  TImageItem = class(TCollectionItem)
  private
    FBitmap: TBitmap;
    // by Starenko begin
    FPicture: TPicture;
    procedure SetPicture(Value: TPicture);
    // be Starenko end
    function GetBitmap: TBitmap;
  protected
    procedure OnChange(Sender: TObject);
  public
    //This is for backward compatibility...
    property Bitmap: TBitmap read GetBitmap; // by Starenko
    // Initializes and creates TImageItem instance.
    constructor Create(Collection: TCollection); override;
    // Destroys instance of the class and frees the occupied memory.
    destructor Destroy; override;
    procedure Assign(Source: TPersistent); override;
  published
    // Points to the TPicture that contains image to be stored in the TCoolImages container.
    property Picture: TPicture read FPicture write SetPicture;
  end;

  // Collection of the TImageItem objects. Used in TCoolImages class.
  TImages = class(TCollection)
  private
    FCoolImages: TCoolImages;
    function GetItem(Index: Integer): TImageItem;
    procedure SetItem(Index: Integer; Value: TImageItem);
  protected
    {$IFNDEF VER90}
    function GetOwner: TPersistent; override;
    {$ENDIF}
    procedure Update(Item: TCollectionItem); override;
  public
    // Creates instance of the TImages class.
    constructor Create(CoolImages: TCoolImages);
    // Creates, initializes and adds instance of the TImageItem class.
    function Add: TImageItem;
    // Use Items property to address the particular TImageItem class with the index Index.
    property Items[Index: Integer]: TImageItem read GetItem write SetItem; default;
  end;

  // TCoolImages component holds collection of images you can use as
  // wallpapers for the components and controls. Each visual control
  // has CoolImages property that can be assigned to TCoolImages so
  // that its images can be used as wallpapers for the control.
  TCoolImages = class(TComponent)
  private
    FAboutBox: TCCAboutBox;
    FClients: TList;
    FImages: TImages;
  protected
    procedure Change; dynamic;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    procedure RegisterChanges(Value: TCoolChangeLink);
    procedure UnRegisterChanges(Value: TCoolChangeLink);
  published
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    // Images property points to the collection of the
    // TImageItem objects that contain the bitmap images.
    property Images: TImages read FImages write FImages;
  end;

  {$IFDEF VER90}
  TEdgeBorder = (ebLeft, ebRight, ebTop, ebBottom);
  TEdgeBorders = set of TEdgeBorder;
  {$ENDIF}

  // This Event is to assign index to number of images in CoolImages list
  TMyNotifyEvent = procedure (Index: Integer; var GlAssign: Integer) of object; // by Starenko

  // TCoolListBox is highly advanced listbox control. It provides with the great
  // amount of styles and features. TCoolListBox  can be used as color selection,
  // font selection, checkmarks control. Can have wallpapers, bevels and many other
  // common and unique features.
  TCoolListBox = class(TCustomListBox)
  private
    FSelColor,
    FCaptionColor,
    FCaptionTextColor: TColor;
    FSelFont: TFont;
    FGlyph: Pointer;
    FWallpaper,
    FSelWallpaper,
    FCaptionWallpaper: TBitmap;
    FOptions: TCoolOptions;
    FBevelInner,
    FBevelOuter: TPanelBevel;
    FBevelStyle: TBevelStyleEx;
    FImageChangeLink: TChangeLink;
    FCoolImagesChangeLink: TCoolChangeLink;
    FImages: TImageList;
    FColorValue: TColor;
    FExtendedStyle: TCoolControlStyle;
    FTrueType: Boolean;
    FFlatCheckBox: Boolean;
    FExtendedCheck: Boolean;
    FWrappers: TCollection;
    FSaveStates: TList;
    FHotTray: Boolean;
    FAboutBox: TCCAboutBox;
    FMaxWidth: Integer;
    FLightColorControl: Boolean;
    FFontValue: TFont;
    FFolderName: TFileName;
    FFileType: TFileType;
    FFileMask: string;
    FFontAutoUpdate: Boolean;
    FTransparencyLevel: Byte;

    FCoolImages: TCoolImages;
    FidWallpaper,
    FidSelWallpaper,
    FidCaptionWallpaper: Integer;

    FShadowColor: TColor;
    FShadowSize: Byte;
    FShadowPos: TShadowPosition;
    FSimpleView: Boolean;

    FEdgeBorders: TEdgeBorders;
    FBorderPen: TPen;
    FBordersTrColor: TColor;

    FOnMouseEnter,
    FOnMouseLeave: TNotifyEvent;
    // This is a procedure to process event
    FOnGlyphDraw: TMyNotifyEvent; // by Starenko

    // Set properties
    procedure SetGlyph(Value: TBitmap);
    function GetGlyph: TBitmap;
    function GetNumGlyphs: TNumGlyphs;
    procedure SetNumGlyphs(Value: TNumGlyphs);
    procedure GlyphChanged(Sender: TObject);

    procedure SetWallpaper(Value: TBitmap);
    function GetWallpaper: TBitmap;
    procedure SetSelWallpaper(Value: TBitmap);
    function GetSelWallpaper: TBitmap;
    procedure SetCaptionWallpaper(Value: TBitmap);
    function GetCaptionWallpaper: TBitmap;
    procedure SetOptions(Value: TCoolOptions);
    procedure SetImages(Value: TImageList);
    procedure SetBevelInner(Value: TPanelBevel);
    procedure SetBevelOuter(Value: TPanelBevel);
    procedure SeTBevelStyleEx(Value: TBevelStyleEx);
    procedure SetCaptionColor(Value: TColor);
    procedure SetCaptionTextColor(Value: TColor);
    procedure SetColorValue(Value: TColor);
    procedure SetExtendedStyle(Value: TCoolControlStyle);
    procedure SetExtendedCheck(Value: Boolean);
    procedure SetTrueType(Value: Boolean);
    procedure SetFontAutoUpdate(Value: Boolean);
    procedure SetSelFont(Value: TFont);
    function GetChecked(Index: Integer): Boolean;
    procedure SetChecked(Index: Integer; Value: Boolean);
    procedure SetState(Index: Integer; Value: TCheckBoxState);
    function GetState(Index: Integer): TCheckBoxState;
    function GetLocked(Index: Integer): Boolean;
    procedure SetLocked(Index: Integer; Value: Boolean);
    procedure SetFlatCheckBox(Value: Boolean);
    procedure SetLightColorControl(Value: Boolean);
    procedure SetFontValue(Value: TFont);
    procedure SetFolderName(Value: TFileName);
    procedure SetFileMask(Value: string);
    procedure SetFileType(Value: TFileType);
    function GetFontValue: TFont;
    procedure FontValueChanged(Sender: TObject);
    function CreateWrapper(Index: Integer): TObject;
    function ExtractWrapper(Index: Integer): TObject;
    function GetWrapper(Index: Integer): TObject;
    function HaveWrapper(Index: Integer): Boolean;
    procedure InvalidateCheck(Index: Integer);
    procedure WallpaperChanged(Sender: TObject);
    procedure ImageListChange(Sender: TObject);
    procedure SelFontChange(Sender: TObject);
    procedure SetTransparencyLevel(Value: Byte);

    procedure BorderPenChange(Sender: TObject);
    procedure SetEdgeBorders(Value: TEdgeBorders);
    procedure SetBorderPen(Value: TPen);
    procedure SetBordersTrColor(Value: TColor);

    procedure SetShadowColor(Value: TColor);
    procedure SetShadowSize(Value: Byte);
    procedure SetShadowPos(Value: TShadowPosition);
    procedure SetSimpleView(Value: Boolean);

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    procedure SetidSelWallpaper(Value: Integer);
    procedure SetidCaptionWallpaper(Value: Integer);
    function CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    function CTLDrawCaptionWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    function CTLDrawWallpaperEx(DC: HDC; R, SubRect: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    function CTLDrawSelWallpaperEx(DC: HDC; R, SubRect: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    function IsWallpaperAssigned: Boolean;
    function IsSelWallpaperAssigned: Boolean;
    procedure CoolImagesChange(Sender: TObject);

    //Messages
    procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;
    procedure LBGetTopIndex(var Message: TMessage); message LB_GETTOPINDEX;
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure WMNCPaint (var Message: TMessage); message WM_NCPAINT;
    procedure CNCtlColorListBox(var Message: TWMCtlColorListBox); message CN_CTLCOLORLISTBOX;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
    procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
    procedure WMNCLButtonDblClk(var Message: TWMNCLButtonDblClk); message WM_NCLBUTTONDBLCLK;
    procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
    procedure CMParentFontChanged(var Message: TMessage); message CM_PARENTFONTCHANGED;
    procedure WMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
    procedure WMDestroy(var Message: TMessage); message WM_DESTROY;
    procedure LBAddString(var Message: TMessage); message LB_ADDSTRING;
    procedure LBInsertString(var Message: TMessage); message LB_INSERTSTRING;
    procedure LBDeleteString(var Message: TMessage); message LB_DELETESTRING;
    procedure LBResetContent(var Message: TMessage); message LB_RESETCONTENT;
    procedure CMParentColorChanged(var Message: TMessage); message CM_PARENTCOLORCHANGED;
    procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
    procedure WMMove(var Message: TWMMove); message WM_MOVE;
    procedure WMSetText(var Message: TMessage); message WM_SETTEXT;

    //Methods
    procedure CreateColorListBox;
    function MakeColorStr(Value: string): string;
    procedure CreateFontListBox;
    procedure CreatePrinterListBox;
    procedure CreateFolderListBox;
    function MaxWidth: Integer;
    function RealWidth(ItemStr: string): Integer;
  protected
    property Style;
    procedure NCCtlChanged; virtual;
    procedure MeasureItem(Index: Integer; var Height: Integer); override;
    procedure DrawItem(Index: Integer; Recty: TRect; State: StdCtrls.TOwnerDrawState); override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure Loaded; override;
    {$IFNDEF VER90}
    procedure SetItemData(Index: Integer; AData: LongInt); override;
    function GetItemData(Index: Integer): LongInt; override;
    {$ELSE}
    procedure SetItemData(Index: Integer; AData: LongInt); dynamic;
    function GetItemData(Index: Integer): LongInt; dynamic;
    {$ENDIF}
    procedure CreateWnd; override;
    procedure DestroyWnd; override;
    {$IFNDEF VER90}
    procedure ResetContent; override;
    procedure DeleteString(Index: Integer); override;
    {$ENDIF}
    procedure SetParent(AParent: TWinControl); override;
  public
    // Use Checked property to specify and retrieve current
    // state of the item with the index Index.
    // This property can be used with the State property and is
    // somewhat faster.
    property Checked[Index: Integer]: Boolean read GetChecked write SetChecked;
    // When ExtendedStyle is ctColorControl use ColorValue to
    // set and retrieve currently selected control's color value.
    property ColorValue: TColor read FColorValue write SetColorValue;
    // When ExtendedStyle is ctFontControl use ColorValue to
    // set and retrieve currently selected control's font value.
    property FontValue: TFont read GetFontValue write SetFontValue;
    // Use Locked property in run-time to determine 
    // whenever item with the index Index is locked. 
    // I.e. it's Checked state cannot be modified.
    property Locked[Index: Integer]: Boolean read GetLocked write SetLocked;
    // Run-time only. Use State property in run-time 
    // to determine or set the particular item's
    // currently chosen state.
    // 
    // <TABLE>
    // Value            Meaning
    // ---------	---------
    // cbUnchecked	Item is unchecked
    // cbChecked	Item is checked
    // cbGrayed	        Item is grayed
    // </TABLE>
    // 
    // this property can be used instead of Checked 
    // property.
    property State[Index: Integer]: TCheckBoxState read GetState write SetState;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    // Use BevelInner to specify whether the inner bevel has a raised, lowered, or flat look. 
    // 
    // The inner bevel appears immediately inside the outer bevel. If there is no outer bevel (BevelOuter is bvNone), the inner bevel appears immediately inside the border.
    property BevelInner: TPanelBevel read FBevelInner write SetBevelInner default bvNone;
    // Use BevelOuter to specify whether the outer bevel has a raised, lowered, or flat look. The outer bevel appears immediately inside the border and outside the inner bevel.
    property BevelOuter: TPanelBevel read FBevelOuter write SetBevelOuter default bvNone;
    // Use BevelStyle to select style for the bevel used with control's items:
    //
    //<TABLE>
    // Value                   Meaning
    // -----                   -------
    // bsBevelBoth             Bevel for both text and image.
    // bsBevelOnlyImage        Bevel for image only
    // bsBevelOnlyText         Bevel for text only
    //</TABLE>
    property BevelStyle: TBevelStyleEx read FBevelStyle write SeTBevelStyleEx default bsBevelBoth;
    // It's possible to draw the edges (borders) for control. Based on EdgeBorders values you can control what borders will be drawn and the BorderPen property points to the pen object used to draw the borders around control.
    // 
    // See Also:
    //   EdgeBorders
    property BorderPen: TPen read FBorderPen write SetBorderPen;
    // If EdgeBorders specified (any) and BordersTrColor is different from clNone there will be painted borders for NON DEFINED edges with the BordersTrColor color. That makes sense if BorderStyle is bsSingle and you would like to make all but one or few edges transparent. Alternatively you can set BorderStyle to bsNone.
    //
    // See Also:
    //   EdgeBorders
    //   BorderPen
    property BordersTrColor: TColor read FBordersTrColor write SetBordersTrColor default clNone;
    // Some controls in the Coolcontrols package 
    // may have captions just like forms (they even 
    // can be dragged within the parent container). 
    // Appearance of the caption controlled by ocNoCaption flag 
    // (Options property)  Caption can be wide or small (ocSmallCaption flag).
    // 
    // Use CaptionColor to set Color of the control's Caption (when 
    // it is visible). clInctiveCaption is the default value.
    property CaptionColor: TColor read FCaptionColor write SetCaptionColor default clInactiveCaption;
    // Some controls in the Coolcontrols package may 
    // have captions just like forms (they even can be 
    // dragged within the parent container). Appearance 
    // of the caption controlled by ocNoCaption flag (Options 
    // property)  Caption can be wide or small (ocSmallCaption flag).
    // 
    // Use CaptionTextColor to set the \color of the control's Caption 
    // text (when caption is visible). clInctiveCaptionText is the 
    // default value. The caption text itself is being set by Caption 
    // property.
    property CaptionTextColor: TColor read FCaptionTextColor write SetCaptionTextColor default clInactiveCaptionText;
    // Some controls in the CoolControls package may have
    // captions just like forms (they even can be dragged 
    // within the parent container). Appearance of the caption 
    // controlled by ocNoCaption flag (Options property)  
    // Caption can be wide or small (ocSmallCaption flag).
    // 
    // Use CaptionWallpaper to specify the bitmap image to be 
    // painted as wallpaper for the caption (when caption is visible).  
    // 
    // There's another possible solution, instead of assigning 
    // CaptionWallpaper property you can use CoolImages and idCaptionWallpaper 
    // properties. This way you save system resources by using the same image for 
    // many controls.
    // 
    // See Also:
    //   Options
    //   idCaptionWallpaper
    //   CoolImages
    property CaptionWallpaper: TBitmap read GetCaptionWallpaper write SetCaptionWallpaper;
    // Use CoolImages property to specify  TCoolImages component will be used 
    // to load images for wallpapers from. TcoolImages acts much like 
    // TImageList that is behaves as placeholder for images. It can contain
    // images only but images of different sizes and color modes can be stored 
    // together in the same object.
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // You may switch between various control styles using this property:
    // 
    //<TABLE>
    // Value                    Meaning
    // -----                    -------
    // ctCoolControl		"Standard" advanced control
    // ctColorControl		\Color selection control
    // ctFontControl		\Font selection control
    // ctPrinterControl		Printer selection control
    // ctCheckControl		Checkmark combobox
    // ctFolderControl		Displays folder's content
    //</TABLE>
    property ExtendedStyle: TCoolControlStyle read FExtendedStyle write SetExtendedStyle default ctCoolControl;
    // Use ExtendedCheck property to indicate whether
    // you want to display the checkbox in addition to the 
    // attached image. If you need check list box only
    // see ExtendedStyle property.
    property ExtendedCheck: Boolean read FExtendedCheck write SetExtendedCheck default False;
    // It's possible to draw the edges (borders) for control. 
    // Based on EdgeBorders values you can control what borders 
    // will be drawn and the BorderPen property points to the 
    // pen object used to draw the borders around control. And  
    // the EdgeBorders property used to add or remove borders.
    property EdgeBorders: TEdgeBorders read FEdgeBorders write SetEdgeBorders default [];
    // FlatCheckBox property controls visual appearance
    // of the check box image. It can be 3D or flat depending 
    // on the property's value.
    property FlatCheckBox: Boolean read FFlatCheckBox write SetFlatCheckBox default False;
    // The FontAutoUpdate property indicates whether the SelFont 
    // should be changed when the general Font is changed so these 
    // two will be alike expect for color.
    property FontAutoUpdate: Boolean read FFontAutoUpdate write SetFontAutoUpdate default False;
    // Use FolderName to specify the folder which contents will be displayed 
    // by the control. ExtendedStyle should be ctFolderControl in order for
    // control to display folder's contents.
    property FolderName: TFileName read FFolderName write SetFolderName;
    // You may want to limit the files count to these matching the mask given. 
    // Any valid DOS mask acceptable.
    property FileMask: string read FFileMask write SetFileMask;
    // Use FileType to specify file types to be displayed by the control.
    // 
    //<TABLE>
    // Value                    Meaning
    // -----                    -------
    // ftReadOnly		Displays files with the read-only attribute.
    // ftHidden			Displays files with the hidden attribute.
    // ftSystem			Displays system files.
    // ftVolumeID		Displays the volume name.
    // ftDirectory		Displays directories.
    // ftArchive		Displays files with archive attribute.
    // ftNormal			Displays files with no special attributes.
    //</TABLE>
    property FileType: TFileType read FFileType write SetFileType default [ftDirectory, ftArchive];
    // If the control or its items can be painted with the 
    // bitmap image (glyph) use this property to specify the bitmap 
    // image to be painted. Painting glyphs may give 
    // your controls more attractive look yet highlight the control's purpose.
    property Glyph: TBitmap read GetGlyph write SetGlyph;
    // Set HotTray to True to provide visual 
    // feedback about which item is under the
    // mouse. When HotTray is True, pausing the
    // mouse over an item causes it to be selected. 
    // When HotTray is False, there is no visual 
    // feedback when the mouse passes over items 
    // and users can't select items by pausing the 
    // mouse.
    property HotTray: Boolean read FHotTray write FHotTray default False;
    // Some controls in the CoolControls 
    // package may have captions just like 
    // forms (they even can be dragged within 
    // the parent container). Appearance of the 
    // caption controlled by ocNoCaption flag 
    // (Options property)  Caption can be wide 
    // or small (ocSmallCaption flag).
    // 
    // Use CaptionWallpaper to specify the bitmap image 
    // to be painted as wallpaper for the caption 
    // (when caption is visible).  
    // 
    // There's another possible solution, instead of 
    // assigning CaptionWallpaper property you can
    // use CoolImages and idCaptionWallpaper properties. This 
    // way you save system resources by using the 
    // same image for many controls.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   CaptionWallpaper
    property idCaptionWallpaper: Integer read FidCaptionWallpaper write SetidCaptionWallpaper default -1;
    // There's an opportunity to paint background image for 
    // selected items only. Among with using SelWallpaper there's 
    // a way to use CoolImages and idSelWallpaper 
    // properties to specify the image. This technique allows to 
    // save resources by using the same image for many controls. 
    // IdSelWallpaper indicates the index of the image in TcoolImages 
    // container. If the control has Options property it's necessary to 
    // include ocPaintSelWallpaper flag into he Options set to actually 
    // enable the painting of the selected wallpaper.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   SelWallpaper
    property idSelWallpaper: Integer read FidSelWallpaper write SetidSelWallpaper default -1;
    // There's an alternative for direct assigning of 
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties 
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper 
    // indicates the index of the image from CoolImages to be used. 
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    // Use Images to provide a customized list of images
    // that can be displayed with the items.
    property Images: TImageList read FImages write SetImages;
    // Use LightColorControl to indicate whether
    // ListView should contain only basic 16 colors 
    // or all possible colors. ExtendedStyle must be 
    // ctColorControl in order for control to display 
    // colors.
    property LightColorControl: Boolean read FLightColorControl write SetLightColorControl default True;
    // NumGlyphs property indicates the number of images 
    // that are in the graphic specified in the Glyph 
    // property for use on a control.
    // If you have multiple images in a bitmap, you must 
    // specify the number of images that are in 
    // the bitmap with the NumGlyphs property. Valid NumGlyphs 
    // values are 1 to 4. The default value is 1.
    //
    // See Also:
    //   Glyph
    property NumGlyphs: TNumGlyphs read GetNumGlyphs write SetNumGlyphs default 1;
    // Options property controls variety of various controls parameters, the combination of included and excluded flags
    // determines appearance and behavior of the control. The following items that being used separately or in combination define
    // control's look, note that some flags can not be used together and the others can or even must, note also that not all flags can be supported by the particular control or component.
    // These flags can be used with the following meaning:
    // <P>
    // * <I>ocPaintWallpaper.</I> Whether you want to paint the wallpaper for control. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocStretchWallpaper.</I> Whether you like to stretch the image to fit all the control surface. If false image will be repeatedly painted to fill the control (tiled).
    // * <I>ocPaintSelWallpaper.</I> Whether you want to paint the wallpaper for selected items. SelWallpaper or combination of  CoolImages and idSelWallpaper properties must be assigned properly.
    // * <I>ocPaintCaptionWallpaper.</I> Whether you want to paint the wallpaper for control's caption (if the latest is visible). CaptionWallpaper or combination of  CoolImages and idCaptionWallpaper properties must be assigned properly.
    // * <I>ocPaintGradiently.</I> Whether you  want to paint the gradient background. Respective color properties define the background range colors.
    // * <I>ocInvertWallpaperAsSelect.</I> Whether you want to use the same wallpaper you use for control to highlight selected items. When presents selected items will be drawn using inverted Wallpaper image, Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocBevelOnlyIfSel.</I> Whether you like to paint bevel around all the control items or only around those selected. 
    // * <I>ocNoHighlightImage.</I> If the items have attached images determines whether those for selected items should or should not be highlighted among with the item.
    // * <I>ocNoImageAttached.</I> Whether control presumes that its items some with attached images If not there will not be extra space between border and items
    // * <I>ocUseImageList.</I> Whether images should be taken from the linked Image List component or directly from the Glyph property. 
    // * <I>oc3dMDIForm.</I> Whether MDI parent form has more 3D look.
    // * <I>ocWallpaperForMDIChildren.</I> Whether attached wallpaper should be painted for all MDI child windows. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocNoCaption.</I> Whether control has caption area. Some controls will not have caption even if this property set to True.
    // * <I>ocSmallCaption.</I> What kind of caption should be used for window (if possible) standard or small caption (like for tool windows).
    // * <I>ocNoMDIChildrensCaptions.</I> Whether MDI child windows should  be drawn with the captions.
    // * <I>ocDragUsingClientArea.</I> Is it possible to drag the form using its client area.
    // * <I>ocNoDragUsingCaption.</I> Is it possible to drag the form using its caption area.
    // * <I>ocRoundedForm.</I> Whether the form should have oval shape.
    // * <I>ocFlatBorder.</I> Whether control should be painted with the modern flat look.
    // * <I>ocPaintTransparently.</I> Whether the control should have its own background or use that of the parent container.
    property Options: TCoolOptions read FOptions write SetOptions default [ocNoCaption, ocBevelOnlyIfSel];
    // There's an opportunity to paint background image 
    // for selected items only. Use SelWallpaper
    // to specify the image to be painted as wallpaper 
    // for selected items. Among with using SelWallpaper 
    // there's a way to use CoolImages and idSelWallpaper 
    // properties to specify the image. This technique 
    // allows to save resources by using the same image 
    // for many controls. IdSelWallpaper indicates the 
    // index of the image in TcoolImages container. If the 
    // control has Options property it's necessary to include 
    // ocPaintSelWallpaper flag into he Options set to 
    // actually enable the painting of the selected wallpaper.
    // 
    // See Also:
    //   Options
    //   idSelWallpaper
    //   CoolImages
    property SelWallpaper: TBitmap read GetSelWallpaper write SetSelWallpaper;
    // SelColor indicates the \color to be used to highlight selected items.
    property SelColor: TColor read FSelColor write FSelColor default clHighlight;
    // SelFot property points to the TFont object to be used to draw the text of the selected items.
    property SelFont: TFont read FSelFont write SetSelFont;
    // In the CoolControls package many controls that 
    // have captions or string items allow to paint 
    // these with the 3D effect. When you use this feature, 
    // use ShadowColor to set the color of the shadow dropped. 
    // The effect being achieved by painting the text 
    // twice - once with the main color and then with the 
    // ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   SimpleView
    property ShadowColor: TColor read FShadowColor write SetShadowColor default clBtnHighlight;
    // In the CoolControls package many controls that have captions 
    // or string items allow to paint these with the 3D effect. 
    // When you use this feature, use ShadowSiize to indicate the 
    // offset  of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and then 
    // with the ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowPos
    //   ShadowColor
    //   SimpleView
    property ShadowSize: Byte read FShadowSize write SetShadowSize default 1;
    // In the CoolControls package many controls that have captions or 
    // string items allow to paint these with the 3D effect. When 
    // you use this feature, use ShadowPos to indicate the position 
    // (relatively to the main text) of the shadow dropped. The effect 
    // being achieved by painting the text twice - once with the main 
    // color and then with the ShadowColor (allowing ShadowSize offset).
    // 
    // <TABLE>
    // Value              Meaning
    // -------            -------------------------
    // spLeftTop          Shadow is in the Left Top direction.
    // spLeftBottom       Shadow is in the Left Bottom direction.
    // spRightBottom      Shadow is in the Right Bottom direction.
    // spRightTop         Shadow is in the Right Top direction.
    // </TABLE>
    // 
    // See Also:
    //   ShadowSize
    //   ShadowColor
    //   SimpleView
    property ShadowPos: TShadowPosition read FShadowPos write SetShadowPos default spLeftTop;
    // In the CoolControls package many controls that have 
    // captions or string items allow to paint these with 
    // the 3D effect. When you use this feature, use ShadowPos 
    // to indicate the position (relatively to the main text) 
    // of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and 
    // then with the ShadowColor (allowing ShadowSize offset).
    // Use SimpleView to indicate whether you want to use the 
    // described feature  or you do not.
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   ShadowColor
    property SimpleView: Boolean read FSimpleView write SetSimpleView default False;
    // Use TransparencyLevel to specify the 
    // parent control whose part will be used 
    // to draw the background of the component. 
    // For example if control placed on the panel 
    // that is placed on the form, setting TransparencyLevel 
    // to 0 will force part of the panel to be used for 
    // painting of the transparent background, setting 
    // TransparencyLevel to 1 will force the part of the 
    // form to be selected on the controls device context 
    // when paint transparently.
    property TransparencyLevel: Byte read FTransparencyLevel write SetTransparencyLevel default 0;
    // If ExtendedStyle is ctFontControl use TrueType
    // property to indicate if you would like to list all
    // the fonts or True Type Fonts (TTF) only.
    property TrueType: Boolean read FTrueType write SetTrueType default False;
    // Use Wallpaper to specify the bitmap image 
    // that will be painted as background wallpaper 
    // for a control. In most cases CoolControls package 
    // requires ocPaintWallpaper flag included into 
    // Options property set in order to actually enable 
    // wallpaper painting. Mind you that there's an 
    // alternative way to attach the image to be painted 
    // on control's background - use CoolImages and idWallpaper 
    // properties for that. This technique allows to save system
    // resources by sharing the same image between many controls.
    // 
    // See Also:
    //   Options
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
    property Align;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Anchors;
    property BiDiMode;
    {$ENDIF}
    property BorderStyle;
    property Caption;
    property Color;
    property Columns;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Constraints;
    {$ENDIF}
    property Ctl3D;
    property DragCursor;
    {$IFDEF DELPHI4_OR_ABOVE}
    property DragKind;
    {$ENDIF}
    property DragMode;
    property Enabled;
    property ExtendedSelect;
    property Font;
    {$IFNDEF VER90}
    property ImeMode;
    property ImeName;
    {$ENDIF}
    property IntegralHeight;
    property ItemHeight;
    property Items;
    property MultiSelect;
    {$IFDEF DELPHI4_OR_ABOVE}
    property ParentBiDiMode;
    {$ENDIF}
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property Sorted;
    property TabOrder;
    property TabStop;
    property TabWidth;
    property Visible;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnDrawItem;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnEndDock;
    {$ENDIF}
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMeasureItem;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnStartDock;
    {$ENDIF}
    property OnStartDrag;
    // OnMouseEnter event occurs immediately after mouse cursor enters the control.
    property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
    // OnMouseLeave event occurs immediately after mouse cursor leaves the control.
    property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
    // OnGlyphDraw event occurs before item's glyph drawing
    property OnGlyphDraw: TMyNotifyEvent read FOnGlyphDraw write FOnGlyphDraw; // by Starenko
  end;


  // TCoolComboBox is highly advanced combobox control. It provides with the great amount 
  // of styles and features. TCoolComboBox can be used as color selection, font selection, 
  // checkmarks control. Can have wallpapers, bevels and many other common and unique features.  
  TCoolComboBox = class(TCustomComboBox)
  private
    FSelFont: TFont;
    FSelColor: TColor;
    FGlyph: Pointer;
    FWallpaper,
    FSelWallpaper: TBitmap;
    FOptions: TCoolOptions;
    FBevelInner,
    FBevelOuter: TPanelBevel;
    FBevelStyle: TBevelStyleEx;
    FImageChangeLink: TChangeLink;
    FCoolImagesChangeLink: TCoolChangeLink;
    FImages: TImageList;
    HListBox: THandle;
    HRect: TRect;
    FColorValue: TColor;
    FExtendedStyle: TCoolControlStyle;
    FTrueType: Boolean;
    FFlatCheckBox: Boolean;
    FExtendedCheck: Boolean;
    FWrappers: TCollection;
    FSaveStates: TList;
    FListBoxWidth: Integer;
    FAboutBox: TCCAboutBox;
    FMaxWidth: Integer;
    FLightColorControl: Boolean;
    FFontValue: TFont;
    FFontAutoUpdate: Boolean;
    FFolderName: TFileName;
    FFileType: TFileType;
    FFileMask: string;
    FAlignment: TPopupAlignment;
    FOnMouseEnter,
    FOnMouseLeave: TNotifyEvent;
    // This is a procedure to process event
    FOnGlyphDraw: TMyNotifyEvent; // by Starenko

    FDefListProc,
    FNewListProc: Pointer;

    FShadowColor: TColor;
    FShadowSize: Byte;
    FShadowPos: TShadowPosition;
    FSimpleView: Boolean;

    FCoolImages: TCoolImages;
    FidWallpaper,
    FidSelWallpaper: Integer;
    FTransparencyLevel: Byte;

    FEdgeBorders: TEdgeBorders;
    FBorderPen: TPen;
    FBordersTrColor: TColor;
    FBorderStyle: TBorderStyle;

    procedure BorderPenChange(Sender: TObject);
    procedure SetEdgeBorders(Value: TEdgeBorders);
    procedure SetBorderPen(Value: TPen);
    procedure SetBordersTrColor(Value: TColor);
    procedure SetBorderStyle(Value: TBorderStyle);

    // Set properties
    procedure SetGlyph(Value: TBitmap);
    function GetGlyph: TBitmap;
    procedure SetWallpaper(Value: TBitmap);
    function GetWallpaper: TBitmap;
    procedure SetSelWallpaper(Value: TBitmap);
    function GetSelWallpaper: TBitmap;
    procedure SetOptions(Value: TCoolOptions);
    procedure SetImages(Value: TImageList);
    procedure SetBevelInner(Value: TPanelBevel);
    procedure SetBevelOuter(Value: TPanelBevel);
    procedure SeTBevelStyleEx(Value: TBevelStyleEx);
    procedure SetTopIndex(Value: Integer);
    function GetTopIndex: Integer;
    procedure SetColorValue(Value: TColor);
    procedure SetExtendedStyle(Value: TCoolControlStyle);
    procedure SetExtendedCheck(Value: Boolean);
    procedure SetTrueType(Value: Boolean);
    procedure SetFontAutoUpdate(Value: Boolean);
    procedure SetSelFont(Value: TFont);
    function GetChecked(Index: Integer): Boolean;
    procedure SetChecked(Index: Integer; Value: Boolean);
    procedure SetState(Index: Integer; Value: TCheckBoxState);
    function GetState(Index: Integer): TCheckBoxState;
    function GetLocked(Index: Integer): Boolean;
    procedure SetLocked(Index: Integer; Value: Boolean);
    procedure SetFlatCheckBox(Value: Boolean);
    procedure SetListBoxWidth(Value: Integer);
    procedure SetLightColorControl(Value: Boolean);
    procedure SetFontValue(Value: TFont);
    function GetFontValue: TFont;
    procedure FontValueChanged(Sender: TObject);
    procedure SetFolderName(Value: TFileName);
    procedure SetFileType(Value: TFileType);
    procedure SetFileMask(Value: string);
    function CreateWrapper(Index: Integer): TObject;
    function ExtractWrapper(Index: Integer): TObject;
    function GetWrapper(Index: Integer): TObject;
    function HaveWrapper(Index: Integer): Boolean;
    procedure WallpaperChanged(Sender: TObject);
    procedure ImageListChange(Sender: TObject);
    procedure SelFontChange(Sender: TObject);
    procedure SetTransparencyLevel(Value: Byte);

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    procedure SetidSelWallpaper(Value: Integer);
    function CTLDrawWallpaperEx(DC: HDC; R, SubRect: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    function CTLDrawSelWallpaperEx(DC: HDC; R, SubRect: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    function IsWallpaperAssigned: Boolean;
    function IsSelWallpaperAssigned: Boolean;

    procedure SetShadowColor(Value: TColor);
    procedure SetShadowSize(Value: Byte);
    procedure SetShadowPos(Value: TShadowPosition);
    procedure SetSimpleView(Value: Boolean);

    procedure CoolImagesChange(Sender: TObject);
    procedure GlyphChanged(Sender: TObject);
    function GetNumGlyphs: TNumGlyphs;
    procedure SetNumGlyphs(Value: TNumGlyphs);

    //Messages
    procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;
    procedure CBGetTopIndex(var Message: TMessage); message CB_GETTOPINDEX;
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure WMNCPaint (var Message: TMessage); message WM_NCPAINT;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
    procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
    procedure CMParentFontChanged(var Message: TMessage); message CM_PARENTFONTCHANGED;
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
    procedure CBAddString(var Message: TMessage); message CB_ADDSTRING;
    procedure CBInsertString(var Message: TMessage); message CB_INSERTSTRING;
    procedure CBDeleteString(var Message: TMessage); message CB_DELETESTRING;
    procedure CBResetContent(var Message: TMessage); message CB_RESETCONTENT;
    procedure CMParentColorChanged(var Message: TMessage); message CM_PARENTCOLORCHANGED;
    procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
    procedure WMMove(var Message: TWMMove); message WM_MOVE;
    procedure CMPaintListBoxPart(var Message: TMessage); message CM_PAINTLISTBOXPART;

    //Methods
    procedure CreateColorComboBox;
    function MakeColorStr(Value: string): string;
    procedure CreateFontComboBox;
    procedure CreatePrinterComboBox;
    procedure CreateFolderComboBox;
    function MaxWidth: Integer;
    function RealWidth(ItemStr: string): Integer;
  protected
    property Style;
    procedure MeasureItem(Index: Integer; var Height: Integer); override;
    procedure DrawItem(Index: Integer; Recty: TRect; State: StdCtrls.TOwnerDrawState); override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure WndProc(var Message: TMessage); override;
    procedure ComboWndProc(var Message: TMessage; ComboWnd: HWnd; ComboProc: Pointer); override;
    procedure ListWndProc(var Message: TMessage); virtual;
    procedure Loaded; override;
    function GetItemData(Index: Integer): LongInt; dynamic;
    procedure SetItemData(Index: Integer; AData: LongInt); dynamic;
    procedure CreateWnd; override;
    procedure DestroyWnd; override;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure SetParent(AParent: TWinControl); override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  public
    // When ExtendedStyle is ctColorControl use ColorValue to
    // set and retrieve currently selected control's color value.
    property ColorValue: TColor read FColorValue write SetColorValue;
    // Use Checked property to specify and retrieve current
    // state of the item with the index Index.
    // This property can be used with the State property and is
    // somewhat faster.
    property Checked[Index: Integer]: Boolean read GetChecked write SetChecked;
    // When ExtendedStyle is ctFontControl use ColorValue to
    // set and retrieve currently selected control's font value.
    property FontValue: TFont read GetFontValue write SetFontValue;
    // Use Locked property in run-time to determine 
    // whenever item with the index Index is locked. 
    // I.e. it's Checked state cannot be modified.
    property Locked[Index: Integer]: Boolean read GetLocked write SetLocked;
    // Run-time only. Use State property in run-time 
    // to determine or set the particular item's
    // currently chosen state.
    // 
    // <TABLE>
    // Value          	Meaning
    // ---------	---------
    // cbUnchecked	Item is unchecked
    // cbChecked	Item is checked
    // cbGrayed	        Item is grayed
    // </TABLE>
    // 
    // this property can be used instead of Checked 
    // property.
    property State[Index: Integer]: TCheckBoxState read GetState write SetState;
    // Run-time and read-only. Use TopIndex property to get the
    // index of the topmost item (item that is currently topmost and
    // visible).
    property TopIndex: Integer read GetTopIndex write SetTopIndex;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published   
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    // When ListBoxWidth is greater than control's width use Alignment property specify align of the control's 
    // list box part
    // 
    // <TABLE>
    // Value            Meaning
    // ------           ----------
    // paLeft           Left aligned
    // paRight          Right aligned
    // paCenter         Center aligned
    // </TABLE>
    property Alignment: TPopupAlignment read FAlignment write FAlignment default paLeft;
    // Use BevelInner to specify whether the inner bevel has a raised, lowered, or flat look. 
    // 
    // The inner bevel appears immediately inside the outer bevel. If there is no outer bevel (BevelOuter is bvNone), the inner bevel appears immediately inside the border.
    property BevelInner: TPanelBevel read FBevelInner write SetBevelInner default bvNone;
    // Use BevelOuter to specify whether the outer bevel has a raised, lowered, or flat look. The outer bevel appears immediately inside the border and outside the inner bevel.
    property BevelOuter: TPanelBevel read FBevelOuter write SetBevelOuter default bvNone;
    // Use BevelStyle to select style for the bevel used with control's items:
    // 
    //<TABLE>
    // Value                   Meaning
    // -----                   -------
    // bsBevelBoth             Bevel for both text and image.
    // bsBevelOnlyImage        Bevel for image only
    // bsBevelOnlyText         Bevel for text only
    //</TABLE>
    property BevelStyle: TBevelStyleEx read FBevelStyle write SeTBevelStyleEx default bsBevelBoth;
    // Use CoolImages property to specify  TCoolImages component will be used 
    // to load images for wallpapers from. TcoolImages acts much like 
    // TImageList that is behaves as placeholder for images. It can contain 
    // images only but images of different sizes and color modes can be stored 
    // together in the same object.
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // It's possible to draw the edges (borders) for control. Based on EdgeBorders values you can control what borders will be drawn and the BorderPen property points to the pen object used to draw the borders around control.
    // 
    // See Also:
    //   EdgeBorders
    property BorderPen: TPen read FBorderPen write SetBorderPen;
    // If EdgeBorders specified (any) and BordersTrColor is different from clNone there will be painted borders for NON DEFINED edges with the BordersTrColor color. That makes sense if BorderStyle is bsSingle and you would like to make all but one or few edges transparent. Alternatively you can set BorderStyle to  bsNone.
    //
    // See Also:
    //   EdgeBorders
    //   BorderPen
    property BordersTrColor: TColor read FBordersTrColor write SetBordersTrColor default clNone;
    property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsSingle; 
    // It's possible to draw the edges (borders) for control. 
    // Based on EdgeBorders values you can control what borders 
    // will be drawn and the BorderPen property points to the 
    // pen object used to draw the borders around control. And  
    // the EdgeBorders property used to add or remove borders.
    property EdgeBorders: TEdgeBorders read FEdgeBorders write SetEdgeBorders default [];
    // You may switch between various control styles using this property:
    // 
    //<TABLE>
    // Value                    Meaning
    // -----                    -------
    // ctCoolControl		"Standard" advanced control
    // ctColorControl		\Color selection control
    // ctFontControl		\Font selection control
    // ctPrinterControl		Printer selection control
    // ctCheckControl		Checkmark combobox
    // ctFolderControl		Displays folder's content
    //</TABLE>
    property ExtendedStyle: TCoolControlStyle read FExtendedStyle write SetExtendedStyle default ctCoolControl;
    // Use ExtendedCheck property to indicate whether
    // you want to display the checkbox in addition to the 
    // attached image. If you need check list box only
    // see ExtendedStyle property.
    property ExtendedCheck: Boolean read FExtendedCheck write SetExtendedCheck default False;
    // You may want to limit the files count to these matching the mask given. 
    // Any valid DOS mask acceptable.
    property FileMask: string read FFileMask write SetFileMask;
    // Use FileType to specify file types to be displayed by the control.
    // 
    //<TABLE>
    // Value                    Meaning
    // -----                    -------
    // ftReadOnly		Displays files with the read-only attribute.
    // ftHidden			Displays files with the hidden attribute.
    // ftSystem			Displays system files.
    // ftVolumeID		Displays the volume name.
    // ftDirectory		Displays directories.
    // ftArchive		Displays files with archive attribute.
    // ftNormal			Displays files with no special attributes.
    //</TABLE>
    property FileType: TFileType read FFileType write SetFileType default [ftDirectory, ftArchive];
    // FlatCheckBox property controls visual appearance
    // of the check box image. It can be 3D or flat depending 
    // on the property's value.
    property FlatCheckBox: Boolean read FFlatCheckBox write SetFlatCheckBox default False;
    // The FontAutoUpdate property indicates whether the SelFont 
    // should be changed when the general Font is changed so these 
    // two will be alike expect for color.
    property FontAutoUpdate: Boolean read FFontAutoUpdate write SetFontAutoUpdate default False;
    // Use FolderName to specify the folder which contents will be displayed 
    // by the control. ExtendedStyle should be ctFolderControl in order for 
    // control to display folder's contents.
    property FolderName: TFileName read FFolderName write SetFolderName;
    // If the control or its items can be painted with the 
    // bitmap image (glyph) use this property to specify the bitmap 
    // image to be painted. Painting glyphs may give 
    // your controls more attractive look yet highlight the control's purpose.
    property Glyph: TBitmap read GetGlyph write SetGlyph;
    // There's an opportunity to paint background image for 
    // selected items only. Among with using SelWallpaper there's 
    // a way to use CoolImages and idSelWallpaper 
    // properties to specify the image. This technique allows to 
    // save resources by using the same image for many controls. 
    // IdSelWallpaper indicates the index of the image in TcoolImages 
    // container. If the control has Options property it's necessary to 
    // include ocPaintSelWallpaper flag into he Options set to actually 
    // enable the painting of the selected wallpaper.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   SelWallpaper
    property idSelWallpaper: Integer read FidSelWallpaper write SetidSelWallpaper default -1;
    // There's an alternative for direct assigning of 
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties 
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper 
    // indicates the index of the image from CoolImages to be used. 
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    // Use Images to provide a customized list of images 
    // that can be displayed with the items.
    property Images: TImageList read FImages write SetImages;
    // Use LightColorControl to indicate whether 
    // ListView should contain only basic 16 colors 
    // or all possible colors. ExtendedStyle must be 
    // ctColorControl in order for control to display 
    // colors.
    property LightColorControl: Boolean read FLightColorControl write SetLightColorControl default True;
    // Width in pixels of the list box part of the control.
    property ListBoxWidth: Integer read FListBoxWidth write SetListBoxWidth;
    // NumGlyphs property indicates the number of images 
    // that are in the graphic specified in the Glyph 
    // property for use on a control.
    // If you have multiple images in a bitmap, you must 
    // specify the number of images that are in 
    // the bitmap with the NumGlyphs property. Valid NumGlyphs 
    // values are 1 to 4. The default value is 1.
    // 
    // See Also:
    //   Glyph
    property NumGlyphs: TNumGlyphs read GetNumGlyphs write SetNumGlyphs default 1;
    // Options property controls variety of various controls parameters, the combination of included and excluded flags  determines appearance and behavior of the control. The following items that being used separately or in combination define control's look, note that some flags can not be used together and the others can or even must, note also that not all flags can be supported by the particular control or component.
    // These flags can be used with the following meaning:
    // <P>
    // * <I>ocPaintWallpaper.</I> Whether you want to paint the wallpaper for control. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocStretchWallpaper.</I> Whether you like to stretch the image to fit all the control surface. If false image will be repeatedly painted to fill the control (tiled).
    // * <I>ocPaintSelWallpaper.</I> Whether you want to paint the wallpaper for selected items. SelWallpaper or combination of  CoolImages and idSelWallpaper properties must be assigned properly.
    // * <I>ocPaintCaptionWallpaper.</I> Whether you want to paint the wallpaper for control's caption (if the latest is visible). CaptionWallpaper or combination of  CoolImages and idCaptionWallpaper properties must be assigned properly.
    // * <I>ocPaintGradiently.</I> Whether you  want to paint the gradient background. Respective color properties define the background range colors.
    // * <I>ocInvertWallpaperAsSelect.</I> Whether you want to use the same wallpaper you use for control to highlight selected items. When presents selected items will be drawn using inverted Wallpaper image, Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocBevelOnlyIfSel.</I> Whether you like to paint bevel around all the control items or only around those selected. 
    // * <I>ocNoHighlightImage.</I> If the items have attached images determines whether those for selected items should or should not be highlighted among with the item.
    // * <I>ocNoImageAttached.</I> Whether control presumes that its items some with attached images If not there will not be extra space between border and items
    // * <I>ocUseImageList.</I> Whether images should be taken from the linked Image List component or directly from the Glyph property. 
    // * <I>oc3dMDIForm.</I> Whether MDI parent form has more 3D look.
    // * <I>ocWallpaperForMDIChildren.</I> Whether attached wallpaper should be painted for all MDI child windows. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocNoCaption.</I> Whether control has caption area. Some controls will not have caption even if this property set to True.
    // * <I>ocSmallCaption.</I> What kind of caption should be used for window (if possible) standard or small caption (like for tool windows).
    // * <I>ocNoMDIChildrensCaptions.</I> Whether MDI child windows should  be drawn with the captions.
    // * <I>ocDragUsingClientArea.</I> Is it possible to drag the form using its client area.
    // * <I>ocNoDragUsingCaption.</I> Is it possible to drag the form using its caption area.
    // * <I>ocRoundedForm.</I> Whether the form should have oval shape.
    // * <I>ocFlatBorder.</I> Whether control should be painted with the modern flat look.
    // * <I>ocPaintTransparently.</I> Whether the control should have its own background or use that of the parent container.
    property Options: TCoolOptions read FOptions write SetOptions default [ocBevelOnlyIfSel];
    // There's an opportunity to paint background image 
    // for selected items only. Use SelWallpaper 
    // to specify the image to be painted as wallpaper 
    // for selected items. Among with using SelWallpaper 
    // there's a way to use CoolImages and idSelWallpaper 
    // properties to specify the image. This technique 
    // allows to save resources by using the same image 
    // for many controls. IdSelWallpaper indicates the 
    // index of the image in TcoolImages container. If the 
    // control has Options property it's necessary to include 
    // ocPaintSelWallpaper flag into he Options set to 
    // actually enable the painting of the selected wallpaper.
    // 
    // See Also:
    //   Options
    //   idSelWallpaper
    //   CoolImages
    property SelWallpaper: TBitmap read GetSelWallpaper write SetSelWallpaper;
    // SelColor indicates the \color to be used to highlight selected items.
    property SelColor: TColor read FSelColor write FSelColor default clHighlight;
    // SelFot property points to the TFont object to be used to draw the text of the selected items.
    property SelFont: TFont read FSelFont write SetSelFont;

    // In the CoolControls package many controls that 
    // have captions or string items allow to paint 
    // these with the 3D effect. When you use this feature, 
    // use ShadowColor to set the color of the shadow dropped. 
    // The effect being achieved by painting the text 
    // twice - once with the main color and then with the 
    // ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   SimpleView
    property ShadowColor: TColor read FShadowColor write SetShadowColor default clBtnHighlight;
    // In the CoolControls package many controls that have captions 
    // or string items allow to paint these with the 3D effect. 
    // When you use this feature, use ShadowSiize to indicate the 
    // offset  of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and then 
    // with the ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowPos
    //   ShadowColor
    //   SimpleView
    property ShadowSize: Byte read FShadowSize write SetShadowSize default 1;
    // In the CoolControls package many controls that have captions or 
    // string items allow to paint these with the 3D effect. When 
    // you use this feature, use ShadowPos to indicate the position 
    // (relatively to the main text) of the shadow dropped. The effect 
    // being achieved by painting the text twice - once with the main 
    // color and then with the ShadowColor (allowing ShadowSize offset).
    // 
    // <TABLE>
    // Value              Meaning
    // -------            -------------------------
    // spLeftTop          Shadow is in the Left Top direction.
    // spLeftBottom       Shadow is in the Left Bottom direction.
    // spRightBottom      Shadow is in the Right Bottom direction.
    // spRightTop         Shadow is in the Right Top direction.
    // </TABLE>
    // 
    // See Also:
    //   ShadowSize
    //   ShadowColor
    //   SimpleView
    property ShadowPos: TShadowPosition read FShadowPos write SetShadowPos default spLeftTop;
    // In the CoolControls package many controls that have 
    // captions or string items allow to paint these with 
    // the 3D effect. When you use this feature, use ShadowPos 
    // to indicate the position (relatively to the main text) 
    // of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and 
    // then with the ShadowColor (allowing ShadowSize offset).
    // Use SimpleView to indicate whether you want to use the 
    // described feature  or you do not.
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   ShadowColor
    property SimpleView: Boolean read FSimpleView write SetSimpleView default False;

    // Use TransparencyLevel to specify the 
    // parent control whose part will be used 
    // to draw the background of the component. 
    // For example if control placed on the panel 
    // that is placed on the form, setting TransparencyLevel 
    // to 0 will force part of the panel to be used for 
    // painting of the transparent background, setting 
    // TransparencyLevel to 1 will force the part of the 
    // form to be selected on the controls device context 
    // when paint transparently.
    property TransparencyLevel: Byte read FTransparencyLevel write SetTransparencyLevel default 0;
    // If ExtendedStyle is ctFontControl use TrueType
    // property to indicate if you would like to list all
    // the fonts or True Type Fonts (TTF) only.
    property TrueType: Boolean read FTrueType write SetTrueType default False;
    // Use Wallpaper to specify the bitmap image 
    // that will be painted as background wallpaper 
    // for a control. In most cases CoolControls package 
    // requires ocPaintWallpaper flag included into 
    // Options property set in order to actually enable 
    // wallpaper painting. Mind you that there's an 
    // alternative way to attach the image to be painted 
    // on control's background - use CoolImages and idWallpaper 
    // properties for that. This technique allows to save system 
    // resources by sharing the same image between many controls.
    // 
    // See Also:
    //   Options
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Anchors;
    property BiDiMode;
    {$ENDIF}
    property Color;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Constraints;
    {$ENDIF}
    property Ctl3D;
    property DragCursor;
    {$IFDEF DELPHI4_OR_ABOVE}
    property DragKind;
    {$ENDIF}
    property DragMode;
    property DropDownCount;
    property Enabled;
    property Font;
    {$IFNDEF VER90}
    property ImeMode;
    property ImeName;
    {$ENDIF}
    property ItemHeight;
    property Items;
    property MaxLength;
    {$IFDEF DELPHI4_OR_ABOVE}
    property ParentBiDiMode;
    {$ENDIF}
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property Sorted;
    property TabOrder;
    property TabStop;
    property Text;
    property Visible;
    property OnChange;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnDrawItem;
    property OnDropDown;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnEndDock;
    {$ENDIF}
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMeasureItem;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnStartDock;
    {$ENDIF}
    property OnStartDrag;
    // OnMouseEnter event occurs immediately after mouse cursor enters the control.
    property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
    // OnMouseLeave event occurs immediately after mouse cursor leaves the control.
    property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
    // OnGlyphDraw event occurs before item's glyph drawing
    property OnGlyphDraw: TMyNotifyEvent read FOnGlyphDraw write FOnGlyphDraw; // by Starenko
  end;

  // Occurs when cell contents editing process is over, that is when user has
  // entered or modified the text in the cell and pressed return key
  //
  // <PRE>  
  //  Sender - Grid that contains the cell being edited
  //  ACol   - Column of the edited cell
  //  ARow   - Row of the edited cell
  //  Cellwidth - Width of the edited cell
  //  CellHeight - Height of the edited cell
  // </PRE>
  TEndCellEditingEvent = procedure(Sender: TObject; ACol, ARow: LongInt;
    var CellWidth, CellHeight: Integer) of Object;

  // TCoolStringGrid provides with a great number of useful features. As its accestor TCoolStringGrid
  // designed to work with textual data in a tabular format. Its features include handling multiline 
  // text, work with clipboard, edges, colors anf fonts for individual cells, ability to insert / remove 
  // columns and rows, save / load grid's data to disk file (including HTML format) and many others.
  TCoolStringGrid = class(TStringGrid)
  private
    FExOptions: TCoolOptions;
    FSelColor,
    FCaptionColor,
    FCaptionTextColor: TColor;
    FWallpaper,
    FSelWallpaper,
    FCaptionWallpaper: TBitmap;
    FWrappers: TList;
    FTextAlign,
    FFixedTextAlign: TAlignment;
    FInnerCellsBevel,
    FOuterCellsBevel: TPanelBevel;
    FCanEdit: Boolean;
    FAboutBox: TCCAboutBox;

    FCellMarginTop,
    FCellMarginLeft,
    FCellMarginRight,
    FCellMarginBottom: Integer;

    FOnPaint,
    FOnMouseEnter,
    FOnMouseLeave: TNotifyEvent;
    FOnEndCellEditing: TEndCellEditingEvent;

    FCoolImages: TCoolImages;
    FidWallpaper,
    FidSelWallpaper,
    FidCaptionWallpaper: Integer;
    FCoolImagesChangeLink: TCoolChangeLink;

    FTransparencyLevel: Byte;
    FGridFormat: Integer;

    //Private
    procedure SetExOptions(Value: TCoolOptions);
    procedure SetWallpaper(Value: TBitmap);
    function GetWallpaper: TBitmap;
    procedure SetSelWallpaper(Value: TBitmap);
    function GetSelWallpaper: TBitmap;
    procedure SetCaptionWallpaper(Value: TBitmap);
    function GetCaptionWallpaper: TBitmap;
    procedure SetCaptionColor(Value: TColor);
    procedure SetCaptionTextColor(Value: TColor);
    function GetColors(ACol, ARow: Integer): TColor;
    procedure SetColors(ACol, ARow: Integer; Value: TColor);
    function GetReadOnlyCells(ACol, ARow: Integer): Boolean;
    procedure SetReadOnlyCells(ACol, ARow: Integer; Value: Boolean);
    function GetWallpaperForCells(ACol, ARow: Integer): Boolean;
    procedure SetWallpaperForCells(ACol, ARow: Integer; Value: Boolean);
    function GetFonts(ACol, ARow: Integer): TFont;
    procedure SetFonts(ACol, ARow: Integer; Value: TFont);
    function GetCellTextAligns(ACol, ARow: Integer): TAlignment;
    procedure SetCellTextAligns(ACol, ARow: Integer; Value: TAlignment);
    procedure SetInnerCellsBevel(Value: TPanelBevel);
    procedure SetOuterCellsBevel(Value: TPanelBevel);
    procedure SetTextAlign(Value: TAlignment);
    procedure SetFixedTextAlign(Value: TAlignment);
    procedure SetSelColor(Value: TColor);
    procedure WallpaperChanged(Sender: TObject);
    procedure SetTransparencyLevel(Value: Byte);

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    procedure SetidSelWallpaper(Value: Integer);
    procedure SetidCaptionWallpaper(Value: Integer);

    procedure SetCellMarginTop(Value: Integer);
    procedure SetCellMarginLeft(Value: Integer);
    procedure SetCellMarginRight(Value: Integer);
    procedure SetCellMarginBottom(Value: Integer);

    function CTLDrawCaptionWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    function CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    function CTLDrawWallpaperEx(DC: HDC; R, SubRect: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    function CTLDrawSelWallpaperEx(DC: HDC; R, SubRect: TRect; IsStretch: Boolean; Mode: Integer): Boolean;

    function IsWallpaperAssigned: Boolean;
    function IsSelWallpaperAssigned: Boolean;
    procedure CoolImagesChange(Sender: TObject);

    //Messages
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
    procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
    procedure WMNCPaint (var Message: TMessage); message WM_NCPAINT;
    procedure WMNCLButtonDblClk(var Message: TWMNCLButtonDblClk); message WM_NCLBUTTONDBLCLK;
    procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
    procedure CMParentColorChanged(var Message: TMessage); message CM_PARENTCOLORCHANGED;
    procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
    procedure WMMove(var Message: TWMMove); message WM_MOVE;
    procedure WMSetText(var Message: TMessage); message WM_SETTEXT;
    procedure CMEndEditing(var Message: TMessage); message CM_ENDEDITING;

    //Wrapper
    function CreateWrapper(ACol, ARow: Integer): TObject;
    function ExtractWrapper(ACol, ARow: Integer): TObject;
    function GetWrapper(ACol, ARow: Integer): TObject;
    function HaveWrapper(ACol, ARow: Integer): Boolean;
  protected
    EditValue: string;
    procedure NCCtlChanged; virtual;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); override;
    procedure ColumnMoved(FromIndex, ToIndex: Longint); override;
    procedure RowMoved(FromIndex, ToIndex: Longint); override;
    procedure AdjustSize(Index, Amount: Longint; Rows: Boolean); override;
    procedure SetEditText(ACol, ARow: Longint; const Value: string); override;
    function GetEditText(ACol, ARow: Longint): string; override;
    function CreateEditor: TInplaceEdit; override;
    function SelectCell(ACol, ARow: Longint): Boolean; override;
    function CanEditShow: Boolean; override;
    procedure TopLeftChanged; override;
    procedure SetParent(AParent: TWinControl); override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  public
    property CellTextAligns[ACol, ARow: Integer]: TAlignment read GetCellTextAligns write SetCellTextAligns;
    // Run-time only. Use to set and obtain the \color
    // of the cell with ACol and ARow coordinates.
    property Colors[ACol, ARow: Integer]: TColor read GetColors write SetColors;
    // Run-time only. Use to set and obtain the \font
    // of the cell with ACol and ARow coordinates.
    property Fonts[ACol, ARow: Integer]: TFont read GetFonts write SetFonts;
    // Run-time only. Use to set and obtain the read-only state 
    // of the cell with ACol and ARow coordinates.
    property ReadOnlyCells[ACol, ARow: Integer]: Boolean read GetReadOnlyCells write SetReadOnlyCells;
    // Run-time only. Use to determine whether
    // the cell with ACol and ARow coordinates should be painted
    // with the wallpapers (if there wallpapers assigned).
    //
    // See Also:
    //   Wallpaper
    //   idWallpaper
    //   ExOptions
    property WallpaperForCells[ACol, ARow: Integer]: Boolean read GetWallpaperForCells write SetWallpaperForCells;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    // Deletes rows from the grid.
    //
    // Parameters:
    //   RowIndex - Index of the first row to delete from
    //   Amount   - Number of rows to be deleted.
    procedure DeleteRows(RowIndex, Amount: LongInt);
    // Inserts rows into the grid.
    //
    // Parameters:
    //   RowIndex - Index of the first row to insert from
    //   Amount   - Number of rows to be inserted.
    procedure InsertRows(RowIndex, Amount: LongInt);
    // Deletes columns from the grid.
    //
    // Parameters:
    //   ColIndex - Index of the first column to delete from
    //   Amount   - Number of columns to be deleted.
    procedure DeleteCols(ColIndex, Amount: LongInt);
    // Inserts columns into the grid.
    //
    // Parameters:
    //   RowIndex - Index of the first column to insert from
    //   Amount   - Number of columns to be inserted.
    procedure InsertCols(ColIndex, Amount: LongInt);
    // Searches the grid for the cell with the specified text.
    //
    // Result:
    //   Boolean value that indecates whether the performed search was successful.
    //
    // Parameters:
    //   SubStr - string to search the grid for.
    //   ACol   - if the search was successful the ACol parameter contains the index of the Column with the cell containing the text.
    //   ARow   - if the search was successful the ARow parameter contains the index of the Row with the cell containing the text.
    function PosCell(SubStr: string; var ACol, ARow: LongInt): Boolean;
    // Clears the entire grid, that is deletes all text from each cell.
    procedure Clear;
    // Use SaveToStream to save grid's contents into the stream.
    //
    // Parameters:
    //   AStream  - stream the grid's contents will be saved to.
    procedure SaveToStream(AStream: TStream);
    // Use LoadFromStream to load grid's contents from the stream.
    //
    // Parameters:
    //   AStream  - stream the grid's contents will be loaded from.
    procedure LoadFromStream(AStream: TStream);
    // Use SaveToFile to save grid's contents into the file.
    //
    // Parameters:
    //   AFileName  - name of the file the grid's contents will be saved to.
    procedure SaveToFile(AFileName: string);
    // Use LoadFromFile to load grid's contents from the file.
    //
    // Parameters:
    //   AFileName  - file the grid's contents will be loaded from.
    procedure LoadFromFile(AFileName: string);
    // Use SaveToHTMLFile to save grid's contents into the file in HTML format.
    // HTML file with the table representing the grid will be created.
    //
    // Parameters:
    //   AFileName  - name of the file the grid's contents will be saved to.
    procedure SaveToHTMLFile(AFileName: string);
    // Use CopyToClipboard to copy the entire grid's contents into Windows clipboard.
    procedure CopyToClipboard;
    // Use PasteFromClipboard to paste Windows clipboard's contents into the grid.
    procedure PasteFromClipboard;

    // Use CopyToClipboard to copy particular cell's contents into Windows clipboard.
    //
    // Parameters:
    //   ACol - column with the cell.
    //   ARow - row with the cell.
    procedure CopyToClipboardCell(ACol, ARow: LongInt);
    // Use CutToClipboard to cut particular cell's contents into Windows clipboard.
    //
    // Parameters:
    //   ACol - column with the cell.
    //   ARow - row with the cell.
    procedure CutToClipboardCell(ACol, ARow: LongInt);
    // Use PasteFromClipboard to paste contents of the Windows clipboard into particular cell.
    //
    // Parameters:
    //   ACol - column with the cell.
    //   ARow - row with the cell.
    procedure PasteFromClipboardCell(ACol, ARow: LongInt);

    // Set the parameters for all the cells in a specified column at once.
    //
    // Parameters:
    //  ACol               - Index of the column the operation will be performed for.
    //  AFixedInclude      - If the column contains fixed cells should the desired action be performed for them.
    //  AColor             - \Color for cells.
    //  AReadOnly          - \Read-only state of cells.
    //  AWallpaperAllowed  - Whether the cell should allow wallpapers painting (if there wallpapers assigned).
    //  AFont              - Font to use for cells.
    //  AAlign             - Align of the text within cells.
    procedure SetColumnParameters(ACol: Longint; AFixedInclude: Boolean; AColor: TColor; AReadOnly, AWallpaperAlloved: Boolean; AFont: TFont; ATextAlign: TAlignment);

    // Set the parameters for all the cells in a specified row at once.
    //
    // Parameters:
    //  ARow               - Index of the row the operation will be performed for.
    //  AFixedInclude      - If the column contains fixed cells should the desired action be performed for them.
    //  AColor             - \Color for cells.
    //  AReadOnly          - \Read-only state of cells.
    //  AWallpaperAllowed  - Whether the cell should allow wallpapers painting (if there wallpapers assigned).
    //  AFont              - Font to use for cells.
    //  AAlign             - Align of the text within cells.
    procedure SetRowParameters(ARow: Longint; AFixedInclude: Boolean; AColor: TColor; AReadOnly, AWallpaperAlloved: Boolean; AFont: TFont; ATextAlign: TAlignment);
  published   
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    // Some controls in the Coolcontrols package 
    // may have captions just like forms (they even 
    // can be dragged within the parent container).
    // Appearance of the caption controlled by ocNoCaption flag 
    // (Options property)  Caption can be wide or small (ocSmallCaption flag).
    // 
    // Use CaptionColor to set Color of the control's Caption (when 
    // it is visible). clInctiveCaption is the default value.
    property CaptionColor: TColor read FCaptionColor write SetCaptionColor default clInactiveCaption;
    // Some controls in the Coolcontrols package may 
    // have captions just like forms (they even can be 
    // dragged within the parent container). Appearance 
    // of the caption controlled by ocNoCaption flag (Options 
    // property)  Caption can be wide or small (ocSmallCaption flag).
    // 
    // Use CaptionTextColor to set the \color of the control's Caption
    // text (when caption is visible). clInctiveCaptionText is the 
    // default value. The caption text itself is being set by Caption 
    // property.
    property CaptionTextColor: TColor read FCaptionTextColor write SetCaptionTextColor default clInactiveCaptionText;
    // Some controls in the CoolControls package may have 
    // captions just like forms (they even can be dragged 
    // within the parent container). Appearance of the caption 
    // controlled by ocNoCaption flag (Options property)
    // Caption can be wide or small (ocSmallCaption flag).
    // 
    // Use CaptionWallpaper to specify the bitmap image to be 
    // painted as wallpaper for the caption (when caption is visible).  
    // 
    // There's another possible solution, instead of assigning 
    // CaptionWallpaper property you can use CoolImages and idCaptionWallpaper 
    // properties. This way you save system resources by using the same image for 
    // many controls.
    // 
    // See Also:
    //   Options
    //   idCaptionWallpaper
    //   CoolImages
    property CaptionWallpaper: TBitmap read GetCaptionWallpaper write SetCaptionWallpaper;
    // Top offset when paint the cell.
    //
    // See Also:
    //   CellMarginTop
    property CellMarginTop: Integer read FCellMarginTop write SetCellMarginTop default 2;
    // Left offset when paint the cell.
    //
    // See Also:
    //   CellMarginLeft
    property CellMarginLeft: Integer read FCellMarginLeft write SetCellMarginLeft default 2;
    // Right offset when paint the cell.
    //
    // See Also:
    //   CellMarginRight
    property CellMarginRight: Integer read FCellMarginRight write SetCellMarginRight default -2;
    // Bottom offset when paint the cell.
    //
    // See Also:
    //   CellMarginBottom
    property CellMarginBottom: Integer read FCellMarginBottom write SetCellMarginBottom default -2;
    // Use CoolImages property to specify  TCoolImages component will be used
    // to load images for wallpapers from. TcoolImages acts much like
    // TImageList that is behaves as placeholder for images. It can contain
    // images only but images of different sizes and color modes can be stored
    // together in the same object.
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // ExOptions property controls variety of various controls parameters, the combination of included and excluded flags  determines appearance and behavior of the control. The following items that being used separately or in combination define control's look, note that some flags can not be used together and the others can or even must, note also that not all flags can be supported by the particular control or component.
    // These flags can be used with the following meaning:
    // <P>
    // * <I>ocPaintWallpaper.</I> Whether you want to paint the wallpaper for control. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocPaintSelWallpaper.</I> Whether you want to paint the wallpaper for selected items. SelWallpaper or combination of  CoolImages and idSelWallpaper properties must be assigned properly.
    // * <I>ocPaintCaptionWallpaper.</I> Whether you want to paint the wallpaper for control's caption (if the latest is visible). CaptionWallpaper or combination of  CoolImages and idCaptionWallpaper properties must be assigned properly.
    // * <I>ocPaintGradiently.</I> Whether you  want to paint the gradient background. Respective color properties define the background range colors.
    // * <I>ocInvertWallpaperAsSelect.</I> Whether you want to use the same wallpaper you use for control to highlight selected items. When presents selected items will be drawn using inverted Wallpaper image, Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocBevelOnlyIfSel.</I> Whether you like to paint bevel around all the control items or only around those selected. 
    // * <I>ocNoHighlightImage.</I> If the items have attached images determines whether those for selected items should or should not be highlighted among with the item.
    // * <I>ocNoImageAttached.</I> Whether control presumes that its items some with attached images If not there will not be extra space between border and items
    // * <I>ocUseImageList.</I> Whether images should be taken from the linked Image List component or directly from the Glyph property. 
    // * <I>oc3dMDIForm.</I> Whether MDI parent form has more 3D look.
    // * <I>ocWallpaperForMDIChildren.</I> Whether attached wallpaper should be painted for all MDI child windows. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocNoCaption.</I> Whether control has caption area. Some controls will not have caption even if this property set to True.
    // * <I>ocSmallCaption.</I> What kind of caption should be used for window (if possible) standard or small caption (like for tool windows).
    // * <I>ocNoMDIChildrensCaptions.</I> Whether MDI child windows should  be drawn with the captions.
    // * <I>ocDragUsingClientArea.</I> Is it possible to drag the form using its client area.
    // * <I>ocNoDragUsingCaption.</I> Is it possible to drag the form using its caption area.
    // * <I>ocRoundedForm.</I> Whether the form should have oval shape.
    // * <I>ocFlatBorder.</I> Whether control should be painted with the modern flat look.
    // * <I>ocPaintTransparently.</I> Whether the control should have its own background or use that of the parent container.
    property ExOptions: TCoolOptions read FExOptions write SetExOptions default [ocNoCaption];
    // Sets the alignment used when displaying text within fixed cells of the control.
    // 
    // <TABLE>
    // Value                    Meaning
    // ------------             ------------
    // taLeftJustify            Text will be left aligned (default)
    // taRightJustify           Text will be right aligned 
    // taCenter	                Text will be center aligned 
    // </TABLE>
    property FixedTextAlign: TAlignment read FFixedTextAlign write SetFixedTextAlign default taLeftJustify;
    // If you like you can specify the bevel to be
    // painted for each cell. There re two bevels define the
    // ook of the individual cell - OuterCellsBevel and InnerCellsBevel.
    // 
    // These are the possible values of bevels:
    // 
    // <TABLE>
    // Value		Meaning
    // -------  	--------
    // pbNone		No bevel, appears flat.
    // pbLowered	Appears recessed.
    // pbRaised	Appears raised.
    // </TABLE>
    // 
    // Combination of both bevels define the look of the control.
    property InnerCellsBevel: TPanelBevel read FInnerCellsBevel write SetInnerCellsBevel default bvNone;
    // Some controls in the CoolControls 
    // package may have captions just like 
    // forms (they even can be dragged within 
    // the parent container). Appearance of the 
    // caption controlled by ocNoCaption flag 
    // (Options property)  Caption can be wide
    // or small (ocSmallCaption flag).
    // 
    // Use CaptionWallpaper to specify the bitmap image 
    // to be painted as wallpaper for the caption 
    // (when caption is visible).  
    // 
    // There's another possible solution, instead of 
    // assigning CaptionWallpaper property you can 
    // use CoolImages and idCaptionWallpaper properties. This 
    // way you save system resources by using the 
    // same image for many controls.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   CaptionWallpaper
    property idCaptionWallpaper: Integer read FidCaptionWallpaper write SetidCaptionWallpaper default -1;
    // There's an opportunity to paint background image for 
    // selected items only. Among with using SelWallpaper there's 
    // a way to use CoolImages and idSelWallpaper 
    // properties to specify the image. This technique allows to
    // save resources by using the same image for many controls. 
    // IdSelWallpaper indicates the index of the image in TcoolImages 
    // container. If the control has Options property it's necessary to 
    // include ocPaintSelWallpaper flag into he Options set to actually 
    // enable the painting of the selected wallpaper.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   SelWallpaper
    property idSelWallpaper: Integer read FidSelWallpaper write SetidSelWallpaper default -1;
    // There's an alternative for direct assigning of 
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties 
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper 
    // indicates the index of the image from CoolImages to be used. 
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    // If you like you can specify the bevel to be
    // painted for each cell. There re two bevels define the
    // ook of the individual cell - OuterCellsBevel and InnerCellsBevel.
    // 
    // These are the possible values of bevels:
    // 
    // <TABLE>
    // Value		Meaning
    // -------  	--------
    // pbNone		No bevel, appears flat.
    // pbLowered	Appears recessed.
    // pbRaised	Appears raised.
    // </TABLE>
    // 
    // Combination of both bevels define the look of the control.
    property OuterCellsBevel: TPanelBevel read FOuterCellsBevel write SetOuterCellsBevel default bvNone;
    // SelColor indicates the \color to be used to highlight selected items.
    property SelColor: TColor read FSelColor write SetSelColor default clHighLight;
    // There's an opportunity to paint background image 
    // for selected items only. Use SelWallpaper 
    // to specify the image to be painted as wallpaper 
    // for selected items. Among with using SelWallpaper 
    // there's a way to use CoolImages and idSelWallpaper 
    // properties to specify the image. This technique 
    // allows to save resources by using the same image 
    // for many controls. IdSelWallpaper indicates the 
    // index of the image in TcoolImages container. If the 
    // control has Options property it's necessary to include 
    // ocPaintSelWallpaper flag into he Options set to 
    // actually enable the painting of the selected wallpaper.
    // 
    // See Also:
    //   Options
    //   idSelWallpaper
    //   CoolImages
    property SelWallpaper: TBitmap read GetSelWallpaper write SetSelWallpaper;
    // Sets the alignment used when displaying text.
    // 
    // <TABLE>
    // Value                    Meaning
    // ----------------         -----------------------------------
    // taLeftJustify            Text will be left aligned (default)
    // taRightJustify           Text will be right aligned 
    // taCenter                 Text will be center aligned 
    // </TABLE>
    property TextAlign: TAlignment read FTextAlign write SetTextAlign default taLeftJustify;
    // Use TransparencyLevel to specify the 
    // parent control whose part will be used 
    // to draw the background of the component. 
    // For example if control placed on the panel 
    // that is placed on the form, setting TransparencyLevel 
    // to 0 will force part of the panel to be used for 
    // painting of the transparent background, setting 
    // TransparencyLevel to 1 will force the part of the 
    // form to be selected on the controls device context 
    // when paint transparently.
    property TransparencyLevel: Byte read FTransparencyLevel write SetTransparencyLevel default 0;
    // Use Wallpaper to specify the bitmap image 
    // that will be painted as background wallpaper 
    // for a control. In most cases CoolControls package 
    // requires ocPaintWallpaper flag included into 
    // Options property set in order to actually enable 
    // wallpaper painting. Mind you that there's an 
    // alternative way to attach the image to be painted 
    // on control's background - use CoolImages and idWallpaper 
    // properties for that. This technique allows to save system 
    // resources by sharing the same image between many controls.
    // 
    // See Also:
    //   Options
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
    // OnMouseEnter event occurs immediately after mouse cursor enters the control.
    property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
    // OnMouseLeave event occurs immediately after mouse cursor leaves the control.
    property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
    // Occurs when finish editing particular cell's content's
    property OnEndCellEditing: TEndCellEditingEvent read FOnEndCellEditing write FOnEndCellEditing;
    // Occurs when control being repainted.
    property OnPaint: TNotifyEvent read FOnPaint write FOnPaint;
    // Use Caption to associate the control with a text string that identifies the control. 
    // For most controls, the Caption is the window title and 
    // it appears as a label for the control.
    property Caption;
  end;

  // TCoolInplaceEdit is advanced TInplaceEdit control written to be used together
  // with the TCoolStringGrid control. It has properties and methods to support the advanced
  // features of a latter.
  TCoolInplaceEdit = class(TInplaceEdit)
  private
    FAboutBox: TCCAboutBox;
    FBeingPainted: Boolean;
    FOptions: TCoolOptions;
    FReturnWanted: Boolean;
    FTextAlign: TAlignment;
    FWallpaper: TBitmap;
    FTransparencyLevel: Byte;

    FOnMouseEnter,
    FOnMouseLeave: TNotifyEvent;

    FCoolImages: TCoolImages;
    FidWallpaper: Integer;
    FCoolImagesChangeLink: TCoolChangeLink;

    FEdgeBorders: TEdgeBorders;
    FBorderPen: TPen;
    FBordersTrColor: TColor;

    procedure BorderPenChange(Sender: TObject);

    procedure SetOptions(Value: TCoolOptions);
    procedure SetTextAlign(Value: TAlignment);
    procedure SetTransparencyLevel(Value: Byte);
    procedure SetEdgeBorders(Value: TEdgeBorders);
    procedure SetBorderPen(Value: TPen);
    procedure SetBordersTrColor(Value: TColor);

    procedure SetWallpaper(Value: TBitmap);
    function GetWallpaper: TBitmap;
    procedure WallpaperChanged(Sender: TObject);

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    function CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    function IsWallpaperAssigned: Boolean;
    procedure CoolImagesChange(Sender: TObject);

    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure WMEraseBkGnd(var Message: TWMEraseBkGnd); message WM_ERASEBKGND;
    procedure CNCtlColorEdit(var Message: TWMCtlColorEdit); message CN_CTLCOLOREDIT;
    procedure CNCtlColorStatic(var Message: TWMCtlColorStatic); message CN_CTLCOLORSTATIC;
    procedure WMNCPaint (var Message: TMessage); message WM_NCPAINT;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
    procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
    procedure CMParentColorChanged(var Message: TMessage); message CM_PARENTCOLORCHANGED;
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
    procedure WMMove(var Message: TWMMove); message WM_MOVE;
  protected
    procedure CreateWnd; override;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyUp(var Key: Word; Shift: TShiftState); override;
    procedure KeyPress(var Key: Char); override;
    procedure DoPaint; dynamic;
    procedure Change; override;
    procedure SetParent(AParent: TWinControl); override;
    procedure WndProc(var Message: TMessage); override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    property PasswordChar;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published   
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    // It's possible to draw the edges (borders) for control. Based on EdgeBorders values you can control what borders will be drawn and the BorderPen property points to the pen object used to draw the borders around control.
    // 
    // See Also:
    //   EdgeBorders
    property BorderPen: TPen read FBorderPen write SetBorderPen;
    // If EdgeBorders specified (any) and BordersTrColor is different from clNone there will be painted borders for NON DEFINED edges with the BordersTrColor color. That makes sense if BorderStyle is bsSingle and you would like to make all but one or few edges transparent. Alternatively you can set BorderStyle to  bsNone.
    //
    // See Also:
    //   EdgeBorders
    //   BorderPen
    property BordersTrColor: TColor read FBordersTrColor write SetBordersTrColor default clNone;
    // Use CoolImages property to specify  TCoolImages component will be used 
    // to load images for wallpapers from. TcoolImages acts much like 
    // TImageList that is behaves as placeholder for images. It can contain 
    // images only but images of different sizes and color modes can be stored 
    // together in the same object.
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // It's possible to draw the edges (borders) for control. 
    // Based on EdgeBorders values you can control what borders 
    // will be drawn and the BorderPen property points to the 
    // pen object used to draw the borders around control. And  
    // the EdgeBorders property used to add or remove borders.
    property EdgeBorders: TEdgeBorders read FEdgeBorders write SetEdgeBorders default [];
    // There's an alternative for direct assigning of 
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties 
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper 
    // indicates the index of the image from CoolImages to be used.
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    // Use Wallpaper to specify the bitmap image 
    // that will be painted as background wallpaper 
    // for a control. In most cases CoolControls package 
    // requires ocPaintWallpaper flag included into 
    // Options property set in order to actually enable 
    // wallpaper painting. Mind you that there's an 
    // alternative way to attach the image to be painted 
    // on control's background - use CoolImages and idWallpaper 
    // properties for that. This technique allows to save system 
    // resources by sharing the same image between many controls.
    // 
    // See Also:
    //   Options
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
    // Options property controls variety of various controls parameters, the combination of included and excluded flags  determines appearance and behavior of the control. The following items that being used separately or in combination define control's look, note that some flags can not be used together and the others can or even must, note also that not all flags can be supported by the particular control or component.
    // These flags can be used with the following meaning:
    // <P>
    // * <I>ocPaintWallpaper.</I> Whether you want to paint the wallpaper for control. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocStretchWallpaper.</I> Whether you like to stretch the image to fit all the control surface. If false image will be repeatedly painted to fill the control (tiled).
    // * <I>ocPaintSelWallpaper.</I> Whether you want to paint the wallpaper for selected items. SelWallpaper or combination of  CoolImages and idSelWallpaper properties must be assigned properly.
    // * <I>ocPaintCaptionWallpaper.</I> Whether you want to paint the wallpaper for control's caption (if the latest is visible). CaptionWallpaper or combination of  CoolImages and idCaptionWallpaper properties must be assigned properly.
    // * <I>ocPaintGradiently.</I> Whether you  want to paint the gradient background. Respective color properties define the background range colors.
    // * <I>ocInvertWallpaperAsSelect.</I> Whether you want to use the same wallpaper you use for control to highlight selected items. When presents selected items will be drawn using inverted Wallpaper image, Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocBevelOnlyIfSel.</I> Whether you like to paint bevel around all the control items or only around those selected. 
    // * <I>ocNoHighlightImage.</I> If the items have attached images determines whether those for selected items should or should not be highlighted among with the item.
    // * <I>ocNoImageAttached.</I> Whether control presumes that its items some with attached images If not there will not be extra space between border and items
    // * <I>ocUseImageList.</I> Whether images should be taken from the linked Image List component or directly from the Glyph property. 
    // * <I>oc3dMDIForm.</I> Whether MDI parent form has more 3D look.
    // * <I>ocWallpaperForMDIChildren.</I> Whether attached wallpaper should be painted for all MDI child windows. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocNoCaption.</I> Whether control has caption area. Some controls will not have caption even if this property set to True.
    // * <I>ocSmallCaption.</I> What kind of caption should be used for window (if possible) standard or small caption (like for tool windows).
    // * <I>ocNoMDIChildrensCaptions.</I> Whether MDI child windows should  be drawn with the captions.
    // * <I>ocDragUsingClientArea.</I> Is it possible to drag the form using its client area.
    // * <I>ocNoDragUsingCaption.</I> Is it possible to drag the form using its caption area.
    // * <I>ocRoundedForm.</I> Whether the form should have oval shape.
    // * <I>ocFlatBorder.</I> Whether control should be painted with the modern flat look.
    // * <I>ocPaintTransparently.</I> Whether the control should have its own background or use that of the parent container.
    property Options: TCoolOptions read FOptions write SetOptions default [];
    // Sets the alignment used when displaying text.
    // 
    // <TABLE>
    // Value                    Meaning
    // ----------------         ---------------------------------------
    // taLeftJustify            Text will be left aligned (default)
    // taRightJustify           Text will be right aligned 
    // taCenter	                Text will be center aligned 
    // </TABLE>
    property TextAlign: TAlignment read FTextAlign write SetTextAlign default taLeftJustify;
    // Use TransparencyLevel to specify the 
    // parent control whose part will be used 
    // to draw the background of the component. 
    // For example if control placed on the panel
    // that is placed on the form, setting TransparencyLevel 
    // to 0 will force part of the panel to be used for 
    // painting of the transparent background, setting 
    // TransparencyLevel to 1 will force the part of the 
    // form to be selected on the controls device context 
    // when paint transparently.
    property TransparencyLevel: Byte read FTransparencyLevel write SetTransparencyLevel default 0;
    property Color;
    property Font;
  end;

  // TCoolEdit is an advanced edit control that comes with the variety of features,
  // wallpapers, transparency, modern flat look, custom text alignment and more enhancements.
  TCoolEdit = class(TCustomEdit)
  private
    FAboutBox: TCCAboutBox;
    FBeingPainted: Boolean;
    FOptions: TCoolOptions;
    FReturnWanted: Boolean;
    FTextAlign: TAlignment;
    FWallpaper: TBitmap;
    
    FTransparencyLevel: Byte;

    FOnMouseEnter,
    FOnMouseLeave: TNotifyEvent;

    FCoolImages: TCoolImages;
    FidWallpaper: Integer;
    FCoolImagesChangeLink: TCoolChangeLink;

    FEdgeBorders: TEdgeBorders;
    FBorderPen: TPen;
    FBordersTrColor: TColor;

    procedure BorderPenChange(Sender: TObject);

    procedure SetOptions(Value: TCoolOptions);
    procedure SetTextAlign(Value: TAlignment);
    procedure SetTransparencyLevel(Value: Byte);
    procedure SetEdgeBorders(Value: TEdgeBorders);
    procedure SetBorderPen(Value: TPen);
    procedure SetBordersTrColor(Value: TColor);

    procedure SetWallpaper(Value: TBitmap);
    function GetWallpaper: TBitmap;
    procedure WallpaperChanged(Sender: TObject);

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    function CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    function IsWallpaperAssigned: Boolean;
    procedure CoolImagesChange(Sender: TObject);

    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure WMEraseBkGnd(var Message: TWMEraseBkGnd); message WM_ERASEBKGND;
    procedure CNCtlColorEdit(var Message: TWMCtlColorEdit); message CN_CTLCOLOREDIT;
    procedure CNCtlColorStatic(var Message: TWMCtlColorStatic); message CN_CTLCOLORSTATIC;
    procedure WMNCPaint (var Message: TMessage); message WM_NCPAINT;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
    procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
    procedure CMParentColorChanged(var Message: TMessage); message CM_PARENTCOLORCHANGED;
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
    procedure WMMove(var Message: TWMMove); message WM_MOVE;
  protected
    procedure CreateWnd; override;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyUp(var Key: Word; Shift: TShiftState); override;
    procedure KeyPress(var Key: Char); override;
    procedure DoPaint; dynamic;
    procedure Change; override;
    procedure SetParent(AParent: TWinControl); override;
    procedure WndProc(var Message: TMessage); override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    property PasswordChar;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    // It's possible to draw the edges (borders) for control. Based on EdgeBorders values you can control what borders will be drawn and the BorderPen property points to the pen object used to draw the borders around control.
    //
    // See Also:
    //   EdgeBorders
    property BorderPen: TPen read FBorderPen write SetBorderPen;
    // If EdgeBorders specified (any) and BordersTrColor is different from clNone there will be painted borders for NON DEFINED edges with the BordersTrColor color. That makes sense if BorderStyle is bsSingle and you would like to make all but one or few edges transparent. Alternatively you can set BorderStyle to  bsNone.
    //
    // See Also:
    //   EdgeBorders
    //   BorderPen
    property BordersTrColor: TColor read FBordersTrColor write SetBordersTrColor default clNone;
    // Use CoolImages property to specify  TCoolImages component will be used
    // to load images for wallpapers from. TcoolImages acts much like
    // TImageList that is behaves as placeholder for images. It can contain
    // images only but images of different sizes and color modes can be stored
    // together in the same object.
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // It's possible to draw the edges (borders) for control.
    // Based on EdgeBorders values you can control what borders
    // will be drawn and the BorderPen property points to the
    // pen object used to draw the borders around control. And
    // the EdgeBorders property used to add or remove borders.
    property EdgeBorders: TEdgeBorders read FEdgeBorders write SetEdgeBorders default [];
    // There's an alternative for direct assigning of
    // the Wallpaper property for cases when you want
    // to paint the image background for the
    // control - use CoolImages and idWallpaper properties
    // for that. This technique allows to save system resources
    // by sharing the same image between many controls. IdWallpaper
    // indicates the index of the image from CoolImages to be used.
    // For controls that have Options property it's necessary to
    // include ocPaintWallpaper flag (Options property) to enable
    // the wallpaper painting.
    //
    // See Also:
    //   Options
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    // Use Wallpaper to specify the bitmap image
    // that will be painted as background wallpaper
    // for a control. In most cases CoolControls package
    // requires ocPaintWallpaper flag included into
    // Options property set in order to actually enable
    // wallpaper painting. Mind you that there's an
    // alternative way to attach the image to be painted
    // on control's background - use CoolImages and idWallpaper
    // properties for that. This technique allows to save system
    // resources by sharing the same image between many controls.
    //
    // See Also:
    //   Options
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
    // Options property controls variety of various controls parameters, the combination of included and excluded flags  determines appearance and behavior of the control. The following items that being used separately or in combination define control's look, note that some flags can not be used together and the others can or even must, note also that not all flags can be supported by the particular control or component.
    // These flags can be used with the following meaning:
    // <P>
    // * <I>ocPaintWallpaper.</I> Whether you want to paint the wallpaper for control. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocStretchWallpaper.</I> Whether you like to stretch the image to fit all the control surface. If false image will be repeatedly painted to fill the control (tiled).
    // * <I>ocPaintSelWallpaper.</I> Whether you want to paint the wallpaper for selected items. SelWallpaper or combination of  CoolImages and idSelWallpaper properties must be assigned properly.
    // * <I>ocPaintCaptionWallpaper.</I> Whether you want to paint the wallpaper for control's caption (if the latest is visible). CaptionWallpaper or combination of  CoolImages and idCaptionWallpaper properties must be assigned properly.
    // * <I>ocPaintGradiently.</I> Whether you  want to paint the gradient background.
    // * <I>ocInvertWallpaperAsSelect.</I> Whether you want to use the same wallpaper you use for control to highlight selected items. When presents selected items will be drawn using inverted Wallpaper image, Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocBevelOnlyIfSel.</I> Whether you like to paint bevel around all the control items or only around those selected.
    // * <I>ocNoHighlightImage.</I> If the items have attached images determines whether those for selected items should or should not be highlighted among with the item.
    // * <I>ocNoImageAttached.</I> Whether control presumes that its items some with attached images If not there will not be extra space between border and items
    // * <I>ocUseImageList.</I> Whether images should be taken from the linked Image List component or directly from the Glyph property.
    // * <I>oc3dMDIForm.</I> Whether MDI parent form has more 3D look.
    // * <I>ocWallpaperForMDIChildren.</I> Whether attached wallpaper should be painted for all MDI child windows. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocNoCaption.</I> Whether control has caption area. Some controls will not have caption even if this property set to True.
    // * <I>ocSmallCaption.</I> What kind of caption should be used for window (if possible) standard or small caption (like for tool windows).
    // * <I>ocNoMDIChildrensCaptions.</I> Whether MDI child windows should  be drawn with the captions.
    // * <I>ocDragUsingClientArea.</I> Is it possible to drag the form using its client area.
    // * <I>ocNoDragUsingCaption.</I> Is it possible to drag the form using its caption area.
    // * <I>ocRoundedForm.</I> Whether the form should have oval shape.
    // * <I>ocFlatBorder.</I> Whether control should be painted with the modern flat look.
    // * <I>ocPaintTransparently.</I> Whether the control should have its own background or use that of the parent container.
    property Options: TCoolOptions read FOptions write SetOptions default [];
    // Sets the alignment used when displaying text.
    //
    // <TABLE>
    // Value                    Meaning
    // ----------------         -------------------------------------
    // taLeftJustify            Text will be left aligned (default)
    // taRightJustify           Text will be right aligned
    // taCenter	                Text will be center aligned
    // </TABLE>
    property TextAlign: TAlignment read FTextAlign write SetTextAlign default taLeftJustify;
    // Use TransparencyLevel to specify the 
    // parent control whose part will be used 
    // to draw the background of the component. 
    // For example if control placed on the panel
    // that is placed on the form, setting TransparencyLevel 
    // to 0 will force part of the panel to be used for 
    // painting of the transparent background, setting 
    // TransparencyLevel to 1 will force the part of the 
    // form to be selected on the controls device context 
    // when paint transparently.
    property TransparencyLevel: Byte read FTransparencyLevel write SetTransparencyLevel default 0;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Anchors;
    {$ENDIF}
    property AutoSelect;
    property AutoSize;
    {$IFDEF DELPHI4_OR_ABOVE}
    property BiDiMode;
    {$ENDIF}
    property BorderStyle;
    property CharCase;
    property Color;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Constraints;
    {$ENDIF}
    property Ctl3D;
    property DragCursor;
    {$IFDEF DELPHI4_OR_ABOVE}
    property DragKind;
    {$ENDIF}
    property DragMode;
    property Enabled;
    property Font;
    property HideSelection;
    {$IFNDEF VER90}
    property ImeMode;
    property ImeName;
    {$ENDIF}
    property MaxLength;
    property OEMConvert;
    {$IFDEF DELPHI4_OR_ABOVE}
    property ParentBiDiMode;
    {$ENDIF}
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ReadOnly;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Text;
    property Visible;
    property OnChange;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnEndDock;
    {$ENDIF}
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnStartDock;
    {$ENDIF}
    property OnStartDrag;
    // OnMouseEnter event occurs immediately after mouse cursor enters the control.
    property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
    // OnMouseLeave event occurs immediately after mouse cursor leaves the control.
    property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  end;

  // TCoolEdit is an advanced edit control that comes with the variety of features,
  // wallpapers, transparency, modern flat look, custom text alignment and more enhancements.
  // In comparision with TCoolEdit, TCoolEditBtn allows you to add speed button to the edit control.
  TCoolEditBtn = class(TCoolEdit)
  private
    FButton: TSpeedButton;
    FOnBtnClick: TNotifyEvent;

    function GetMinHeight: Integer;
    procedure SetEditRect;

    function GetGlyph: TBitmap;
    procedure SetGlyph(Value: TBitmap);
    procedure SetBtnCaption(Value: TCaption);
    function GetBtnCaption: TCaption;
    function GetNumGlyphs: TNumGlyphs;
    procedure SetNumGlyphs(Value: TNumGlyphs);

    procedure WMSize(var Message: TWMSize); message WM_SIZE;
    procedure BtnClick(Sender: TObject);
  protected
    procedure CreateWnd; override;
    procedure CreateParams(var Params: TCreateParams); override;
    {$IFDEF DELPHI4_OR_ABOVE}
    procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
    {$ENDIF}
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    // Run-time and read-only. Button property points to the TSpeedButton
    // control attached to edit control. There is  special OnBtnClick event 
    // associated with this button. 
    property Button: TSpeedButton read FButton;
  published
    // Use this property to specify the bitmap to be drawn with the TSpeedButton
    // control used with the edit. 
    property Glyph: TBitmap read GetGlyph write SetGlyph;
    // Use BtnCaption to associate the control with a text string that identifies the control. 
    property BtnCaption: TCaption read GetBtnCaption write SetBtnCaption;
    // NumGlyphs property indicates the number of images 
    // that are in the graphic specified in the Glyph 
    // property for use on a control.
    // If you have multiple images in a bitmap, you must 
    // specify the number of images that are in 
    // the bitmap with the NumGlyphs property. Valid NumGlyphs 
    // values are 1 to 4. The default value is 1.
    // 
    // See Also:
    //   Glyph
    property NumGlyphs: TNumGlyphs read GetNumGlyphs write SetNumGlyphs default 1;
    // Event being fired immediately after the mouse click in
    // the attached speed button area oxxurs. Use event to
    // write custom code to be called as a reaction on click.
    property OnBtnClick: TNotifyEvent read FOnBtnClick write FOnBtnClick;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Action;
    {$ENDIF}
  end;

  // TCoolMemo is an advanced memo control. With TCoolMemo it is possible to
  // use wallpapders, transparency, chose text align an other visual effects 
  // in the memo control.
  TCoolMemo = class(TCustomMemo)
  private
    FCaption: TCaption;
    FCaptionColor,
    FCaptionTextColor: TColor;
    FCaptionWallpaper: TBitmap;

    FOptions: TCoolOptions;
    FTextAlign: TAlignment;
    FWallpaper: TBitmap;
    FAboutBox: TCCAboutBox;
    FOnMouseEnter,
    FOnMouseLeave: TNotifyEvent;

    FOldSelStart: Integer;
    FBeingPainted: Boolean;
    FTransparencyLevel: Byte;

    FCoolImages: TCoolImages;
    FidWallpaper,
    FidCaptionWallpaper: Integer;
    FCoolImagesChangeLink: TCoolChangeLink;

    FEdgeBorders: TEdgeBorders;
    FBorderPen: TPen;
    FBordersTrColor: TColor;

    procedure BorderPenChange(Sender: TObject);

    //Setting of properties
    procedure SetOptions(Value: TCoolOptions);
    procedure SetTextAlign(Value: TAlignment);
    procedure SetWallpaper(Value: TBitmap);
    function GetWallpaper: TBitmap;
    procedure SetCaptionWallpaper(Value: TBitmap);
    function GetCaptionWallpaper: TBitmap;
    procedure SetCaptionColor(Value: TColor);
    procedure SetCaptionTextColor(Value: TColor);
    procedure SetTransparencyLevel(Value: Byte);
    procedure SetCaption(Value: TCaption);
    function GetCaption: TCaption;

    procedure SetEdgeBorders(Value: TEdgeBorders);
    procedure SetBorderPen(Value: TPen);
    procedure SetBordersTrColor(Value: TColor);

    procedure WallpaperChanged(Sender: TObject);

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    procedure SetidCaptionWallpaper(Value: Integer);
    function CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    function CTLDrawCaptionWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    function IsWallpaperAssigned: Boolean;
    procedure CoolImagesChange(Sender: TObject);

    //Messages
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure WMEraseBkGnd(var Message: TWMEraseBkGnd); message WM_ERASEBKGND;
    procedure CNCtlColorEdit(var Message: TWMCtlColorEdit); message CN_CTLCOLOREDIT;
    procedure CNCtlColorStatic(var Message: TWMCtlColorStatic); message CN_CTLCOLORSTATIC;
    procedure WMNCPaint (var Message: TMessage); message WM_NCPAINT;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
    procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
    procedure CMParentColorChanged(var Message: TMessage); message CM_PARENTCOLORCHANGED;
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
    procedure WMMove(var Message: TWMMove); message WM_MOVE;
    procedure CNCommand(var Msg: TWMCommand); message CN_COMMAND;
    procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
    procedure WMSetText(var Message: TMessage); message WM_SETTEXT;
    procedure WMNCLButtonDblClk(var Message: TWMNCLButtonDblClk); message WM_NCLBUTTONDBLCLK;
  protected
    procedure CreateWnd; override;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyUp(var Key: Word; Shift: TShiftState); override;
    procedure KeyPress(var Key: Char); override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure DoPaint; dynamic;
    procedure Change; override;
    procedure WndProc(var Message: TMessage); override;
    procedure SetParent(AParent: TWinControl); override;
    procedure NCCtlChanged; virtual;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure SetFocus; override;
  published
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    // It's possible to draw the edges (borders) for control. Based on EdgeBorders values you can control what borders will be drawn and the BorderPen property points to the pen object used to draw the borders around control.
    // 
    // See Also:
    //   EdgeBorders
    property BorderPen: TPen read FBorderPen write SetBorderPen;
    // If EdgeBorders specified (any) and BordersTrColor is different from clNone there will be painted
    // borders for NON DEFINED edges with the BordersTrColor color. That makes sense if BorderStyle is bsSingle and
    // you would like to make all but one or few edges transparent. Alternatively you can set BorderStyle to  bsNone.
    //
    // See Also:
    //   EdgeBorders
    //   BorderPen
    property BordersTrColor: TColor read FBordersTrColor write SetBordersTrColor default clNone;
    // Some controls in the Coolcontrols package 
    // may have captions just like forms (they even 
    // can be dragged within the parent container). 
    // Appearance of the caption controlled by ocNoCaption flag 
    // (Options property)  Caption can be wide or small (ocSmallCaption flag).
    // 
    // Use CaptionColor to set Color of the control's Caption (when 
    // it is visible). clInctiveCaption is the default value.
    property CaptionColor: TColor read FCaptionColor write SetCaptionColor default clInactiveCaption;
    // Some controls in the Coolcontrols package may 
    // have captions just like forms (they even can be
    // dragged within the parent container). Appearance 
    // of the caption controlled by ocNoCaption flag (Options 
    // property)  Caption can be wide or small (ocSmallCaption flag).
    // 
    // Use CaptionTextColor to set the \color of the control's Caption 
    // text (when caption is visible). clInctiveCaptionText is the 
    // default value. The caption text itself is being set by Caption 
    // property.
    property CaptionTextColor: TColor read FCaptionTextColor write SetCaptionTextColor default clInactiveCaptionText;
    // Some controls in the CoolControls package may have 
    // captions just like forms (they even can be dragged 
    // within the parent container). Appearance of the caption 
    // controlled by ocNoCaption flag (Options property)  
    // Caption can be wide or small (ocSmallCaption flag).
    // 
    // Use CaptionWallpaper to specify the bitmap image to be 
    // painted as wallpaper for the caption (when caption is visible).  
    // 
    // There's another possible solution, instead of assigning 
    // CaptionWallpaper property you can use CoolImages and idCaptionWallpaper 
    // properties. This way you save system resources by using the same image for
    // many controls.
    // 
    // See Also:
    //   Options
    //   idCaptionWallpaper
    //   CoolImages
    property CaptionWallpaper: TBitmap read GetCaptionWallpaper write SetCaptionWallpaper;
    // Use CoolImages property to specify  TCoolImages component will be used 
    // to load images for wallpapers from. TcoolImages acts much like 
    // TImageList that is behaves as placeholder for images. It can contain 
    // images only but images of different sizes and color modes can be stored 
    // together in the same object.
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // It's possible to draw the edges (borders) for control. 
    // Based on EdgeBorders values you can control what borders 
    // will be drawn and the BorderPen property points to the 
    // pen object used to draw the borders around control. And  
    // the EdgeBorders property used to add or remove borders.
    property EdgeBorders: TEdgeBorders read FEdgeBorders write SetEdgeBorders default [];
    // Some controls in the CoolControls 
    // package may have captions just like
    // forms (they even can be dragged within 
    // the parent container). Appearance of the 
    // caption controlled by ocNoCaption flag 
    // (Options property)  Caption can be wide 
    // or small (ocSmallCaption flag).
    // 
    // Use CaptionWallpaper to specify the bitmap image 
    // to be painted as wallpaper for the caption 
    // (when caption is visible).  
    // 
    // There's another possible solution, instead of 
    // assigning CaptionWallpaper property you can 
    // use CoolImages and idCaptionWallpaper properties. This 
    // way you save system resources by using the 
    // same image for many controls.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   CaptionWallpaper
    property idCaptionWallpaper: Integer read FidCaptionWallpaper write SetidCaptionWallpaper default -1;
    // There's an alternative for direct assigning of 
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties 
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper 
    // indicates the index of the image from CoolImages to be used. 
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    // Options property controls variety of various controls parameters, the combination of included and excluded flags  determines appearance and behavior of the control. The following items that being used separately or in combination define control's look, note that some flags can not be used together and the others can or even must, note also that not all flags can be supported by the particular control or component.
    // These flags can be used with the following meaning:
    // <P>
    // * <I>ocPaintWallpaper.</I> Whether you want to paint the wallpaper for control. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocStretchWallpaper.</I> Whether you like to stretch the image to fit all the control surface. If false image will be repeatedly painted to fill the control (tiled).
    // * <I>ocPaintSelWallpaper.</I> Whether you want to paint the wallpaper for selected items. SelWallpaper or combination of  CoolImages and idSelWallpaper properties must be assigned properly.
    // * <I>ocPaintCaptionWallpaper.</I> Whether you want to paint the wallpaper for control's caption (if the latest is visible). CaptionWallpaper or combination of  CoolImages and idCaptionWallpaper properties must be assigned properly.
    // * <I>ocPaintGradiently.</I> Whether you  want to paint the gradient background. Respective color properties define the background range colors.
    // * <I>ocInvertWallpaperAsSelect.</I> Whether you want to use the same wallpaper you use for control to highlight selected items. When presents selected items will be drawn using inverted Wallpaper image, Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocBevelOnlyIfSel.</I> Whether you like to paint bevel around all the control items or only around those selected. 
    // * <I>ocNoHighlightImage.</I> If the items have attached images determines whether those for selected items should or should not be highlighted among with the item.
    // * <I>ocNoImageAttached.</I> Whether control presumes that its items some with attached images If not there will not be extra space between border and items
    // * <I>ocUseImageList.</I> Whether images should be taken from the linked Image List component or directly from the Glyph property. 
    // * <I>oc3dMDIForm.</I> Whether MDI parent form has more 3D look.
    // * <I>ocWallpaperForMDIChildren.</I> Whether attached wallpaper should be painted for all MDI child windows. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocNoCaption.</I> Whether control has caption area. Some controls will not have caption even if this property set to True.
    // * <I>ocSmallCaption.</I> What kind of caption should be used for window (if possible) standard or small caption (like for tool windows).
    // * <I>ocNoMDIChildrensCaptions.</I> Whether MDI child windows should  be drawn with the captions.
    // * <I>ocDragUsingClientArea.</I> Is it possible to drag the form using its client area.
    // * <I>ocNoDragUsingCaption.</I> Is it possible to drag the form using its caption area.
    // * <I>ocRoundedForm.</I> Whether the form should have oval shape.
    // * <I>ocFlatBorder.</I> Whether control should be painted with the modern flat look.
    // * <I>ocPaintTransparently.</I> Whether the control should have its own background or use that of the parent container.
    property Options: TCoolOptions read FOptions write SetOptions default [ocNoCaption];
    // Sets the alignment used when displaying text.
    // 
    // <TABLE>
    // Value                    Meaning
    // ----------------         ---------------------------------------
    // taLeftJustify            Text will be left aligned (default)
    // taRightJustify           Text will be right aligned 
    // taCenter	                Text will be center aligned 
    // </TABLE>
    property TextAlign: TAlignment read FTextAlign write SetTextAlign default taLeftJustify;
    // Use TransparencyLevel to specify the 
    // parent control whose part will be used 
    // to draw the background of the component. 
    // For example if control placed on the panel 
    // that is placed on the form, setting TransparencyLevel 
    // to 0 will force part of the panel to be used for 
    // painting of the transparent background, setting 
    // TransparencyLevel to 1 will force the part of the 
    // form to be selected on the controls device context 
    // when paint transparently.
    property TransparencyLevel: Byte read FTransparencyLevel write SetTransparencyLevel default 0;
    // Use Wallpaper to specify the bitmap image 
    // that will be painted as background wallpaper 
    // for a control. In most cases CoolControls package 
    // requires ocPaintWallpaper flag included into 
    // Options property set in order to actually enable 
    // wallpaper painting. Mind you that there's an 
    // alternative way to attach the image to be painted 
    // on control's background - use CoolImages and idWallpaper 
    // properties for that. This technique allows to save system 
    // resources by sharing the same image between many controls.
    // 
    // See Also:
    //   Options
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
    property Align;
    property Alignment;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Anchors;
    property BiDiMode;
    {$ENDIF}
    property BorderStyle;
    // Use Caption to associate the control with a text string that identifies the control. 
    // For most controls, the Caption is the window title and 
    // it appears as a label for the control.
    property Caption read GetCaption write SetCaption;
    property Color;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Constraints;
    {$ENDIF}
    property Ctl3D;
    property DragCursor;
    {$IFDEF DELPHI4_OR_ABOVE}
    property DragKind;
    {$ENDIF}
    property DragMode;
    property Enabled;
    property Font;
    property HideSelection;
    {$IFDEF DELPHI4_OR_ABOVE}
    property ImeMode;
    property ImeName;
    {$ENDIF}
    property Lines;
    property MaxLength;
    property OEMConvert;
    {$IFDEF DELPHI4_OR_ABOVE}
    property ParentBiDiMode;
    {$ENDIF}
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ReadOnly;
    property ScrollBars;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Visible;
    property WantReturns;
    property WantTabs;
    property WordWrap;
    property OnChange;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnEndDock;
    {$ENDIF}
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnStartDock;
    {$ENDIF}
    property OnStartDrag;
    // OnMouseEnter event occurs immediately after mouse cursor enters the control.
    property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
    // OnMouseLeave event occurs immediately after mouse cursor leaves the control.
    property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  end;

  // TCoolLabel is highly advanced label component. Adds many features: bevels, 3D text,
  // wallpapers and more.
  TCoolLabel = class(TCustomLabel)
  private
    FShadowColor: TColor;
    FShadowSize: Byte;
    FShadowPos: TShadowPosition;
    FSimpleView: Boolean;
    FStretched: Boolean;
    FWallpaper: TBitmap;
    FBevelInner,
    FBevelOuter: TPanelBevel;
    FBevelsOffset: Integer;
    FGlyph: Pointer;
    FAboutBox: TCCAboutBox;

    FCoolImages: TCoolImages;
    FidWallpaper: Integer;
    FCoolImagesChangeLink: TCoolChangeLink;

    FEdgeBorders: TEdgeBorders;
    FBorderPen: TPen;

    procedure BorderPenChange(Sender: TObject);

    procedure SetEdgeBorders(Value: TEdgeBorders);
    procedure SetBorderPen(Value: TPen);
    procedure SetStretched(Value: Boolean);

    procedure SetShadowColor(Value: TColor);
    procedure SetShadowSize(Value: Byte);
    procedure SetShadowPos(Value: TShadowPosition);
    procedure SetSimpleView(Value: Boolean);
    procedure SetWallpaper(Value: TBitmap);
    function GetWallpaper: TBitmap;
    procedure SetBevelInner(Value: TPanelBevel);
    procedure SetBevelOuter(Value: TPanelBevel);
    procedure SetBevelsOffset(Value: Integer);
    procedure GlyphChanged(Sender: TObject);
    function GetGlyph: TBitmap;
    procedure SetGlyph(Value: TBitmap);
    function GetNumGlyphs: TNumGlyphs;
    procedure SetNumGlyphs(Value: TNumGlyphs);
    procedure WallpaperChanged(Sender: TObject);

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    function CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    procedure CoolImagesChange(Sender: TObject);

    procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
    procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
  protected
    procedure AdjustBounds; {$IFNDEF BCB} {$IFDEF DELPHI4_OR_ABOVE} override {$ELSE} dynamic {$ENDIF}; {$ELSE} {$IFNDEF VER90} override {$ELSE} dynamic {$ENDIF}; {$ENDIF}
    {$IFDEF BCB}
    procedure DoDrawText(var Recty: TRect; Flags: {$IFNDEF VER125}{$IFDEF DELPHI5_OR_ABOVE}LongInt{$ELSE}Word{$ENDIF}{$ELSE}Longint{$ENDIF}); {$IFNDEF VER90} override; {$ENDIF}
    {$ELSE}
    procedure DoDrawText(var Recty: TRect; Flags: Longint); {$IFDEF DELPHI4_OR_ABOVE} override; {$ENDIF}
    {$ENDIF}
    procedure Paint; override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure Loaded; override;
    procedure SetAutoSize(Value: Boolean); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published   
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    // It's possible to draw the edges (borders) for control. Based on EdgeBorders values you can control what borders will be drawn and the BorderPen property points to the pen object used to draw the borders around control.
    // 
    // See Also:
    //   EdgeBorders
    property BorderPen: TPen read FBorderPen write SetBorderPen;
    // Use CoolImages property to specify  TCoolImages component will be used
    // to load images for wallpapers from. TcoolImages acts much like 
    // TImageList that is behaves as placeholder for images. It can contain 
    // images only but images of different sizes and color modes can be stored 
    // together in the same object.
    //
    // See Also:
    //   idWallpaper
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // It's possible to draw the edges (borders) for control. 
    // Based on EdgeBorders values you can control what borders 
    // will be drawn and the BorderPen property points to the 
    // pen object used to draw the borders around control. And  
    // the EdgeBorders property used to add or remove borders.
    property EdgeBorders: TEdgeBorders read FEdgeBorders write SetEdgeBorders default [];
    // There's an alternative for direct assigning of
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper 
    // indicates the index of the image from CoolImages to be used. 
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    //
    // See Also:
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    // If the control or its items can be painted with the 
    // bitmap image (glyph) use this property to specify the bitmap 
    // image to be painted. Painting glyphs may give 
    // your controls more attractive look yet highlight the control's purpose.
    property Glyph: TBitmap read GetGlyph write SetGlyph;
    // NumGlyphs property indicates the number of images 
    // that are in the graphic specified in the Glyph
    // property for use on a control.
    // If you have multiple images in a bitmap, you must 
    // specify the number of images that are in 
    // the bitmap with the NumGlyphs property. Valid NumGlyphs 
    // values are 1 to 4. The default value is 1.
    // 
    // See Also:
    //   Glyph
    property NumGlyphs: TNumGlyphs read GetNumGlyphs write SetNumGlyphs default 1;
    // In the CoolControls package many controls that 
    // have captions or string items allow to paint 
    // these with the 3D effect. When you use this feature, 
    // use ShadowColor to set the color of the shadow dropped. 
    // The effect being achieved by painting the text 
    // twice - once with the main color and then with the 
    // ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   SimpleView
    property ShadowColor: TColor read FShadowColor write SetShadowColor default clBtnHighlight;
    // In the CoolControls package many controls that have captions 
    // or string items allow to paint these with the 3D effect. 
    // When you use this feature, use ShadowSiize to indicate the
    // offset  of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and then 
    // with the ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowPos
    //   ShadowColor
    //   SimpleView
    property ShadowSize: Byte read FShadowSize write SetShadowSize default 1;
    // In the CoolControls package many controls that have captions or 
    // string items allow to paint these with the 3D effect. When
    // you use this feature, use ShadowPos to indicate the position 
    // (relatively to the main text) of the shadow dropped. The effect 
    // being achieved by painting the text twice - once with the main 
    // color and then with the ShadowColor (allowing ShadowSize offset).
    // 
    // <TABLE>
    // Value              Meaning
    // -------            -------------------------
    // spLeftTop          Shadow is in the Left Top direction.
    // spLeftBottom       Shadow is in the Left Bottom direction.
    // spRightBottom      Shadow is in the Right Bottom direction.
    // spRightTop         Shadow is in the Right Top direction.
    // </TABLE>
    // 
    // See Also:
    //   ShadowSize
    //   ShadowColor
    //   SimpleView
    property ShadowPos: TShadowPosition read FShadowPos write SetShadowPos default spLeftTop;
    // In the CoolControls package many controls that have 
    // captions or string items allow to paint these with 
    // the 3D effect. When you use this feature, use ShadowPos 
    // to indicate the position (relatively to the main text) 
    // of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and
    // then with the ShadowColor (allowing ShadowSize offset).
    // Use SimpleView to indicate whether you want to use the
    // described feature  or you do not.
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   ShadowColor
    property SimpleView: Boolean read FSimpleView write SetSimpleView default False;
    // Determines whether the wallpaper should be stretched to fit into the control's dimensions.
    // Otherwise image will be tiled to cover the control's surface.
    property Stretched: Boolean read FStretched write SetStretched default False;
    // Use Wallpaper to specify the bitmap image
    // that will be painted as background wallpaper
    // for a control. In most cases CoolControls package
    // requires ocPaintWallpaper flag included into
    // Options property set in order to actually enable
    // wallpaper painting. Mind you that there's an
    // alternative way to attach the image to be painted 
    // on control's background - use CoolImages and idWallpaper 
    // properties for that. This technique allows to save system
    // resources by sharing the same image between many controls.
    //
    // See Also:
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
    // Use BevelInner to specify whether the inner bevel has a raised, lowered, or flat look. 
    // 
    // The inner bevel appears immediately inside the outer bevel. If there is no outer bevel (BevelOuter is bvNone), the inner bevel appears immediately inside the border.
    // If you like you can specify the bevel to be
    // painted for each cell. There re two bevels define the
    // ook of the individual cell - OuterCellsBevel and InnerCellsBevel.
    // 
    // These are the possible values of bevels:
    // 
    // <TABLE>
    // Value		Meaning
    // -------  	--------
    // pbNone		No bevel, appears flat.
    // pbLowered	Appears recessed.
    // pbRaised	Appears raised.
    // </TABLE>
    // 
    // Combination of both bevels define the look of the control.
    property BevelInner: TPanelBevel read FBevelInner write SetBevelInner default bvNone;
    // Use BevelOuter to specify whether the outer bevel has a raised, lowered, or flat look. The outer bevel appears immediately inside the border and outside the inner bevel.
    // If you like you can specify the bevel to be
    // painted for each cell. There re two bevels define the
    // ook of the individual cell - OuterCellsBevel and InnerCellsBevel.
    // 
    // These are the possible values of bevels:
    // 
    // <TABLE>
    // Value		Meaning
    // -------  	--------
    // pbNone		No bevel, appears flat.
    // pbLowered	Appears recessed.
    // pbRaised	Appears raised.
    // </TABLE>
    // 
    // Combination of both bevels define the look of the control.
    property BevelOuter: TPanelBevel read FBevelOuter write SetBevelOuter default bvNone;
    // Use BevelsOffset to specify the space (in pixels) to beused between 
    // text edges and control's bevels.
    // 
    // See Also:
    //   BevelOuter
    //   BevelInner
    property BevelsOffset: Integer read FBevelsOffset write SetBevelsOffset default 0;
    property Align;
    property Alignment;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Anchors;
    property BiDiMode;
    property Constraints;
    property DragKind;
    property ParentBiDiMode;
    {$ENDIF}
    property AutoSize;
    property Caption;
    property Color;
    property DragCursor;
    property DragMode;
    property Enabled;
    property FocusControl;
    property Font;
    property ParentColor;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowAccelChar;
    property ShowHint;
    // Use Transparent property to specify that the
    // control will be drawn transparently. Similar to the
    // meaning of the ocPaintTransparently flag in the Options
    // property of the most controls.
    property Transparent;
    {$IFNDEF VER90}
    // The Layout property defines the layout of a bitmap within 
    // a control. These are the possible values:
    // 
    // <TABLE>
    // Value            Meaning
    // ------------     --------------
    // blGlyphLeft      The image appears on the left side of the text or caption.
    // blGlyphRight     The image appears on the right side of the text or caption.
    // blGlyphTop       The image appears at the top of the text or caption.
    // blGlyphBottom    The image appears at the bottom of the text or caption.
    // </TABLE>
    property Layout;
    {$ENDIF}
    property Visible;
    property WordWrap;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnEndDock;
    property OnStartDock;
    {$ENDIF}
    property OnEndDrag;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;  
    property OnStartDrag;
  end;

  // Determines the type of the check-radio box control.
  //
  // <TABLE>
  // Value           Meaning
  // ---------       ----------
  // crCheckBox      Check box control
  // crRadioBox      Radio button control
  // </TABLE>
  TCheckRadioType = (crCheckBox, crRadioBox);

  // Starenko begin
  // Determines the source of the images in a case of OwnerDraw.
  //
  // <TABLE>
  // Value           Meaning
  // ---------       ----------
  // isGlyph         Images from GlyphMarked/Normal property
  // isImageList     Images from Images property
  // </TABLE>
  TImageSource = (isGlyph, isImageList{, isCoolImages});
  // Starenko end

  TCoolCheckRadioBox = class;

  {$IFDEF DELPHI4_OR_ABOVE}

  {TCoolCheckRadioBoxActionLink}
  TCoolCheckRadioBoxActionLink = class(TControlActionLink)
  protected
    FClient: TCoolCheckRadioBox;
    procedure AssignClient(AClient: TObject); override;
    function IsCheckedLinked: Boolean; override;
    procedure SetChecked(Value: Boolean); override;
  end;

  TCoolCheckRadioBoxActionLinkClass = class of TCoolCheckRadioBoxActionLink;
  {$ENDIF}

  // TColCheckRadioBox is an advanced control that provides functionality of  
  // both TCheckBox and TRadioButton among with some extra cool visual features. 
  // Such as wallpaper, transparency, bevels, 3D view and more effects.
  TCoolCheckRadioBox = class(TCustomControl)
  private
    FTransparent: Boolean;
    FWallpaper: TBitmap;
    FAlignment: TLeftRight;
    FChecked: Boolean;
    FAllowGrayed: Boolean;
    FDown: Boolean;
    FCheckRadioType: TCheckRadioType;
    FGroupIndex: Integer;
    FFlat: Boolean;
    FOwnerDraw: Boolean;
    FStretched: Boolean;

    FShadowColor: TColor;
    FShadowSize: Byte;
    FShadowPos: TShadowPosition;
    FSimpleView: Boolean;
    FBevelInner,
    FBevelOuter: TPanelBevel;
    FBevelsOffset: Integer;
    FTransparencyLevel: Byte;
    FAboutBox: TCCAboutBox;

    FGlyphMarked,
    FGlyphNormal: Pointer;
    //Starenko begin
    FImages: TImageList;
    FImageChangeLink: TChangeLink;
    FImageSrc: TImageSource;
    //Starenko end

    FCoolImages: TCoolImages;
    FidWallpaper: Integer;
    FCoolImagesChangeLink: TCoolChangeLink;

    FOnMouseEnter,
    FOnMouseLeave: TNotifyEvent;

    function GetWallpaper: TBitmap;
    procedure SetWallpaper(Value: TBitmap);
    procedure SetTransparent(Value: Boolean);
    procedure SetState(Value: TCheckBoxState);
    procedure SetAlignment(Value: TLeftRight);
    procedure SetChecked(Value: Boolean);
    procedure SetCheckRadioType(Value: TCheckRadioType);
    procedure SetFlat(Value: Boolean);

    procedure SetShadowColor(Value: TColor);
    procedure SetShadowSize(Value: Byte);
    procedure SetShadowPos(Value: TShadowPosition);
    procedure SetSimpleView(Value: Boolean);
    procedure SetBevelInner(Value: TPanelBevel);
    procedure SetBevelOuter(Value: TPanelBevel);
    procedure SetBevelsOffset(Value: Integer);
    procedure SetOwnerDraw(Value: Boolean);
    procedure SetTransparencyLevel(Value: Byte);
    procedure SetStretched(Value: Boolean);

    procedure GlyphMarkedChanged(Sender: TObject);
    procedure GlyphNormalChanged(Sender: TObject);
    function GetGlyphMarked: TBitmap;
    procedure SetGlyphMarked(Value: TBitmap);
    function GetGlyphNormal: TBitmap;
    procedure SetGlyphNormal(Value: TBitmap);
    function GetNumGlyphsMarked: TNumGlyphs;
    procedure SetNumGlyphsMarked(Value: TNumGlyphs);
    function GetNumGlyphsNormal: TNumGlyphs;
    procedure SetNumGlyphsNormal(Value: TNumGlyphs);
    procedure WallpaperChanged(Sender: TObject);
    procedure ImageListChange(Sender: TObject);  // by Starenko

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    function CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    procedure CoolImagesChange(Sender: TObject);
    function IsCheckedStored: Boolean;
    procedure SetImages(Value: TImageList);      // by Starenko
    procedure SetImageSrc(Value: TImageSource);       // by Starenko

    procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;
    procedure CMFocusChanged(var Message: TCMFocusChanged); message CM_FOCUSCHANGED;
    procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
    procedure CMParentColorChanged(var Message: TMessage); message CM_PARENTCOLORCHANGED;
    procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;
    procedure CMFontChange(var Message: TMessage); message CM_FONTCHANGE;
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
    procedure WMMove(var Message: TWMMove); message WM_MOVE;
    procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
    procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
  protected
    FState: TCheckBoxState;
    function Toggle: Boolean; virtual;
    function GetImageHeight: Integer;
    property  ImageHeight: Integer read GetImageHeight;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure Paint; override;
    {$IFDEF DELPHI4_OR_ABOVE}
    procedure AdjustSize; override;
    {$ENDIF}
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure KeyDown(var Key: Word; Shift: TShiftSTate); override;
    procedure KeyUp(var Key: Word; Shift: TShiftSTate); override;
    procedure DoEnter; override;
    procedure DoExit; override;
    procedure InvalidateEx; virtual;
    procedure Click; override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    {$IFDEF DELPHI4_OR_ABOVE}
    function GetActionLinkClass: TControlActionLinkClass; override;
    procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
    {$ENDIF}
    procedure AssignTo(Dest: TPersistent); override;
    procedure Loaded; override;
    procedure ReadState(Reader: TReader); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure SetFocus; override;
  published
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    property Alignment: TLeftRight read FAlignment write SetAlignment default taRightJustify;
    // When ChdeckRadioType set to crCheckBox setting this property
    // to True allows use third state of check box (grayed).
    //
    // See Also:
    //   ChdeckRadioType
    property AllowGrayed: Boolean read FAllowGrayed write FAllowGrayed default False;
    // Use BevelInner to specify whether the inner bevel has a raised, lowered, or flat look.
    //
    // The inner bevel appears immediately inside the outer bevel. If there is no outer bevel (BevelOuter is bvNone), the inner bevel appears immediately inside the border.
    property BevelInner: TPanelBevel read FBevelInner write SetBevelInner default bvNone;
    // Use BevelOuter to specify whether the outer bevel has a raised, lowered, or flat look. The outer bevel appears immediately inside the border and outside the inner bevel.
    property BevelOuter: TPanelBevel read FBevelOuter write SetBevelOuter default bvNone;
    // Use BevelsOffset to specify the space (in pixels) to beused between
    // text edges and control's bevels.
    //
    // See Also:
    //   BevelOuter
    //   BevelInner
    property BevelsOffset: Integer read FBevelsOffset write SetBevelsOffset default 0;
    // Use Checked property to specify and retrieve current
    // state of the control.
    // This property can be used with the State property and
    // is somewhat faster.
    property Checked: Boolean read FChecked write SetChecked stored IsCheckedStored default False;
    // Use CheckRadioType property to chose the type of the check-radio box control.
    //
    // <TABLE>
    // Value           Meaning
    // ---------       ----------
    // crCheckBox      Check box control
    // crRadioBox      Radio button control
    // </TABLE>
    property CheckRadioType: TCheckRadioType read FCheckRadioType write SetCheckRadioType default crCheckBox;
    // Use CoolImages property to specify  TCoolImages component will be used
    // to load images for wallpapers from. TcoolImages acts much like
    // TImageList that is behaves as placeholder for images. It can contain
    // images only but images of different sizes and color modes can be stored
    // together in the same object.
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // There's an alternative for direct assigning of
    // the Wallpaper property for cases when you want
    // to paint the image background for the
    // control - use CoolImages and idWallpaper properties
    // for that. This technique allows to save system resources
    // by sharing the same image between many controls. IdWallpaper
    // indicates the index of the image from CoolImages to be used.
    // For controls that have Options property it's necessary to
    // include ocPaintWallpaper flag (Options property) to enable
    // the wallpaper painting.
    //
    // See Also:
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    property GroupIndex: Integer read FGroupIndex write FGroupIndex default 0;
    // If the control or its items can be painted with the
    // bitmap image (glyph) use this property to specify the bitmap
    // image to be painted. Painting glyphs may give
    // your controls more attractive look yet highlight the control's purpose.
    property GlyphMarked: TBitmap read GetGlyphMarked write SetGlyphMarked;
    // If the control or its items can be painted with the
    // bitmap image (glyph) use this property to specify the bitmap
    // image to be painted. Painting glyphs may give
    // your controls more attractive look yet highlight the control's purpose.
    property GlyphNormal: TBitmap read GetGlyphNormal write SetGlyphNormal;
    // NumGlyphsMarked property indicates the number of images
    // that are in the graphic specified in the GlyphMarked
    // property for use on a control.
    // If you have multiple images in a bitmap, you must
    // specify the number of images that are in
    // the bitmap with the NumGlyphsMarked property. Valid NumGlyphsMarked
    // values are 1 to 4. The default value is 1.
    //
    // See Also:
    //   GlyphMarked
    property NumGlyphsMarked: TNumGlyphs read GetNumGlyphsMarked write SetNumGlyphsMarked default 1;
    // NumGlyphsNormal property indicates the number of images
    // that are in the graphic specified in the GlyphNormal
    // property for use on a control.
    // If you have multiple images in a bitmap, you must
    // specify the number of images that are in
    // the bitmap with the NumGlyphsNormal property. Valid NumGlyphsNormal
    // values are 1 to 4. The default value is 1.
    //
    // See Also:
    //   GlyphNormal
    property NumGlyphsNormal: TNumGlyphs read GetNumGlyphsNormal write SetNumGlyphsNormal default 1;

    // Starenko begin
    // Use Images to provide a customized list of images
    // that can be displayed with the items.
    property Images: TImageList read FImages write SetImages;
    property ImageSource: TImageSource read FImageSrc write SetImageSrc default isGlyph;
    // Starenko end

    // Use Flat property to indicate when control should be painted in a modern
    // flat way.
    property Flat: Boolean read FFlat write SetFlat default False;
    // Use OwnerDraw to indicate if you would like the system to paint
    // the control in the default manner or would like take the control over the painting yourself.
    // You need to set this property to True if you want to assign and use
    // custom images for GlyphNormal and GlyphMarked properties.
    // 
    // See Also:
    //   GlyphNormal
    //   GlyphMarked
    property OwnerDraw: boolean read FOwnerDraw write SetOwnerDraw default False;
    // State property defines the current state of the control,
    // it can be /checked or unchecked. 
    // This property can be used instead of the Checked property.
    property State: TCheckBoxState read FState write SetState default cbUnchecked;
    // In the CoolControls package many controls that 
    // have captions or string items allow to paint 
    // these with the 3D effect. When you use this feature, 
    // use ShadowColor to set the color of the shadow dropped. 
    // The effect being achieved by painting the text 
    // twice - once with the main color and then with the 
    // ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   SimpleView
    property ShadowColor: TColor read FShadowColor write SetShadowColor default clBtnHighlight;
    // In the CoolControls package many controls that have captions
    // or string items allow to paint these with the 3D effect. 
    // When you use this feature, use ShadowSiize to indicate the 
    // offset  of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and then 
    // with the ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowPos
    //   ShadowColor
    //   SimpleView
    property ShadowSize: Byte read FShadowSize write SetShadowSize default 1;
    // In the CoolControls package many controls that have captions or 
    // string items allow to paint these with the 3D effect. When 
    // you use this feature, use ShadowPos to indicate the position 
    // (relatively to the main text) of the shadow dropped. The effect 
    // being achieved by painting the text twice - once with the main
    // color and then with the ShadowColor (allowing ShadowSize offset).
    // 
    // <TABLE>
    // Value              Meaning
    // -------            -------------------------
    // spLeftTop          Shadow is in the Left Top direction.
    // spLeftBottom       Shadow is in the Left Bottom direction.
    // spRightBottom      Shadow is in the Right Bottom direction.
    // spRightTop         Shadow is in the Right Top direction.
    // </TABLE>
    // 
    // See Also:
    //   ShadowSize
    //   ShadowColor
    //   SimpleView
    property ShadowPos: TShadowPosition read FShadowPos write SetShadowPos default spLeftTop;
    // In the CoolControls package many controls that have 
    // captions or string items allow to paint these with
    // the 3D effect. When you use this feature, use ShadowPos
    // to indicate the position (relatively to the main text)
    // of the shadow dropped. The effect being achieved by
    // painting the text twice - once with the main color and
    // then with the ShadowColor (allowing ShadowSize offset).
    // Use SimpleView to indicate whether you want to use the
    // described feature  or you do not.
    //
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   ShadowColor
    property SimpleView: Boolean read FSimpleView write SetSimpleView default False;
    // Determines whether the wallpaper should be stretched to fit into the control's dimensions.
    // Otherwise image will be tiled to cover the control's surface.
    property Stretched: Boolean read FStretched write SetStretched default False;
    // Use Transparent property to specify that the
    // control will be drawn transparently. Similar to the
    // meaning of the ocPaintTransparently flag in the Options
    // property of the most controls.
    property Transparent: Boolean read FTransparent write SetTransparent default False;
    // Use TransparencyLevel to specify the 
    // parent control whose part will be used 
    // to draw the background of the component. 
    // For example if control placed on the panel 
    // that is placed on the form, setting TransparencyLevel 
    // to 0 will force part of the panel to be used for 
    // painting of the transparent background, setting 
    // TransparencyLevel to 1 will force the part of the 
    // form to be selected on the controls device context 
    // when paint transparently.
    property TransparencyLevel: Byte read FTransparencyLevel write SetTransparencyLevel default 0;
    // Use Wallpaper to specify the bitmap image 
    // that will be painted as background wallpaper 
    // for a control. In most cases CoolControls package 
    // requires ocPaintWallpaper flag included into 
    // Options property set in order to actually enable 
    // wallpaper painting. Mind you that there's an 
    // alternative way to attach the image to be painted 
    // on control's background - use CoolImages and idWallpaper 
    // properties for that. This technique allows to save system 
    // resources by sharing the same image between many controls.
    // 
    // See Also:
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Action;
    property Anchors;
    property BiDiMode;
    {$ENDIF}
    property Caption;
    property Color;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Constraints;
    {$ENDIF}
    property Ctl3D;
    {$IFDEF DELPHI4_OR_ABOVE}
    property UseDockManager default True;
    property DockSite;
    {$ENDIF}
    property DragCursor;
    {$IFDEF DELPHI4_OR_ABOVE}
    property DragKind;
    {$ENDIF}
    property DragMode;
    property Enabled;
    property Font;
    {$IFDEF DELPHI4_OR_ABOVE}
    property ParentBiDiMode;
    {$ENDIF}
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Visible;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnCanResize;
    {$ENDIF}
    property OnClick;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnConstrainedResize;
    property OnDockDrop;
    property OnDockOver;
    {$ENDIF}
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnEndDock;
    {$ENDIF}
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnGetSiteInfo;
    {$ENDIF}
    property OnKeyDown;
    property OnKeyUp;
    property OnKeyPress;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnResize;
    property OnStartDock;
    property OnUnDock;
    {$ENDIF}
    property OnStartDrag;
    // OnMouseEnter event occurs immediately after mouse cursor enters the control.
    property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
    // OnMouseLeave event occurs immediately after mouse cursor leaves the control.
    property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  end;

  // TCoolGroupBox is an advanced group box component it supports all the
  // features of the standard TGroupBox component and can be use just like 
  // it but also comes with some addiutional properties and features. 
  // It can be transparent, can have wallpaper and can be drawn with the 3D caption.
  TCoolGroupBox = class(TCustomGroupBox)
  private
    FTransparent: Boolean;
    FWallpaper: TBitmap;
    FShadowColor: TColor;
    FShadowSize: Byte;
    FShadowPos: TShadowPosition;
    FSimpleView: Boolean;
    FTransparencyLevel: Byte;
    FAboutBox: TCCAboutBox;
    FStretched: Boolean;

    FCoolImages: TCoolImages;
    FidWallpaper: Integer;
    FCoolImagesChangeLink: TCoolChangeLink;

    procedure SetTransparent(Value: Boolean);
    procedure SetWallpaper(Value: TBitmap);
    function GetWallpaper: TBitmap;
    procedure SetShadowColor(Value: TColor);
    procedure SetShadowSize(Value: Byte);
    procedure SetShadowPos(Value: TShadowPosition);
    procedure SetSimpleView(Value: Boolean);
    procedure SetTransparencyLevel(Value: Byte);
    procedure WallpaperChanged(Sender: TObject);
    procedure SetStretched(Value: Boolean);

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    function CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    procedure CoolImagesChange(Sender: TObject);

    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
    procedure CMParentColorChanged(var Message: TMessage); message CM_PARENTCOLORCHANGED;
    procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
    procedure WMMove(var Message: TWMMove); message WM_MOVE;
  protected
    procedure Paint; override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published   
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    // Use CoolImages property to specify  TCoolImages component will be used 
    // to load images for wallpapers from. TcoolImages acts much like 
    // TImageList that is behaves as placeholder for images. It can contain
    // images only but images of different sizes and color modes can be stored 
    // together in the same object.
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // There's an alternative for direct assigning of 
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties 
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper 
    // indicates the index of the image from CoolImages to be used. 
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    // 
    // See Also:
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    // Use Transparent property to specify that the
    // control will be drawn transparently. Similar to the
    // meaning of the ocPaintTransparently flag in the Options
    // property of the most controls.
    property Transparent: Boolean read FTransparent write SetTransparent default False;
    // Use Wallpaper to specify the bitmap image
    // that will be painted as background wallpaper 
    // for a control. In most cases CoolControls package 
    // requires ocPaintWallpaper flag included into 
    // Options property set in order to actually enable 
    // wallpaper painting. Mind you that there's an 
    // alternative way to attach the image to be painted
    // on control's background - use CoolImages and idWallpaper 
    // properties for that. This technique allows to save system 
    // resources by sharing the same image between many controls.
    // 
    // See Also:
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
    // In the CoolControls package many controls that
    // have captions or string items allow to paint 
    // these with the 3D effect. When you use this feature, 
    // use ShadowColor to set the color of the shadow dropped. 
    // The effect being achieved by painting the text 
    // twice - once with the main color and then with the 
    // ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   SimpleView
    property ShadowColor: TColor read FShadowColor write SetShadowColor default clBtnHighlight;
    // In the CoolControls package many controls that have captions 
    // or string items allow to paint these with the 3D effect. 
    // When you use this feature, use ShadowSiize to indicate the 
    // offset  of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and then 
    // with the ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowPos
    //   ShadowColor
    //   SimpleView
    property ShadowSize: Byte read FShadowSize write SetShadowSize default 1;
    // In the CoolControls package many controls that have captions or 
    // string items allow to paint these with the 3D effect. When 
    // you use this feature, use ShadowPos to indicate the position
    // (relatively to the main text) of the shadow dropped. The effect 
    // being achieved by painting the text twice - once with the main 
    // color and then with the ShadowColor (allowing ShadowSize offset).
    // 
    // <TABLE>
    // Value              Meaning
    // -------            -------------------------
    // spLeftTop          Shadow is in the Left Top direction.
    // spLeftBottom       Shadow is in the Left Bottom direction.
    // spRightBottom      Shadow is in the Right Bottom direction.
    // spRightTop         Shadow is in the Right Top direction.
    // </TABLE>
    // 
    // See Also:
    //   ShadowSize
    //   ShadowColor
    //   SimpleView
    property ShadowPos: TShadowPosition read FShadowPos write SetShadowPos default spLeftTop;
    // In the CoolControls package many controls that have 
    // captions or string items allow to paint these with 
    // the 3D effect. When you use this feature, use ShadowPos
    // to indicate the position (relatively to the main text) 
    // of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and
    // then with the ShadowColor (allowing ShadowSize offset).
    // Use SimpleView to indicate whether you want to use the 
    // described feature  or you do not.
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   ShadowColor
    property SimpleView: Boolean read FSimpleView write SetSimpleView default False;
    // Use TransparencyLevel to specify the 
    // parent control whose part will be used
    // to draw the background of the component. 
    // For example if control placed on the panel 
    // that is placed on the form, setting TransparencyLevel 
    // to 0 will force part of the panel to be used for 
    // painting of the transparent background, setting 
    // TransparencyLevel to 1 will force the part of the 
    // form to be selected on the controls device context
    // when paint transparently.
    property TransparencyLevel: Byte read FTransparencyLevel write SetTransparencyLevel default 0;
    // Determines whether the wallpaper should be stretched to fit into the control's dimensions.
    // Otherwise image will be tiled to cover the control's surface.
    property Stretched: Boolean read FStretched write SetStretched default False;
    property Align;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Anchors;
    property BiDiMode;
    {$ENDIF}
    property Caption;
    property Color;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Constraints;
    {$ENDIF}
    property Ctl3D;
    {$IFDEF DELPHI4_OR_ABOVE}
    property DockSite;
    {$ENDIF}
    property DragCursor;
    {$IFDEF DELPHI4_OR_ABOVE}
    property DragKind;
    {$ENDIF}
    property DragMode;
    property Enabled;
    property Font;
    {$IFDEF DELPHI4_OR_ABOVE}
    property ParentBiDiMode;
    {$ENDIF}
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Visible;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnDockDrop;
    property OnDockOver;
    {$ENDIF}
    property OnDragOver;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnEndDock;
    {$ENDIF}
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnGetSiteInfo;
    {$ENDIF}    
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDrag;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnStartDock;
    property OnUnDock;
    {$ENDIF}
  end;

  // Used for scroll events.
  // <PRE>
  //   Sender - object that fires event
  //   InitialPosition - whether scrolled text should be set into initial position
  // </PRE>
  // 
  TTextScrolledEvent = procedure(Sender: TObject; var InitialPosition: Boolean) of Object;

  // Threaded timer class.
  TThreadTimer = class(TThread)
  private
    FEnabled: Boolean;
    FInterval: WORD;
    FOnTimer: TNotifyEvent;
    procedure SetEnabled(Value: Boolean);
  protected
    procedure DoTimer; virtual;
    procedure Execute; override;
  public
    constructor Create;
    property Enabled: Boolean read FEnabled write SetEnabled;
    // Interval determines how frequently the scrolling event occurs.
    // Each time the specified interval passes, the text is scrolled on one position.
    // 
    // Use Interval to specify any cardinal value as the interval between scroll events. The 
    // default value is 25 ms.
    property Interval: WORD read FInterval write FInterval;
    // Use OnTimer to write an event handler to execute an action at regular intervals.
    //
    // The Interval property of a timer determines how frequently the OnTimer event occurs. 
    // Each time the specified interval passes, the OnTimer event occurs.
    //
    // See Also:
    //   Interval 
    property OnTimer: TNotifyEvent read FOnTimer write FOnTimer;
  end;

  // TCoolScrollingText can flicker free scroll large amount of text. Text can be
  // scrolled vertically, horizontally in any direction. Control useful for about boxes,
  // long labels and so on. Text can be painted with 3D effect, control can be linked to
  // any windowed control and act like TLabel component.
  TCoolScrollingText = class(TGraphicControl)
  private
    {$IFNDEF DELPHI4_OR_ABOVE}
    FAutoSize: Boolean;
    {$ENDIF}
    FStrings: TStrings;
    FActive: Boolean;
    FInterval: Cardinal;
    FAlignment: TAlignment;
    FScrollDirection: TScrollDirection;
    FGlyph: Pointer;

    FShadowColor: TColor;
    FShadowSize: Byte;
    FShadowPos: TShadowPosition;
    FSimpleView: Boolean;
    FFocusControl: TWinControl;
    FShowAccelChar: Boolean;
    FAboutBox: TCCAboutBox;
    FStretched: Boolean;

    FWallpaper: TBitmap;
    FCoolImages: TCoolImages;
    FidWallpaper: Integer;
    FCoolImagesChangeLink: TCoolChangeLink;
    FTransparent: Boolean;

    FTimer: TThreadTimer;
    FBackBitmap: TBitmap;
    FOnTextScrolled: TTextScrolledEvent;

    procedure CoolImagesChange(Sender: TObject);
    function IsWallpaperAssigned: Boolean;
    procedure WallpaperChanged(Sender: TObject);
    function CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    procedure SetidWallpaper(Value: Integer);

    procedure SetWallpaper(Value: TBitmap);
    function GetWallpaper: TBitmap;
    procedure SetCoolImages(Value: TCoolImages);

    procedure SetStrings(Value: TStrings);
    procedure StringsChange(Sender: TObject);
    procedure SetStretched(Value: Boolean);
    procedure SetActive(Value: Boolean);
    procedure SetInterval(Value: Cardinal);
    procedure SetAlignment(Value: TAlignment);
    procedure SetScrollDirection(Value: TScrollDirection);
    procedure SetShadowColor(Value: TColor);
    procedure SetShadowSize(Value: Byte);
    procedure SetShadowPos(Value: TShadowPosition);
    procedure SetSimpleView(Value: Boolean);
    procedure SetFocusControl(Value: TWinControl);
    procedure SetShowAccelChar(Value: Boolean);
    {$IFNDEF DELPHI4_OR_ABOVE}
    procedure SetAutoSize(Value: Boolean);
    {$ENDIF}
    procedure SetTransparent(Value: Boolean);

    procedure GlyphChanged(Sender: TObject);
    function GetGlyph: TBitmap;
    procedure SetGlyph(Value: TBitmap);
    function GetNumGlyphs: TNumGlyphs;
    procedure SetNumGlyphs(Value: TNumGlyphs);

    procedure DoPaintBackground; virtual;
    procedure DoPaint(Canv: TCanvas);
    procedure DoPaintEvent;
    procedure DoTimer(Sender: TObject);
    procedure UpdateTimer;

    function BusyRect: TRect;

    procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
    procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
    procedure CMDialogChar(var Message: TCMDialogChar); message CM_DIALOGCHAR;
    procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
  protected
    // Absolute positions of the text within control.
    X, Y: Integer;
    procedure Paint; override;
    procedure Loaded; override;
    procedure SetName(const Value: TComponentName); override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    // Adjusts the text within control's bounds
    procedure AdjustBounds; dynamic;
    {$IFDEF DELPHI4_OR_ABOVE}
    procedure AdjustSize; override;
    {$ENDIF}
    {$IFDEF BCB}
    procedure DoDrawText(Canv: TCanvas; var Recty: TRect; Flags: {$IFNDEF VER125}Word{$ELSE}Longint{$ENDIF}); virtual;
    {$ELSE}
    procedure DoDrawText(Canv: TCanvas; var Recty: TRect; Flags: Longint); virtual;
    {$ENDIF}
    // Returns the strings list displayed by the control.
    function GetStrings: TStrings; virtual;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    // Sets the text position to initial position. Call this method from within OnTextScrolled event
    // to reposition the text.
    //
    // Arguments:
    //   Initial - if True text will be displayed from the left top corner of the control otherwise depending on the last position.
    procedure SetTextCoordinates(Initial: Boolean);
  published
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
    // Set Active to True to make the control scroll its contents and set
    // Active to False to stop the scrolling. To manipulate the scrolling speed modify Interval property.
    // 
    // See Also:
    //   Interval
    property Active: Boolean read FActive write SetActive default False;
    {$IFNDEF DELPHI4_OR_ABOVE}
    property AutoSize: Boolean read FAutoSize write SetAutoSize default False;
    {$ENDIF}
    // Use CoolImages property to specify  TCoolImages component will be used 
    // to load images for wallpapers from. TcoolImages acts much like
    // TImageList that is behaves as placeholder for images. It can contain 
    // images only but images of different sizes and color modes can be stored
    // together in the same object.
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // There's an alternative for direct assigning of 
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties 
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper 
    // indicates the index of the image from CoolImages to be used. 
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    property FocusControl: TWinControl read FFocusControl write SetFocusControl;
    // Interval determines how frequently the scrolling event occurs. 
    // Each time the specified interval passes, the text is scrolled on one position.
    // 
    // Use Interval to specify any cardinal value as the interval between scroll events. The 
    // default value is 25 ms.
    property Interval: Cardinal read FInterval write SetInterval default 25;
    // If the control or its items can be painted with the
    // bitmap image (glyph) use this property to specify the bitmap 
    // image to be painted. Painting glyphs may give 
    // your controls more attractive look yet highlight the control's purpose.
    property Glyph: TBitmap read GetGlyph write SetGlyph;
    // NumGlyphs property indicates the number of images 
    // that are in the graphic specified in the Glyph 
    // property for use on a control.
    // If you have multiple images in a bitmap, you must 
    // specify the number of images that are in 
    // the bitmap with the NumGlyphs property. Valid NumGlyphs 
    // values are 1 to 4. The default value is 1.
    // 
    // See Also:
    //   Glyph
    property NumGlyphs: TNumGlyphs read GetNumGlyphs write SetNumGlyphs default 1;
    // Use ScrollDirection property to set up the 
    // direction in which scrolling will occur. 
    // 
    // <TABLE>
    // Value                Meaning
    // -------------        -------------
    // sdBottomToTop        Text scrolls from bottom to top
    // sdTopToBottom        Text scrolls from top to bottom
    // sdLeftToRight        Text scrolls from left to right
    // sdRightToLeft        Text scrolls from right to left
    // </TABLE>
    property ScrollDirection: TScrollDirection read FScrollDirection write SetScrollDirection default sdRightToLeft;
    // Use Strings property to set the text that
    // will be displayed (scrolled) by the control.
    property Strings: TStrings read GetStrings write SetStrings;
    // In the CoolControls package many controls that 
    // have captions or string items allow to paint 
    // these with the 3D effect. When you use this feature, 
    // use ShadowColor to set the color of the shadow dropped. 
    // The effect being achieved by painting the text
    // twice - once with the main color and then with the 
    // ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   SimpleView
    property ShadowColor: TColor read FShadowColor write SetShadowColor default clBtnHighlight;
    // In the CoolControls package many controls that have captions 
    // or string items allow to paint these with the 3D effect. 
    // When you use this feature, use ShadowSiize to indicate the 
    // offset  of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and then 
    // with the ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowPos
    //   ShadowColor
    //   SimpleView
    property ShadowSize: Byte read FShadowSize write SetShadowSize default 1;
    // In the CoolControls package many controls that have captions or
    // string items allow to paint these with the 3D effect. When 
    // you use this feature, use ShadowPos to indicate the position 
    // (relatively to the main text) of the shadow dropped. The effect 
    // being achieved by painting the text twice - once with the main
    // color and then with the ShadowColor (allowing ShadowSize offset).
    // 
    // <TABLE>
    // Value              Meaning
    // -------            -------------------------
    // spLeftTop          Shadow is in the Left Top direction.
    // spLeftBottom       Shadow is in the Left Bottom direction.
    // spRightBottom      Shadow is in the Right Bottom direction.
    // spRightTop         Shadow is in the Right Top direction.
    // </TABLE>
    // 
    // See Also:
    //   ShadowSize
    //   ShadowColor
    //   SimpleView
    property ShadowPos: TShadowPosition read FShadowPos write SetShadowPos default spLeftTop;
    // In the CoolControls package many controls that have 
    // captions or string items allow to paint these with 
    // the 3D effect. When you use this feature, use ShadowPos 
    // to indicate the position (relatively to the main text) 
    // of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and 
    // then with the ShadowColor (allowing ShadowSize offset).
    // Use SimpleView to indicate whether you want to use the 
    // described feature  or you do not.
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   ShadowColor
    property SimpleView: Boolean read FSimpleView write SetSimpleView default False;
    // Set ShowAccelChar to True to allow the control to 
    // display an underlined accelerator key value. When 
    // ShowAccelChar is True, any character preceded by 
    // an ampersand (&) appears underlined. If the 
    // FocusControl property is set, the windowed control 
    // specified by the FocusControl property receives 
    // input focus when the user types that underlined 
    // character. To display an ampersand when ShowAccelChar 
    // is True, use two ampersands (&&) to stand for the 
    // single ampersand that is displayed.
    // 
    // Set ShowAccelChar to False to display the control text 
    // with all ampersands appearing as ampersands. When 
    // ShowAccelChar is False, the value of the FocusControl 
    // property is not used.
    property ShowAccelChar: Boolean read FShowAccelChar write SetShowAccelChar default True;
    // Use Transparent property to specify that the
    // control will be drawn transparently. Similar to the
    // meaning of the ocPaintTransparently flag in the Options
    // property of the most controls.
    property Transparent: Boolean read FTransparent write SetTransparent default False;
    // Use Wallpaper to specify the bitmap image 
    // that will be painted as background wallpaper 
    // for a control. In most cases CoolControls package 
    // requires ocPaintWallpaper flag included into 
    // Options property set in order to actually enable 
    // wallpaper painting. Mind you that there's an 
    // alternative way to attach the image to be painted 
    // on control's background - use CoolImages and idWallpaper
    // properties for that. This technique allows to save system 
    // resources by sharing the same image between many controls.
    // 
    // See Also:
    //   Options
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
    // Event occurs when the iteration of the text is complete, that is
    // text has been completely scrolled into the view.
    property OnTextScrolled: TTextScrolledEvent read FOnTextScrolled write FOnTextScrolled;
    // Determines whether the wallpaper should be stretched to fit into the control's dimensions.
    // Otherwise image will be tiled to cover the control's surface.
    property Stretched: Boolean read FStretched write SetStretched default False;
    property Align;
    {$IFDEF DELPHI4_OR_ABOVE}
    property AutoSize;
    property Anchors;
    property BiDiMode;
    {$ENDIF}
    property Color;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Constraints;
    {$ENDIF}
    property DragCursor;
    {$IFDEF DELPHI4_OR_ABOVE}
    property DragKind;
    {$ENDIF}
    property DragMode;
    property Enabled;
    property Font;
    {$IFDEF DELPHI4_OR_ABOVE}
    property ParentBiDiMode;
    {$ENDIF}
    property ParentColor;
    property ParentFont;
    property ParentShowHint;
    property ShowHint;
    property Visible;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnEndDock;
    {$ENDIF}
    property OnEndDrag;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnStartDock;
    {$ENDIF}
    property OnStartDrag;
  end;

  {$IFNDEF VER90}
  TCoolForm = class(TCustomForm);
  {$ELSE}
  TCoolForm = class(TForm);
  {$ENDIF}

  // Determines the intence of the transparency. Underlying form can be completely
  // transparent, semi-transparent or non transparent at all.
  TTransparencyIntense = 0..255;

  // TCoolFormHook provides some additional features for the Form it's assigned to.
  // It allows drawing of the wallpapers, forms may have or have not caption, can be transparent
  // or semi-transparent, oval or rectanfular. More cool effects available.
  TCoolFormHook = class(TComponent)
  private
    FWallpaper: TBitmap;
    FOptions: TCoolOptions;
    FRoundXOffset,
    FRoundYOffset: Integer;

    FStartColor,
    FEndColor: TColor;
    FWindowHook: TWndHook;
    FAboutBox: TCCAboutBox;

    FGradientDirection: TGradientDirection;

    FCoolImages: TCoolImages;
    FidWallpaper: Integer;
    FCoolImagesChangeLink: TCoolChangeLink;

    FTransparencyIntense: TTransparencyIntense;
    FDragRect: TRect;

    procedure SetWallpaper(Value: TBitmap);
    function GetWallpaper: TBitmap;
    procedure SetOptions(Value: TCoolOptions); virtual;
    procedure SetStartColor(Value: TColor);
    procedure SetEndColor(Value: TColor);
    procedure SetGradientDirection(Value: TGradientDirection);
    procedure SetTransparencyIntense(Value: TTransparencyIntense);
    procedure WallpaperChanged(Sender: TObject);

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    function CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    procedure CoolImagesChange(Sender: TObject);
    function FormAssigned: Boolean;
  protected
    Form: TCoolForm;
    procedure BeforeMessage(Sender: TObject; var Msg: TMessage; var Handled: Boolean);
    procedure AfterMessage(Sender: TObject; var Msg: TMessage; var Handled: Boolean);
    procedure ChangeControl(Sender: TObject);
    procedure Loaded; override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    // The rectangle that is defines the area to be used for dragging the form
    // when respective properties correctly assigned.
    property DragRect: TRect read FDragRect write FDragRect;     
  published   
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    // Use CoolImages property to specify  TCoolImages component will be used 
    // to load images for wallpapers from. TcoolImages acts much like 
    // TImageList that is behaves as placeholder for images. It can contain 
    // images only but images of different sizes and color modes can be stored 
    // together in the same object.
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // There's an alternative for direct assigning of 
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties 
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper 
    // indicates the index of the image from CoolImages to be used. 
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    // You may achieve gradient button effect that is
    // button's surface will be filled gradient from the
    // StartColor \color to EndColor \color. Options property 
    // should include the ocPaintGradiently flag.
    //
    // See Also:
    //   Options
    property EndColor: TColor read FEndColor write SetEndColor default clBlack;
    // Use GradientDirection to determine the type of the gradient painting effect.
    // 
    // <TABLE>
    // Value          Meaning
    // ------------   -----------
    // gdHorizontal   Colors fill control horizontally
    // gdVertical     Colors fill control vertically
    // </TABLE>
    property GradientDirection: TGradientDirection read FGradientDirection
      write SetGradientDirection
      default gdVertical;
    // Options property controls variety of various controls parameters, the combination of included and excluded flags  determines appearance and behavior of the control. The following items that being used separately or in combination define control's look, note that some flags can not be used together and the others can or even must, note also that not all flags can be supported by the particular control or component.
    // These flags can be used with the following meaning:
    // <P>
    // * <I>ocPaintWallpaper.</I> Whether you want to paint the wallpaper for control. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocStretchWallpaper.</I> Whether you like to stretch the image to fit all the control surface. If false image will be repeatedly painted to fill the control (tiled).
    // * <I>ocPaintSelWallpaper.</I> Whether you want to paint the wallpaper for selected items. SelWallpaper or combination of  CoolImages and idSelWallpaper properties must be assigned properly.
    // * <I>ocPaintCaptionWallpaper.</I> Whether you want to paint the wallpaper for control's caption (if the latest is visible). CaptionWallpaper or combination of  CoolImages and idCaptionWallpaper properties must be assigned properly.
    // * <I>ocPaintGradiently.</I> Whether you  want to paint the gradient background. Respective color properties define the background range colors.
    // * <I>ocInvertWallpaperAsSelect.</I> Whether you want to use the same wallpaper you use for control to highlight selected items. When presents selected items will be drawn using inverted Wallpaper image, Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocBevelOnlyIfSel.</I> Whether you like to paint bevel around all the control items or only around those selected. 
    // * <I>ocNoHighlightImage.</I> If the items have attached images determines whether those for selected items should or should not be highlighted among with the item.
    // * <I>ocNoImageAttached.</I> Whether control presumes that its items some with attached images If not there will not be extra space between border and items
    // * <I>ocUseImageList.</I> Whether images should be taken from the linked Image List component or directly from the Glyph property. 
    // * <I>oc3dMDIForm.</I> Whether MDI parent form has more 3D look.
    // * <I>ocWallpaperForMDIChildren.</I> Whether attached wallpaper should be painted for all MDI child windows. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocNoCaption.</I> Whether control has caption area. Some controls will not have caption even if this property set to True.
    // * <I>ocSmallCaption.</I> What kind of caption should be used for window (if possible) standard or small caption (like for tool windows).
    // * <I>ocNoMDIChildrensCaptions.</I> Whether MDI child windows should  be drawn with the captions.
    // * <I>ocDragUsingClientArea.</I> Is it possible to drag the form using its client area.
    // * <I>ocNoDragUsingCaption.</I> Is it possible to drag the form using its caption area.
    // * <I>ocRoundedForm.</I> Whether the form should have oval shape.
    // * <I>ocFlatBorder.</I> Whether control should be painted with the modern flat look.
    // * <I>ocPaintTransparently.</I> Whether the control should have its own background or use that of the parent container.
    property Options: TCoolOptions read FOptions write SetOptions default [];
    // RoundXOffset defines how much the rounded form will be ellipse-like (ellipse vs circle offset).
    // The horizontal offset is controlled by the property.
    // 
    // See Also:
    //   RoundYOffset
    //   Options
    property RoundXOffset: Integer read FRoundXOffset write FRoundXOffset default 0;
    // RoundYOffset defines how much the rounded form will be ellipse-like (ellipse vs circle offset).    
    // The vertical offset is controlled by the property.
    // 
    // See Also:
    //   RoundXOffset
    //   Options
    property RoundYOffset: Integer read FRoundYOffset write FRoundYOffset default 0;
    // You may achieve gradient button effect that is
    // button's surface will be filled gradient from the
    // StartColor \color to EndColor \color. Options property 
    // should include the ocPaintGradiently flag.
    // 
    // See Also:
    //   Options
    property StartColor: TColor read FStartColor write SetStartColor default clBlue;
    // TransparencyIntense property defines the level of transparency semi-transparent forms come with.
    // Options should include ocPaintFormSemiTransparently flag in order for this property to be of use.
    //
    // See Also:
    //   Options
    property TransparencyIntense: TTransparencyIntense read FTransparencyIntense write SetTransparencyIntense default 128;
    // Use Wallpaper to specify the bitmap image 
    // that will be painted as background wallpaper 
    // for a control. In most cases CoolControls package 
    // requires ocPaintWallpaper flag included into 
    // Options property set in order to actually enable 
    // wallpaper painting. Mind you that there's an 
    // alternative way to attach the image to be painted 
    // on control's background - use CoolImages and idWallpaper 
    // properties for that. This technique allows to save system 
    // resources by sharing the same image between many controls.
    // 
    // See Also:
    //   Options
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
  end;

  // TMDICoolFormHook provides some additional features for the MDI Forms it's assigned to.
  // It allows drawing of the wallpapers, forms may have or have not caption, can be transparent
  // or semi-transparent, oval or rectanfular. The same modifications can be applied to the 
  // child forms. More cool effects available.
  TMDICoolFormHook = class(TCoolFormHook)
  private
    FDefProc,
    FNewProc: Pointer;
    FOldChildPaint: TNotifyEvent;
    procedure SetOptions(Value: TCoolOptions); override;
    procedure HookWndProc(AHandle: HWND);
    procedure UnHookWndProc(AHandle: HWND);
    procedure HookedPaint(Sender: TObject);
  protected
    procedure ClientWndProc(var Message: TMessage); virtual;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure Loaded; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

  // Controls the visual appearance of the button control.
  //
  // <TABLE>
  // Value               Meaning
  // ------------        --------
  // bpoDrawFocus        Whether you want to draw the focused state.
  // bpoDrawDefault      Whether you want to draw the default state.
  // </TABLE>
  TBtnPaintOption = (bpoDrawFocus, bpoDrawDefault);
  // Set of the TBtnPaintOption defined flags.
  TBtnPaintOptions = set of TBtnPaintOption;

  // TCoolBtn is a highly advanced button control with wide range of  
  // properties and features. Transparency, wallpapers, shapes, 
  // animation, 3D captions and more effects for your buttons.
  TCoolBtn = class(TButton)
  private
    IsFocused: Boolean;
    FCanvas: TCanvas;
    FGlyph: Pointer;
    FWallpaper: TBitmap;
    FOptions: TCoolOptions;
    FLayout: TButtonLayout;
    FSpacing: Integer;
    FMargin: Integer;
    FImages: TImageList;
    FImageChangeLink: TChangeLink;
    FInterval: Cardinal;
    FAnimated: Boolean;
    FImageIndex: Integer;
    FTimer: TTimer;
    FAboutBox: TCCAboutBox;

    FShadowColor: TColor;
    FShadowSize: Byte;
    FShadowPos: TShadowPosition;
    FSimpleView: Boolean;
    FTransparencyLevel: Byte;

    FColorStart,
    FColorEnd: TColor;

    FCoolImages: TCoolImages;
    FidWallpaper: Integer;
    FCoolImagesChangeLink: TCoolChangeLink;

    FGradientDirection: TGradientDirection;
    FOnDrawButton: TDrawButtonEvent;
    FMouseInControl: Boolean;
    FBtnPaintOptions: TBtnPaintOptions;

    FOnMouseEnter,
    FOnMouseLeave: TNotifyEvent;

    procedure SetWallpaper(Value: TBitmap);
    function GetWallpaper: TBitmap;
    procedure SetOptions(Value: TCoolOptions);
    procedure SetShadowColor(Value: TColor);
    procedure SetShadowSize(Value: Byte);
    procedure SetShadowPos(Value: TShadowPosition);
    procedure SetSimpleView(Value: Boolean);
    procedure SetGlyph(Value: TBitmap);
    function GetGlyph: TBitmap;
    procedure SetLayout(Value: TButtonLayout);
    function GetNumGlyphs: TNumGlyphs;
    procedure SetNumGlyphs(Value: TNumGlyphs);
    procedure SetSpacing(Value: Integer);
    procedure SetMargin(Value: Integer);
    procedure SetImages(Value: TImageList);
    procedure SetInterval(Value: Cardinal);
    procedure SetAnimated(Value: Boolean);
    procedure SetTransparencyLevel(Value: Byte);

    procedure SetColorStart(Value: TColor);
    procedure SetColorEnd(Value: TColor);
    procedure SetGradientDirection(Value: TGradientDirection);

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    function CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    procedure CoolImagesChange(Sender: TObject);

    procedure CNMeasureItem(var Message: TWMMeasureItem); message CN_MEASUREITEM;
    procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
    procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
    procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
    procedure CMColorChanged(var Message: TMessage); message CM_COLORCHANGED;
    procedure CMParentColorChanged(var Message: TMessage); message CM_PARENTCOLORCHANGED;
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure WMMouseMove(var Message: TMessage); message WM_MOUSEMOVE;

    procedure UpdateTimer(Sender: TObject);
    procedure DrawItem(DrawItemStruct: TDrawItemStruct);
    procedure DrawItemRect(DrawItemStruct: TDrawItemStruct);
    procedure DrawItemCircle(DrawItemStruct: TDrawItemStruct);
    procedure GlyphChanged(Sender: TObject);
    procedure WallpaperChanged(Sender: TObject);
    procedure ImageListChange(Sender: TObject);
  protected
    // Button will be drawn as flat looking regardless of the mouse cursor position.
    ForcedFlat: Boolean;
    procedure CreateParams(var Params: TCreateParams); override;
    // Method makes the button look like default regardless on the actual default state.
    //
    // Parameters:
    //   ADefault - defines the button default state.  
    procedure SetButtonStyle(ADefault: Boolean); override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    {$IFDEF DELPHI4_OR_ABOVE}
    procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
    {$ENDIF}
    procedure Loaded; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published   
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    // The button may have static or animated image. Use Animated
    // property to activate the animation. Images property should
    // be assigned to the TImageList containing glyphs to be used 
    // for animation effect.
    // 
    // See Also:
    //   Images
    //   Interval
    property Animated: Boolean read FAnimated write SetAnimated default False;
    // You may control every detail of the button's look. 
    // The BtnPaintOptions property allows to define the following
    // visual elements of the button.
    // 
    // <TABLE>
    // Value             Meaning
    // ------------      --------
    // bpoDrawFocus      Whether you want to draw the focused state.
    // bpoDrawDefault    Whether you want to draw the default state.
    // </TABLE>
    property BtnPaintOptions: TBtnPaintOptions read FBtnPaintOptions write FBtnPaintOptions default [bpoDrawFocus, bpoDrawDefault];
    // You may achieve gradient button effect that is
    // button's surface will be filled gradient from the
    // ColorStart \color to ColorEnd \color. Options property 
    // should include the ocPaintGradiently flag.
    // 
    // See Also:
    //   Options
    property ColorEnd: TColor read FColorEnd write SetColorEnd default clBtnShadow;
    // You may achieve gradient button effect that is
    // button's surface will be filled gradient from the
    // ColorStart \color to ColorEnd \color. Options property 
    // should include the ocPaintGradiently flag.
    // 
    // See Also:
    //   Options
    property ColorStart: TColor read FColorStart write SetColorStart default clBtnFace;
    // Use CoolImages property to specify  TCoolImages component will be used 
    // to load images for wallpapers from. TcoolImages acts much like 
    // TImageList that is behaves as placeholder for images. It can contain 
    // images only but images of different sizes and color modes can be stored 
    // together in the same object.
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // There's an alternative for direct assigning of 
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties 
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper 
    // indicates the index of the image from CoolImages to be used. 
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    // Use GradientDirection to determine the type of the gradient painting effect.
    // 
    // <TABLE>
    // Value            Meaning
    // --------------   -----------
    // gdHorizontal     Colors fill control horizontally
    // gdVertical       Colors fill control vertically
    // </TABLE>
    property GradientDirection: TGradientDirection read FGradientDirection write SetGradientDirection default gdHorizontal;
    // If the control or its items can be painted with the 
    // bitmap image (glyph) use this property to specify the bitmap 
    // image to be painted. Painting glyphs may give 
    // your controls more attractive look yet highlight the control's purpose.
    property Glyph: TBitmap read GetGlyph write SetGlyph;
    // Use Images to provide a customized list of images 
    // that can be displayed with the items.
    property Images: TImageList read FImages write SetImages;
    // When the button is Animated, Interval determines how frequently the image rendering event occurs. 
    // Each time the specified interval passes, the new image is being selected from the Images and drawn on the control.
    // 
    // Use Interval to specify any cardinal value as the interval between rendering events. The 
    // default value is 1000 ms.
    // 
    // See Also:
    //   Animated
    //   Images
    property Interval: Cardinal read FInterval write SetInterval default 1000;
    // Options property controls variety of various controls parameters, the combination of included and excluded flags  determines appearance and behavior of the control. The following items that being used separately or in combination define control's look, note that some flags can not be used together and the others can or even must, note also that not all flags can be supported by the particular control or component.
    // These flags can be used with the following meaning:
    // <P>
    // * <I>ocPaintWallpaper.</I> Whether you want to paint the wallpaper for control. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocStretchWallpaper.</I> Whether you like to stretch the image to fit all the control surface. If false image will be repeatedly painted to fill the control (tiled).
    // * <I>ocPaintSelWallpaper.</I> Whether you want to paint the wallpaper for selected items. SelWallpaper or combination of  CoolImages and idSelWallpaper properties must be assigned properly.
    // * <I>ocPaintCaptionWallpaper.</I> Whether you want to paint the wallpaper for control's caption (if the latest is visible). CaptionWallpaper or combination of  CoolImages and idCaptionWallpaper properties must be assigned properly.
    // * <I>ocPaintGradiently.</I> Whether you  want to paint the gradient background. Respective color properties define the background range colors.
    // * <I>ocInvertWallpaperAsSelect.</I> Whether you want to use the same wallpaper you use for control to highlight selected items. When presents selected items will be drawn using inverted Wallpaper image, Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocBevelOnlyIfSel.</I> Whether you like to paint bevel around all the control items or only around those selected. 
    // * <I>ocNoHighlightImage.</I> If the items have attached images determines whether those for selected items should or should not be highlighted among with the item.
    // * <I>ocNoImageAttached.</I> Whether control presumes that its items some with attached images If not there will not be extra space between border and items
    // * <I>ocUseImageList.</I> Whether images should be taken from the linked Image List component or directly from the Glyph property. 
    // * <I>oc3dMDIForm.</I> Whether MDI parent form has more 3D look.
    // * <I>ocWallpaperForMDIChildren.</I> Whether attached wallpaper should be painted for all MDI child windows. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocNoCaption.</I> Whether control has caption area. Some controls will not have caption even if this property set to True.
    // * <I>ocSmallCaption.</I> What kind of caption should be used for window (if possible) standard or small caption (like for tool windows).
    // * <I>ocNoMDIChildrensCaptions.</I> Whether MDI child windows should  be drawn with the captions.
    // * <I>ocDragUsingClientArea.</I> Is it possible to drag the form using its client area.
    // * <I>ocNoDragUsingCaption.</I> Is it possible to drag the form using its caption area.
    // * <I>ocRoundedForm.</I> Whether the form should have oval shape.
    // * <I>ocFlatBorder.</I> Whether control should be painted with the modern flat look.
    // * <I>ocPaintTransparently.</I> Whether the control should have its own background or use that of the parent container.
    property Options: TCoolOptions read FOptions write SetOptions default [];
    // The Layout property defines the layout of a bitmap within 
    // a control. These are the possible values:
    // 
    // <TABLE>
    // Value            Meaning
    // ------------     --------------
    // blGlyphLeft      The image appears on the left side of the text or caption.
    // blGlyphRight     The image appears on the right side of the text or caption.
    // blGlyphTop       The image appears at the top of the text or caption.
    // blGlyphBottom    The image appears at the bottom of the text or caption.
    // </TABLE>
    property Layout: TButtonLayout read FLayout write SetLayout default blGlyphLeft;
    // The margin is the space between the image edge and 
    // the control edge. The format of the edges depends on 
    // the layout of the image and text (specified 
    // in the Layout property). For example, if Layout is 
    // blGlyphLeft, the margin appears between the left edge 
    // of the image and the left edge of the control. If 
    // Margin is 3, three pixels separate the image and the 
    // control edges. If Margin is 0, there is no space between 
    // the image and the control edges.
    // 
    // If Margin is -1 (the default value), the image and text 
    // (specified in the Caption property) are centered. The number of 
    // pixels between the image and control edge is equal to the number 
    // of pixels between the opposite edge of the control and the text.
    property Margin: Integer read FMargin write SetMargin default -1;
    // NumGlyphs property indicates the number of images 
    // that are in the graphic specified in the Glyph 
    // property for use on a control.
    // If you have multiple images in a bitmap, you must 
    // specify the number of images that are in 
    // the bitmap with the NumGlyphs property. Valid NumGlyphs 
    // values are 1 to 4. The default value is 1.
    // 
    // See Also:
    //   Glyph
    property NumGlyphs: TNumGlyphs read GetNumGlyphs write SetNumGlyphs default 1;
    // In the CoolControls package many controls that 
    // have captions or string items allow to paint 
    // these with the 3D effect. When you use this feature, 
    // use ShadowColor to set the color of the shadow dropped. 
    // The effect being achieved by painting the text 
    // twice - once with the main color and then with the 
    // ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   SimpleView
    property ShadowColor: TColor read FShadowColor write SetShadowColor default clBtnHighlight;
    // In the CoolControls package many controls that have captions 
    // or string items allow to paint these with the 3D effect. 
    // When you use this feature, use ShadowSiize to indicate the 
    // offset  of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and then 
    // with the ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowPos
    //   ShadowColor
    //   SimpleView
    property ShadowSize: Byte read FShadowSize write SetShadowSize default 1;
    // In the CoolControls package many controls that have captions or 
    // string items allow to paint these with the 3D effect. When 
    // you use this feature, use ShadowPos to indicate the position 
    // (relatively to the main text) of the shadow dropped. The effect 
    // being achieved by painting the text twice - once with the main 
    // color and then with the ShadowColor (allowing ShadowSize offset).
    // 
    // <TABLE>
    // Value              Meaning
    // -------            -------------------------
    // spLeftTop          Shadow is in the Left Top direction.
    // spLeftBottom       Shadow is in the Left Bottom direction.
    // spRightBottom      Shadow is in the Right Bottom direction.
    // spRightTop         Shadow is in the Right Top direction.
    // </TABLE>
    // 
    // See Also:
    //   ShadowSize
    //   ShadowColor
    //   SimpleView
    property ShadowPos: TShadowPosition read FShadowPos write SetShadowPos default spLeftTop;
    // In the CoolControls package many controls that have 
    // captions or string items allow to paint these with 
    // the 3D effect. When you use this feature, use ShadowPos 
    // to indicate the position (relatively to the main text) 
    // of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and 
    // then with the ShadowColor (allowing ShadowSize offset).
    // Use SimpleView to indicate whether you want to use the 
    // described feature  or you do not.
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   ShadowColor
    property SimpleView: Boolean read FSimpleView write SetSimpleView default False;
    // Spacing determines the number of pixels between the 
    // image (specified in the Glyph property) and the text 
    // (specified in the Caption property). The default value 
    // is 4 pixels.
    // 
    // If Spacing is a positive number, its value is the number 
    // of pixels between the image and text. If Spacing is 0, no pixels 
    // will be between the image and text. If Spacing is -1, the text 
    // appears centered between the image and the control edge. The number of 
    // pixels between the image and text is equal to the number of pixels between the text and 
    // the control edge opposite the glyph.
    property Spacing: Integer read FSpacing write SetSpacing default 4;
    // Use TransparencyLevel to specify the 
    // parent control whose part will be used 
    // to draw the background of the component. 
    // For example if control placed on the panel 
    // that is placed on the form, setting TransparencyLevel 
    // to 0 will force part of the panel to be used for 
    // painting of the transparent background, setting 
    // TransparencyLevel to 1 will force the part of the 
    // form to be selected on the controls device context 
    // when paint transparently.
    property TransparencyLevel: Byte read FTransparencyLevel write SetTransparencyLevel default 0;
    // Use Wallpaper to specify the bitmap image 
    // that will be painted as background wallpaper 
    // for a control. In most cases CoolControls package 
    // requires ocPaintWallpaper flag included into 
    // Options property set in order to actually enable 
    // wallpaper painting. Mind you that there's an 
    // alternative way to attach the image to be painted 
    // on control's background - use CoolImages and idWallpaper 
    // properties for that. This technique allows to save system 
    // resources by sharing the same image between many controls.
    // 
    // See Also:
    //   Options
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
    // Event occurs when the button control being painted.
    property OnDrawButton: TDrawButtonEvent read FOnDrawButton write FOnDrawButton;
    property Color default clBtnFace;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Action;
    property Anchors;
    property BiDiMode;
    {$ENDIF}
    property Cancel;
    property Caption;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Constraints;
    {$ENDIF}
    property Default;
    property Enabled;
    property ModalResult;
    property ParentShowHint;
    {$IFDEF DELPHI4_OR_ABOVE}
    property ParentBiDiMode;
    {$ENDIF}
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Visible;
    property OnEnter;
    property OnExit;
    // OnMouseEnter event occurs immediately after mouse cursor enters the control.
    property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
    // OnMouseLeave event occurs immediately after mouse cursor leaves the control.
    property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  end;

  // Defines the type of button
  //
  // <TABLE>
  // Value 				Meaning
  // -------------			-------------------
  // cbtClose 			Close button
  // cbtHelp 			Help button
  // cbtMaximize 			Maximize button
  // cbtMinimize 			Minimize button
  // cbtRestore			Restore button
  // </TABLE>
  TCaptionBtnType = (cbtClose, cbtHelp, cbtMaximize, cbtMinimize, cbtRestore);

  // TCaptionBtn control encapsulates functionality and appearance of the caption 
  // buttons and allows to place them anywhere in the form.
  TCoolCaptionBtn = class(TButton)
  private
    FCanvas: TCanvas;
    IsFocused: Boolean;
    FCaptionBtnType: TCaptionBtnType;
    FAboutBox: TCCAboutBox;
    procedure SetCaptionBtnType(Value: TCaptionBtnType);
    function GetCaption: TCaption;
    procedure DrawItem(DrawItemStruct: TDrawItemStruct);
    procedure CNMeasureItem(var Message: TWMMeasureItem); message CN_MEASUREITEM;
    procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
  protected
    procedure CreateParams(var Params: TCreateParams); override;
    procedure SetButtonStyle(ADefault: Boolean); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published   
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    // Use CaptionBtnType to determine what caption button type will be used.
    //
    // <TABLE>
    // Value 				Meaning
    // -------------			-------------------
    // cbtClose 			Close button
    // cbtHelp 			Help button
    // cbtMaximize 			Maximize button
    // cbtMinimize 			Minimize button
    // cbtRestore			Restore button
    // </TABLE>
    property CaptionBtnType: TCaptionBtnType read FCaptionBtnType write SetCaptionBtnType default cbtClose;
    // Use Caption to associate the control with a text string that identifies the control. 
    // For most controls, the Caption is the window title and 
    // it appears as a label for the control.
    property Caption: TCaption read GetCaption;
  end;

  // Defines the position of the control.
  //
  // <TABLE>
  // Value              Meaning
  // -------------      ----------------
  // toHorizontal       Horizontally positioned control
  // toVertical         Vertically positioned control
  // </TABLE>
  TTrackOrientation = (toHorizontal, toVertical);

  // Contains extra optionss for the TCoolTrackBar painting.
  // <TABLE> 
  // Value               Meaning
  // --------------      ---------------
  // poDrawFocusRect     Should be drawn focused rect when control is selected
  // poDrawTrackBar      Should be drawn track bar
  // poDrawTicks         Should be drawn ticks
  // poDrawThumb         Should be drawn thumb
  // poDrawThumbStates   Should be used special thumb when it is in action
  TPaintOption = (poDrawFocusRect, poDrawTrackBar, poDrawTicks, poDrawThumb, poDrawThumbStates);

  // Set of the TPaintOption flags.
  TPaintOptions = set of TPaintOption;
      
  /// TCoolTrackBar is a highly advanced trackbar control. It enhanced with
  // the wallpapers, transparency and other features.  
  TCoolTrackBar = class(TCustomControl)
  private
    FOrientation: TTrackOrientation;
    FMinValue: Integer;
    FMaxValue: Integer;
    FPosition: Integer;

    FThumbHorz,
    FThumbVert,
    FThumbHorzSelected,
    FThumbVertSelected,
    FThumbImage: TBitmap;

    FThumbRect: TRect;
    FTrackRect: TRect;

    FTickMarks: TTickMark;
    FBarSize: Integer;
    FBarColor: TColor;
    FBorderWidth: Integer;

    FPageSize: Word;
    FSliding: Boolean;

    FBevelInner,
    FBevelOuter: TPanelBevel;

    FTransparentThumb: Boolean;
    FOptions: TCoolOptions;
    FPaintOptions: TPaintOptions;
    FWallpaper: TBitmap;
    FTransparencyLevel: Byte;

    FAboutBox: TCCAboutBox;

    FCoolImages: TCoolImages;
    FidWallpaper: Integer;
    FCoolImagesChangeLink: TCoolChangeLink;

    FOnChange: TNotifyEvent;
    FOnMouseEnter,
    FOnMouseLeave: TNotifyEvent;

    procedure SetOrientation(Value: TTrackOrientation);
    procedure SetMinValue(Value: Integer);
    procedure SetMaxValue(Value: Integer);
    procedure SetPosition(Value: Integer);
    procedure SetBarSize(Value: Integer);
    procedure SetBarColor(Value: TColor);
    procedure SetTickMarks(Value: TTickMark);
    procedure SetTransparencyLevel(Value: Byte);

    function GetThumbHorz: TBitmap;
    function GetThumbVert: TBitmap;
    function GetThumbHorzSelected: TBitmap;
    function GetThumbVertSelected: TBitmap;
    procedure SetThumbHorz(Value: TBitmap);
    procedure SetThumbVert(Value: TBitmap);
    procedure SetThumbHorzSelected(Value: TBitmap);
    procedure SetThumbVertSelected(Value: TBitmap);

    procedure SetBevelInner(Value: TPanelBevel);
    procedure SetBevelOuter(Value: TPanelBevel);

    procedure SetTransparentThumb(Value: Boolean);
    procedure SetOptions(Value: TCoolOptions);
    procedure SetWallpaper(Value: TBitmap);
    function GetWallpaper: TBitmap;
    procedure SetPaintOptions(Value: TPaintOptions);
    procedure WallpaperChanged(Sender: TObject);

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    function CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    procedure CoolImagesChange(Sender: TObject);

    procedure InvalidateThumb;

    procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
    procedure CMParentColorChanged(var Message: TMessage); message CM_PARENTCOLORCHANGED;
    procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  protected
    procedure Loaded; override;
    procedure LoadImages; virtual;
    procedure DrawTrack(ACanvas: TCanvas); virtual;
    procedure DrawTicks(ACanvas: TCanvas); virtual;
    procedure DrawThumb(ACanvas: TCanvas); virtual;
    procedure Paint; override;

    procedure DoEnter; override;
    procedure DoExit; override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure SetFocus; override;
  published
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    // Use BarColor property to specify the \color of the bar. That is color of the inner
    // part of the track bar.
    property BarColor: TColor read FBarColor write SetBarColor default clWindow;
    // Use BarSize  property to specify the \height (or \width if Orientation is toVertical) of the bar. That is measurement of the inner
    // part of the track bar.
    property BarSize: Integer read FBarSize write SetBarSize default 10;
    // Use BevelInner to specify whether the inner bevel has a raised, lowered, or flat look. 
    // 
    // The inner bevel appears immediately inside the outer bevel. If there is no outer bevel (BevelOuter is bvNone), the inner bevel appears immediately inside the border.
    property BevelInner: TPanelBevel read FBevelInner write SetBevelInner default bvNone;
    // Use BevelOuter to specify whether the outer bevel has a raised, lowered, or flat look. The outer bevel appears immediately inside the border and outside the inner bevel.
    property BevelOuter: TPanelBevel read FBevelOuter write SetBevelOuter default bvNone;
    // Use CoolImages property to specify  TCoolImages component will be used 
    // to load images for wallpapers from. TcoolImages acts much like 
    // TImageList that is behaves as placeholder for images. It can contain 
    // images only but images of different sizes and color modes can be stored 
    // together in the same object.
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // There's an alternative for direct assigning of 
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties 
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper 
    // indicates the index of the image from CoolImages to be used. 
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    // Use Orientation to determine orentation (position) of the control.
    //
    // <TABLE>
    // Value              Meaning
    // -------------      ----------------
    // toHorizontal       Horizontally positioned control
    // toVertical         Vertically positioned control
    // </TABLE>
    property Orientation: TTrackOrientation read FOrientation write SetOrientation default toHorizontal;

    // Use MinValue to set a lower limit to the value that can be represented 
    // using the track bar. A slider indicates the current Position in a range between MinValue and MaxValue.
    property MinValue: Integer read FMinValue write SetMinValue default 0;
    // Use MaxValue to set an upper limit to the value that can be represented using 
    // the track bar. A slider indicates the current Position in a range between MinValue and MaxValue.
    property MaxValue: Integer read FMaxValue write SetMaxValue default 10;
    // Options property controls variety of various controls parameters, the combination of included and excluded flags  determines appearance and behavior of the control. The following items that being used separately or in combination define control's look, note that some flags can not be used together and the others can or even must, note also that not all flags can be supported by the particular control or component.
    // These flags can be used with the following meaning:
    // <P>
    // * <I>ocPaintWallpaper.</I> Whether you want to paint the wallpaper for control. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocStretchWallpaper.</I> Whether you like to stretch the image to fit all the control surface. If false image will be repeatedly painted to fill the control (tiled).
    // * <I>ocPaintSelWallpaper.</I> Whether you want to paint the wallpaper for selected items. SelWallpaper or combination of  CoolImages and idSelWallpaper properties must be assigned properly.
    // * <I>ocPaintCaptionWallpaper.</I> Whether you want to paint the wallpaper for control's caption (if the latest is visible). CaptionWallpaper or combination of  CoolImages and idCaptionWallpaper properties must be assigned properly.
    // * <I>ocPaintGradiently.</I> Whether you  want to paint the gradient background. Respective color properties define the background range colors.
    // * <I>ocInvertWallpaperAsSelect.</I> Whether you want to use the same wallpaper you use for control to highlight selected items. When presents selected items will be drawn using inverted Wallpaper image, Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocBevelOnlyIfSel.</I> Whether you like to paint bevel around all the control items or only around those selected. 
    // * <I>ocNoHighlightImage.</I> If the items have attached images determines whether those for selected items should or should not be highlighted among with the item.
    // * <I>ocNoImageAttached.</I> Whether control presumes that its items some with attached images If not there will not be extra space between border and items
    // * <I>ocUseImageList.</I> Whether images should be taken from the linked Image List component or directly from the Glyph property. 
    // * <I>oc3dMDIForm.</I> Whether MDI parent form has more 3D look.
    // * <I>ocWallpaperForMDIChildren.</I> Whether attached wallpaper should be painted for all MDI child windows. Wallpaper or combination of  CoolImages and idWallpaper properties must be assigned properly.
    // * <I>ocNoCaption.</I> Whether control has caption area. Some controls will not have caption even if this property set to True.
    // * <I>ocSmallCaption.</I> What kind of caption should be used for window (if possible) standard or small caption (like for tool windows).
    // * <I>ocNoMDIChildrensCaptions.</I> Whether MDI child windows should  be drawn with the captions.
    // * <I>ocDragUsingClientArea.</I> Is it possible to drag the form using its client area.
    // * <I>ocNoDragUsingCaption.</I> Is it possible to drag the form using its caption area.
    // * <I>ocRoundedForm.</I> Whether the form should have oval shape.
    // * <I>ocFlatBorder.</I> Whether control should be painted with the modern flat look.
    // * <I>ocPaintTransparently.</I> Whether the control should have its own background or use that of the parent container.
    property Options: TCoolOptions read FOptions write SetOptions default [];
    // Use PaintOptions to set up additional options for painting the control.
    // 
    // <TABLE> 
    // Value               Meaning
    // --------------      ---------------
    // poDrawFocusRect     Should be drawn focused rect when control is selected
    // poDrawTrackBar      Should be drawn track bar
    // poDrawTicks         Should be drawn ticks
    // poDrawThumb         Should be drawn thumb
    // poDrawThumbStates   Should be used special thumb when it is in action
    // </TABLE> 
    property PaintOptions: TPaintOptions read FPaintOptions write SetPaintOptions default [poDrawFocusRect, poDrawTrackBar, poDrawTicks, poDrawThumb, poDrawThumbStates];
    // Set PageSize to the distance along the track bar that corresponds to a single view. 
    // A slider marks the current Position. The PageUp key increments the value of Position by PageSize, and PageDown key decrements the value of Position by PageSize. 
    property PageSize: Word read FPageSize write FPageSize default 1;
    // Set or read Position to determine the current value represented by the track bar. Position is 
    // a value in the range between MinValue and MaxValue (inclusive). Set Position to programmatically move the slider of the track bar to a new value.    
    property Position: Integer read FPosition write SetPosition default 0;
    // Set TickMarks to specify where the tick marks should be drawn. TickMarks has these possible values:
    //
    // <TABLE>
    // Value	   Meaning
    // -------------   --------------
    // tmBottomRight   Tick marks are on the bottom or right of the track bar, depending of the value of Orientation.
    // tmTopLeft	   Tick marks are on the top or left of the track bar, depending of the value of Orientation.
    // tmBoth	   Tick marks are on both sides of the track bar.
    // </TABLE>
    property TickMarks: TTickMark read FTickMarks write SetTickMarks default tmBottomRight;
    // When Orientation is toHorizontal use ThumbHorz to specify custom image to be
    // drawn instead of standard thumb glyph.
    //
    // See Also:
    //   Orientation 
    property ThumbHorz: TBitmap read GetThumbHorz write SetThumbHorz;
    // When Orientation is toVertical use ThumbHorz to specify custom image to be
    // drawn instead of standard thumb glyph.
    //
    // See Also:
    //   Orientation 
    property ThumbVert: TBitmap read GetThumbVert write SetThumbVert;
    // When Orientation is toHorizontal and thumb is currently selected use ThumbHorzSelected to specify custom image to be
    // drawn instead of standard thumb glyph.
    //
    // See Also:
    //   Orientation 
    //   ThumbHorz
    property ThumbHorzSelected: TBitmap read GetThumbHorzSelected write SetThumbHorzSelected;
    // When Orientation is toVertical and thumb is currently selected use ThumbHorzSelected to specify custom image to be
    // drawn instead of standard thumb glyph.
    //
    // See Also:
    //   Orientation 
    //   ThumbVert
    property ThumbVertSelected: TBitmap read GetThumbVertSelected write SetThumbVertSelected;
    // Use Transparent property to specify that the
    // control will be drawn transparently. Similar to the
    // meaning of the ocPaintTransparently flag in the Options
    // property of the most controls.
    property TransparentThumb: Boolean read FTransparentThumb write SetTransparentThumb default True;
    // Use TransparencyLevel to specify the 
    // parent control whose part will be used 
    // to draw the background of the component.
    // For example if control placed on the panel 
    // that is placed on the form, setting TransparencyLevel 
    // to 0 will force part of the panel to be used for 
    // painting of the transparent background, setting 
    // TransparencyLevel to 1 will force the part of the 
    // form to be selected on the controls device context 
    // when paint transparently.
    property TransparencyLevel: Byte read FTransparencyLevel write SetTransparencyLevel default 0;
    // Use Wallpaper to specify the bitmap image 
    // that will be painted as background wallpaper 
    // for a control. In most cases CoolControls package 
    // requires ocPaintWallpaper flag included into 
    // Options property set in order to actually enable 
    // wallpaper painting. Mind you that there's an 
    // alternative way to attach the image to be painted 
    // on control's background - use CoolImages and idWallpaper 
    // properties for that. This technique allows to save system 
    // resources by sharing the same image between many controls.
    // 
    // See Also:
    //   Options
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
    // Event occurs when Position values is changed.
    //
    // See Also:
    //   Position
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Action;
    property Anchors;
    property BiDiMode;
    {$ENDIF}
    property Caption;
    property Color;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Constraints;
    {$ENDIF}
    property Ctl3D;
    {$IFDEF DELPHI4_OR_ABOVE}
    property UseDockManager default True;
    property DockSite;
    {$ENDIF}
    property DragCursor;
    {$IFDEF DELPHI4_OR_ABOVE}
    property DragKind;
    {$ENDIF}
    property DragMode;
    property Enabled;
    property Font;
    {$IFDEF DELPHI4_OR_ABOVE}
    property ParentBiDiMode;
    {$ENDIF}
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Visible;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnCanResize;
    {$ENDIF}
    property OnClick;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnConstrainedResize;
    property OnDockDrop;
    property OnDockOver;
    {$ENDIF}
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnEndDock;
    {$ENDIF}
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnGetSiteInfo;
    {$ENDIF}
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnResize;
    property OnStartDock;
    property OnUnDock;
    {$ENDIF}
    property OnStartDrag;
  end;

  // Deines position of the TCoolThumbTab control in the parent windowed control.
  // 
  // <TABLE>
  // Value                Position
  // ------------         ------------------------
  // tpLeftBottom         In the left bottom corner
  // tpRightBottom        In the right bottom corner
  // tpLeftTop            In the left top corner
  // tpRightTop           In the right top corner
  // </TABLE>
  TCoolThumbTabPosition = (tpLeftBottom, tpRightBottom, tpLeftTop, tpRightTop);

  // TCoolThumbTab can be placed to one of the TWinControl descendant's 
  // corners so it is possible to resize it.  Useful for touch screens, 
  // if you develop softwre for people with disabilities and just like 
  // additional functionality for an application.
  TCoolThumbTab = class(TGraphicControl)
  private
    FAboutBox: TCCAboutBox;
    FWindowHook: TWndHook;
    FThumbPosition: TCoolThumbTabPosition;
    FTransparent: Boolean;
    FWallpaper: TBitmap;

    FCoolImages: TCoolImages;
    FidWallpaper: Integer;
    FCoolImagesChangeLink: TCoolChangeLink;

    FStretched: Boolean;
    
    procedure SetThumbPosition(Value: TCoolThumbTabPosition);
    procedure SetWallpaper(Value: TBitmap);
    function GetWallpaper: TBitmap;
    procedure WallpaperChanged(Sender: TObject);
    procedure SetTransparent(Value: Boolean);
    procedure SetStretched(Value: Boolean);

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    function CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    procedure CoolImagesChange(Sender: TObject);

    procedure AfterMessage(Sender: TObject; var Msg: TMessage; var Handled: Boolean);
    function SubRect: TRect;
  protected
    procedure WndProc(var Message: TMessage); override;
    procedure Paint; override;
    procedure Loaded; override;
    procedure SetParent(AParent: TWinControl); override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published   
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    // Use CoolImages property to specify  TCoolImages component will be used 
    // to load images for wallpapers from. TcoolImages acts much like 
    // TImageList that is behaves as placeholder for images. It can contain 
    // images only but images of different sizes and color modes can be stored 
    // together in the same object.
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // There's an alternative for direct assigning of 
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties 
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper 
    // indicates the index of the image from CoolImages to be used. 
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    //
    // See Also:
    //   Options
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    // Use ThumbPosition property to specify position of the control in the parent windowed control.
    // 
    // <TABLE>
    // Value                Position
    // ------------         ------------------------
    // tpLeftBottom         In the left bottom corner
    // tpRightBottom        In the right bottom corner
    // tpLeftTop            In the left top corner
    // tpRightTop           In the right top corner
    // </TABLE>
    property ThumbPosition: TCoolThumbTabPosition read FThumbPosition write SetThumbPosition default tpRightBottom;
    // Use Transparent property to specify that the
    // control will be drawn transparently. Similar to the
    // meaning of the ocPaintTransparently flag in the Options
    // property of the most controls.
    property Transparent: Boolean read FTransparent write SetTransparent default False;
    // Determines whether the wallpaper should be stretched to fit into the control's dimensions.
    // Otherwise image will be tiled to cover the control's surface.
    property Stretched: Boolean read FStretched write SetStretched default False;
    // Use Wallpaper to specify the bitmap image 
    // that will be painted as background wallpaper 
    // for a control. In most cases CoolControls package 
    // requires ocPaintWallpaper flag included into 
    // Options property set in order to actually enable 
    // wallpaper painting. Mind you that there's an 
    // alternative way to attach the image to be painted 
    // on control's background - use CoolImages and idWallpaper 
    // properties for that. This technique allows to save system
    // resources by sharing the same image between many controls.
    // 
    // See Also:
    //   Options
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Anchors;
    {$ENDIF}
    property Align;
    property Enabled;
    property Color;
    property PopupMenu;
    property ParentColor;
    property Visible;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnEndDock;
    property OnStartDock;
    {$ENDIF}
    property OnEndDrag;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDrag;
  end;

  // TCoolBevel is advanced bevel component that allows you to use any color
  // and wallpapers for the bevel.
  TCoolBevel = class(TBevel)
  private
    FAboutBox: TCCAboutBox;
    FColor: TColor;
    FCoolImages: TCoolImages;
    FidWallpaper: Integer;
    FCoolImagesChangeLink: TCoolChangeLink;
    FTransparent: Boolean;
    FFlat: Boolean;
    FWallpaper: TBitmap;

    FStretched: Boolean;

    FOnMouseEnter,
    FOnMouseLeave: TNotifyEvent;

    procedure SetColor(Value: TColor);
    procedure SetTransparent(Value: Boolean);
    procedure SetCoolImages(Value: TCoolImages);
    procedure SetFlat(Value: Boolean);
    procedure SetStretched(Value: Boolean);

    procedure SetidWallpaper(Value: Integer);
    function IsWallpaperAssigned: Boolean;
    function CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    procedure CoolImagesChange(Sender: TObject);
    procedure WallpaperChanged(Sender: TObject);

    function GetWallpaper: TBitmap;
    procedure SetWallpaper(Value: TBitmap);

    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  protected
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure Paint; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published   
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    property Color: TColor read FColor write SetColor default clBtnFace;
    // Use CoolImages property to specify  TCoolImages component will be used 
    // to load images for wallpapers from. TcoolImages acts much like 
    // TImageList that is behaves as placeholder for images. It can contain 
    // images only but images of different sizes and color modes can be stored 
    // together in the same object.
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // Use Flat property to indicate when control should be painted in a modern
    // flat way.
    property Flat: Boolean read FFlat write SetFlat default False;
    // There's an alternative for direct assigning of
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties 
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper 
    // indicates the index of the image from CoolImages to be used. 
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    // Determines whether the wallpaper should be stretched to fit into the control's dimensions.
    // Otherwise image will be tiled to cover the control's surface.
    property Stretched: Boolean read FStretched write SetStretched default False;
    // Use Transparent property to specify that the
    // control will be drawn transparently. Similar to the
    // meaning of the ocPaintTransparently flag in the Options
    // property of the most controls.
    property Transparent: Boolean read FTransparent write SetTransparent default True;
    // Use Wallpaper to specify the bitmap image 
    // that will be painted as background wallpaper 
    // for a control. In most cases CoolControls package 
    // requires ocPaintWallpaper flag included into 
    // Options property set in order to actually enable 
    // wallpaper painting. Mind you that there's an 
    // alternative way to attach the image to be painted 
    // on control's background - use CoolImages and idWallpaper 
    // properties for that. This technique allows to save system 
    // resources by sharing the same image between many controls.
    // 
    // See Also:
    //   Options
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
    property OnClick;
    // OnMouseEnter event occurs immediately after mouse cursor enters the control.
    property OnMouseEnter: TNotifyevent read FOnMouseEnter write FOnMouseEnter;
    // OnMouseLeave event occurs immediately after mouse cursor leaves the control.
    property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  end;

  // TCustomCoolCheckRadioGroup is an advanced group box control that groups TCoolCheckRadioBox
  // controls.
  TCustomCoolCheckRadioGroup = class(TCoolGroupBox)
  private
    FAboutBox: TCCAboutBox;
    FButtons: TList;
    FItems: TStrings;
    FItemIndex: Integer;
    FColumns: Integer;
    FReading: Boolean;
    FUpdating: Boolean;
    FFlat: Boolean;
    FCheckRadioType: TCheckRadioType;
    FGlyphMarked,
    FGlyphNormal: TBitmap;

    procedure SetCheckRadioType(Value: TCheckRadioType);
    procedure SetButtonCount(Value: Integer);
    procedure SetColumns(Value: Integer);
    procedure SetItemIndex(Value: Integer);
    procedure SetItems(Value: TStrings);
    procedure SetGlyphNormal(Value: TBitmap);
    procedure SetFlat(Value: Boolean);
    function GetGlyphNormal: TBitmap;
    procedure SetGlyphMarked(Value: TBitmap);
    function GetGlyphMarked: TBitmap;

    procedure ArrangeButtons;
    procedure ButtonClick(Sender: TObject);
    procedure ItemsChange(Sender: TObject);
    procedure UpdateButtons;

    procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
    procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
    procedure CMChanged(var Message: TMessage); message CM_CHANGED;
  protected
    procedure ReadState(Reader: TReader); override;
    procedure Loaded; override;

    // Use CheckRadioType property to chose the type of the check-radio box control.
    // 
    // <TABLE>
    // Value           Meaning		
    // ---------       ----------
    // crCheckBox      Check box control
    // crRadioBox      Radio button control
    // </TABLE>
    property CheckRadioType: TCheckRadioType read FCheckRadioType write SetCheckRadioType default crRadioBox;
    property Columns: Integer read FColumns write SetColumns default 1;
    // If the control or its items can be painted with the 
    // bitmap image (glyph) use this property to specify the bitmap 
    // image to be painted. Painting glyphs may give 
    // your controls more attractive look yet highlight the control's purpose.
    property GlyphMarked: TBitmap read GetGlyphMarked write SetGlyphMarked;
    // If the control or its items can be painted with the 
    // bitmap image (glyph) use this property to specify the bitmap 
    // image to be painted. Painting glyphs may give 
    // your controls more attractive look yet highlight the control's purpose.
    property GlyphNormal: TBitmap read GetGlyphNormal write SetGlyphNormal;
    // Use Flat property to indicate when control should be painted in a modern
    // flat way.
    property Flat: Boolean read FFlat write SetFlat default False;
    property ItemIndex: Integer read FItemIndex write SetItemIndex default -1;
    property Items: TStrings read FItems write SetItems;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published   
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
  end;

  // Publishes properties of the TCustomCoolCheckRadioGroup control.
  TCoolCheckRadioGroup = class(TCustomCoolCheckRadioGroup)
  published
    // Use CheckRadioType property to chose the type of the check-radio box control.
    // 
    // <TABLE>
    // Value           Meaning		
    // ---------       ----------
    // crCheckBox      Check box control
    // crRadioBox      Radio button control
    // </TABLE>
    property CheckRadioType;
    property Columns;
    // If the control or its items can be painted with the 
    // bitmap image (glyph) use this property to specify the bitmap 
    // image to be painted. Painting glyphs may give 
    // your controls more attractive look yet highlight the control's purpose.
    property GlyphMarked;
    // If the control or its items can be painted with the 
    // bitmap image (glyph) use this property to specify the bitmap 
    // image to be painted. Painting glyphs may give 
    // your controls more attractive look yet highlight the control's purpose.
    property GlyphNormal;
    // Use Flat property to indicate when control should be painted in a modern
    // flat way.
    property Flat;
    property ItemIndex;
    property Items;
  end;

  // Defines current state of the TCustomPopupButton control.
  //
  // <TABLE>
  // Value          Meaning
  // ---------      --------------
  // bseDownBoth    Both buttos in down state
  // bseDownAdd     Right button in down state
  // bseUpBoth      Both buttos in up state
  // bseNoneBoth    Both buttos in undefined state
  // </TABLE>
  TButtonStateEx = (bseDownBoth, bseDownAdd, bseUpBoth, bseNoneBoth);

  // TCustomPopupButton is a button control with attached popup menu that becomes 
  // active when right button is clicked. The similar controls can be found in  
  // Outlook Express and many other modern programs.
  TCustomPopupButton = class(TGraphicControl)
  private
    FButtonStateEx: TButtonStateEx;
    FAboutBox: TCCAboutBox;
    FBtnAddSize: Integer;

    FGlyph: Pointer;
    FLayout: TButtonLayout;
    FSpacing: Integer;
    FMargin: Integer;

    FShadowColor: TColor;
    FShadowSize: Byte;
    FShadowPos: TShadowPosition;
    FSimpleView: Boolean;
    FStretched: Boolean;

    FFlat: Boolean;
    FTransparent: Boolean;

    FCoolImagesChangeLink: TCoolChangeLink;

    FWallPaper: TBitmap;
    FCoolImages: TCoolImages;
    FidWallpaper: Integer;

    procedure SetGlyph(Value: TBitmap);
    function GetGlyph: TBitmap;
    procedure SetLayout(Value: TButtonLayout);
    function GetNumGlyphs: TNumGlyphs;
    procedure SetNumGlyphs(Value: TNumGlyphs);
    procedure SetSpacing(Value: Integer);
    procedure SetMargin(Value: Integer);
    procedure GlyphChanged(Sender: TObject);

    procedure SetWallPaper(Value: TBitmap);
    function GetWallpaper: TBitmap;
    procedure WallpaperChanged(Sender: TObject);
    function CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    function IsWallpaperAssigned: Boolean;
    procedure SetidWallpaper(Value: Integer);
    procedure SetCoolImages(Value: TCoolImages);
    procedure CoolImagesChange(Sender: TObject);

    procedure SetShadowColor(Value: TColor);
    procedure SetShadowSize(Value: Byte);
    procedure SetShadowPos(Value: TShadowPosition);
    procedure SetSimpleView(Value: Boolean);
    procedure SetStretched(Value: Boolean);

    procedure SetFlat(Value: Boolean);
    procedure SetTransparent(Value: Boolean);
    procedure SetBtnAddSize(Value: Integer);

    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure CMHitTest(var Message: TCMHitTest); message CM_HITTEST;
    procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
  protected
    Handle: THandle;
    // Run-time. Use ButtonStateEx to obtain/set current state of the TCustomPopupButton control.
    //
    // <TABLE>
    // Value          Meaning
    // ---------      --------------
    // bseDownBoth    Both buttos in down state
    // bseDownAdd     Right button in down state
    // bseUpBoth      Both buttos in up state
    // bseNoneBoth    Both buttos in undefined state
    // </TABLE>
    property ButtonStateEx: TButtonStateEx read FButtonStateEx write FButtonStateEx;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure WndProc(var Message: TMessage); override;
    procedure Paint; override;
    procedure Click; override;
    // Click event for the right button.
    procedure ClickAdd; virtual;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    // TCustomPopuButton is complex class that contains two buttons. BtnAddSize property 
    // specifies the width of the right button (the one that usually activates popup menu).
    property BtnAddSize: Integer read FBtnAddSize write SetBtnAddSize default 16;
    // Use CoolImages property to specify  TCoolImages component will be used 
    // to load images for wallpapers from. TcoolImages acts much like 
    // TImageList that is behaves as placeholder for images. It can contain 
    // images only but images of different sizes and color modes can be stored 
    // together in the same object.
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // There's an alternative for direct assigning of 
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties 
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper 
    // indicates the index of the image from CoolImages to be used. 
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    // Use Flat property to indicate when control should be painted in a modern
    // flat way.
    property Flat: Boolean read FFlat write SetFlat default False;
    // If the control or its items can be painted with the 
    // bitmap image (glyph) use this property to specify the bitmap 
    // image to be painted. Painting glyphs may give 
    // your controls more attractive look yet highlight the control's purpose.
    property Glyph: TBitmap read GetGlyph write SetGlyph;
    // The Layout property defines the layout of a bitmap within 
    // a control. These are the possible values:
    // 
    // <TABLE>
    // Value            Meaning
    // ------------     --------------
    // blGlyphLeft      The image appears on the left side of the text or caption.
    // blGlyphRight     The image appears on the right side of the text or caption.
    // blGlyphTop       The image appears at the top of the text or caption.
    // blGlyphBottom    The image appears at the bottom of the text or caption.
    // </TABLE>
    property Layout: TButtonLayout read FLayout write SetLayout default blGlyphLeft;
    // The margin is the space between the image edge and 
    // the control edge. The format of the edges depends on 
    // the layout of the image and text (specified 
    // in the Layout property). For example, if Layout is 
    // blGlyphLeft, the margin appears between the left edge 
    // of the image and the left edge of the control. If 
    // Margin is 3, three pixels separate the image and the 
    // control edges. If Margin is 0, there is no space between 
    // the image and the control edges.
    // 
    // If Margin is -1 (the default value), the image and text 
    // (specified in the Caption property) are centered. The number of 
    // pixels between the image and control edge is equal to the number 
    // of pixels between the opposite edge of the control and the text.
    property Margin: Integer read FMargin write SetMargin default -1;
    // NumGlyphs property indicates the number of images 
    // that are in the graphic specified in the Glyph 
    // property for use on a control.
    // If you have multiple images in a bitmap, you must 
    // specify the number of images that are in 
    // the bitmap with the NumGlyphs property. Valid NumGlyphs 
    // values are 1 to 4. The default value is 1.
    // 
    // See Also:
    //   Glyph
    property NumGlyphs: TNumGlyphs read GetNumGlyphs write SetNumGlyphs default 1;
    // Spacing determines the number of pixels between the 
    // image (specified in the Glyph property) and the text 
    // (specified in the Caption property). The default value 
    // is 4 pixels.
    // 
    // If Spacing is a positive number, its value is the number 
    // of pixels between the image and text. If Spacing is 0, no pixels 
    // will be between the image and text. If Spacing is -1, the text 
    // appears centered between the image and the control edge. The number of 
    // pixels between the image and text is equal to the number of pixels between the text and
    // the control edge opposite the glyph.
    property Spacing: Integer read FSpacing write SetSpacing default 4;
    // In the CoolControls package many controls that 
    // have captions or string items allow to paint 
    // these with the 3D effect. When you use this feature, 
    // use ShadowColor to set the color of the shadow dropped. 
    // The effect being achieved by painting the text 
    // twice - once with the main color and then with the 
    // ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   SimpleView
    property ShadowColor: TColor read FShadowColor write SetShadowColor default clBtnHighlight;
    // In the CoolControls package many controls that have captions 
    // or string items allow to paint these with the 3D effect.
    // When you use this feature, use ShadowSiize to indicate the
    // offset  of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and then 
    // with the ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowPos
    //   ShadowColor
    //   SimpleView
    property ShadowSize: Byte read FShadowSize write SetShadowSize default 1;
    // In the CoolControls package many controls that have captions or 
    // string items allow to paint these with the 3D effect. When 
    // you use this feature, use ShadowPos to indicate the position 
    // (relatively to the main text) of the shadow dropped. The effect 
    // being achieved by painting the text twice - once with the main 
    // color and then with the ShadowColor (allowing ShadowSize offset).
    // 
    // <TABLE>
    // Value              Meaning
    // -------            -------------------------
    // spLeftTop          Shadow is in the Left Top direction.
    // spLeftBottom       Shadow is in the Left Bottom direction.
    // spRightBottom      Shadow is in the Right Bottom direction.
    // spRightTop         Shadow is in the Right Top direction.
    // </TABLE>
    // 
    // See Also:
    //   ShadowSize
    //   ShadowColor
    //   SimpleView
    property ShadowPos: TShadowPosition read FShadowPos write SetShadowPos default spLeftTop;
    // In the CoolControls package many controls that have 
    // captions or string items allow to paint these with 
    // the 3D effect. When you use this feature, use ShadowPos 
    // to indicate the position (relatively to the main text) 
    // of the shadow dropped. The effect being achieved by
    // painting the text twice - once with the main color and 
    // then with the ShadowColor (allowing ShadowSize offset).
    // Use SimpleView to indicate whether you want to use the 
    // described feature  or you do not.
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   ShadowColor
    property SimpleView: Boolean read FSimpleView write SetSimpleView default False;
    // Determines whether the wallpaper should be stretched to fit into the control's dimensions.
    // Otherwise image will be tiled to cover the control's surface.
    property Stretched: Boolean read FStretched write SetStretched default False;
    // Use Transparent property to specify that the
    // control will be drawn transparently. Similar to the
    // meaning of the ocPaintTransparently flag in the Options
    // property of the most controls.
    property Transparent: Boolean read FTransparent write SetTransparent default False;
    // Use Wallpaper to specify the bitmap image
    // that will be painted as background wallpaper
    // for a control. In most cases CoolControls package
    // requires ocPaintWallpaper flag included into 
    // Options property set in order to actually enable 
    // wallpaper painting. Mind you that there's an 
    // alternative way to attach the image to be painted 
    // on control's background - use CoolImages and idWallpaper 
    // properties for that. This technique allows to save system 
    // resources by sharing the same image between many controls.
    // 
    // See Also:
    //   Options
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
  published   
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
  end;

  // TCoolPopupButton is a button control with attached popup menu that becomes 
  // active when right button is clicked. The similar controls can be found in  
  // Outlook Express and many other modern programs. TCoolPopupButton class publishes TCustomPopupButton's properties.
  TCoolPopupButton = class(TCustomPopupButton)
  private
    FDownMenu: TPopupMenu;
    {$IFNDEF DELPHI4_OR_ABOVE}
    FMenuHelp: THelpContext;
    {$ENDIF}
  protected
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure WndProc(var Message: TMessage); override;
    // Click event for the right button.
    procedure ClickAdd; override;
    procedure Click; override;
  published
    // Use DownMenu property to specify the popup menu that will become active each time button is clicked.
    property DownMenu: TPopupMenu read FDownMenu write FDownMenu;
    // TCustomPopuButton is complex class that contains two buttons. BtnAddSize property 
    // specifies the width of the right button (the one that usually activates popup menu).
    property BtnAddSize;
    // Use CoolImages property to specify  TCoolImages component will be used 
    // to load images for wallpapers from. TcoolImages acts much like 
    // TImageList that is behaves as placeholder for images. It can contain 
    // images only but images of different sizes and color modes can be stored 
    // together in the same object.
    property CoolImages;
    // There's an alternative for direct assigning of 
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties 
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper 
    // indicates the index of the image from CoolImages to be used. 
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   Wallpaper
    property idWallpaper;
    // Use Flat property to indicate when control should be painted in a modern
    // flat way. In such a case button will be activated upon capturing mouse cursor.
    property Flat;
    // If the control or its items can be painted with the 
    // bitmap image (glyph) use this property to specify the bitmap 
    // image to be painted. Painting glyphs may give 
    // your controls more attractive look yet highlight the control's purpose.
    property Glyph;
    // The Layout property defines the layout of a bitmap within 
    // a control. These are the possible values:
    // 
    // <TABLE>
    // Value            Meaning
    // ------------     --------------
    // blGlyphLeft      The image appears on the left side of the text or caption.
    // blGlyphRight     The image appears on the right side of the text or caption.
    // blGlyphTop       The image appears at the top of the text or caption.
    // blGlyphBottom    The image appears at the bottom of the text or caption.
    // </TABLE>
    property Layout;
    // The margin is the space between the image edge and 
    // the control edge. The format of the edges depends on 
    // the layout of the image and text (specified 
    // in the Layout property). For example, if Layout is 
    // blGlyphLeft, the margin appears between the left edge 
    // of the image and the left edge of the control. If 
    // Margin is 3, three pixels separate the image and the 
    // control edges. If Margin is 0, there is no space between 
    // the image and the control edges.
    // 
    // If Margin is -1 (the default value), the image and text 
    // (specified in the Caption property) are centered. The number of 
    // pixels between the image and control edge is equal to the number 
    // of pixels between the opposite edge of the control and the text.
    property Margin;
    // NumGlyphs property indicates the number of images 
    // that are in the graphic specified in the Glyph 
    // property for use on a control.
    // If you have multiple images in a bitmap, you must 
    // specify the number of images that are in 
    // the bitmap with the NumGlyphs property. Valid NumGlyphs 
    // values are 1 to 4. The default value is 1.
    // 
    // See Also:
    //   Glyph
    property NumGlyphs;
    property PopupMenu;
    // Spacing determines the number of pixels between the 
    // image (specified in the Glyph property) and the text 
    // (specified in the Caption property). The default value 
    // is 4 pixels.
    // 
    // If Spacing is a positive number, its value is the number 
    // of pixels between the image and text. If Spacing is 0, no pixels 
    // will be between the image and text. If Spacing is -1, the text 
    // appears centered between the image and the control edge. The number of 
    // pixels between the image and text is equal to the number of pixels between the text and 
    // the control edge opposite the glyph.
    property Spacing;
    // In the CoolControls package many controls that 
    // have captions or string items allow to paint 
    // these with the 3D effect. When you use this feature, 
    // use ShadowColor to set the color of the shadow dropped. 
    // The effect being achieved by painting the text 
    // twice - once with the main color and then with the 
    // ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   SimpleView
    property ShadowColor;
    // In the CoolControls package many controls that have captions 
    // or string items allow to paint these with the 3D effect. 
    // When you use this feature, use ShadowSiize to indicate the 
    // offset  of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and then 
    // with the ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowPos
    //   ShadowColor
    //   SimpleView
    property ShadowSize;
    // In the CoolControls package many controls that have captions or 
    // string items allow to paint these with the 3D effect. When 
    // you use this feature, use ShadowPos to indicate the position 
    // (relatively to the main text) of the shadow dropped. The effect 
    // being achieved by painting the text twice - once with the main 
    // color and then with the ShadowColor (allowing ShadowSize offset).
    // 
    // <TABLE>
    // Value 			Meaning
    // -----------		----------
    // spLeftTop		Shadow is in the Left Top direction.
    // spLeftBottom		Shadow is in the Left Bottom direction.
    // spRightBottom 		Shadow is in the Right Bottom direction.
    // spRightTop		Shadow is in the Right Top direction.
    // </TABLE>
    // 
    // See Also:
    //   ShadowSize
    //   ShadowColor
    //   SimpleView
    property ShadowPos;
    // In the CoolControls package many controls that have 
    // captions or string items allow to paint these with 
    // the 3D effect. When you use this feature, use ShadowPos 
    // to indicate the position (relatively to the main text) 
    // of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and 
    // then with the ShadowColor (allowing ShadowSize offset).
    // Use SimpleView to indicate whether you want to use the 
    // described feature  or you do not.
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   ShadowColor
    property SimpleView;
    // Use Transparent property to specify that the
    // control will be drawn transparently. Similar to the
    // meaning of the ocPaintTransparently flag in the Options
    // property of the most controls.
    property Transparent;
    // Use Wallpaper to specify the bitmap image 
    // that will be painted as background wallpaper 
    // for a control. In most cases CoolControls package 
    // requires ocPaintWallpaper flag included into 
    // Options property set in order to actually enable 
    // wallpaper painting. Mind you that there's an 
    // alternative way to attach the image to be painted 
    // on control's background - use CoolImages and idWallpaper 
    // properties for that. This technique allows to save system 
    // resources by sharing the same image between many controls.
    // 
    // See Also:
    //   Options
    //   idWallpaper
    //   CoolImages
    property Wallpaper;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Action;
    property Anchors;
    property BiDiMode;
    {$ENDIF}
    property Caption;
    property Color;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Constraints;
    {$ENDIF}
    property Enabled;
    property Font;
    property ParentColor;
    property ParentFont;
    property ParentShowHint;
    {$IFDEF DELPHI4_OR_ABOVE}
    property ParentBiDiMode;
    {$ENDIF}
    property ShowHint;
    property Visible;
    property OnClick;
    property OnDblClick;
    property OnMouseDown;
    property OnMouseUp;
    property OnMouseMove;
  end;

  // TCoolListBoxEx is inner class that works together with the TCoolPopupBox
  TCoolListBoxEx = class(TCoolListBox)
  private
    CanClose: Boolean;
    procedure WMMouseActivate(var Message: TWMMouseActivate); message WM_MOUSEACTIVATE;
    procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
  protected
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyUp(var Key: Word; Shift: TShiftState); override;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure Click; override;
  end;

  // TCoolPopupBox component is a control similar to TCoolPopupButton except 
  // for that instead of popup menu it has attached listbox control (like 
  // combobox) which becomes active when right button is clicked.
  TCoolPopupBox = class(TCustomPopupButton)
  private
    FListBox: TCoolListBoxEx;
    FMouseAction: Boolean;
    FPrevMessage: TMessageEvent;
    FOnChange: TNotifyEvent;

    function GetItems: TStrings;
    procedure SetItems(Value: TStrings);

    function GetItemIndex: Integer;
    procedure SetItemIndex(Value: Integer);

    procedure AppMessage(var Msg: TMsg; var Handled: Boolean);
    function IsCloseMsg(var Msg: TMsg): Boolean;
    procedure Change(Sender: TObject);

    procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
    procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
    procedure CMColorChanged(var Message: TMessage); message CM_COLORCHANGED;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  protected
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    // Click event for the right button.
    procedure ClickAdd; override;
    procedure Click; override;
  public
    // Use ItemIndex to set/obtain active item of the listbox part of the control.
    //
    // See Also:
    //   Items
    property ItemIndex: Integer read GetItemIndex write SetItemIndex;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    // Use Items to specify items of the listbox part of the control
    //
    // See Also:
    //   ItemIndex
    property Items: TStrings read GetItems write SetItems;
    // Event occurs when currently active item is changed.
    //
    // See Also:
    //   ItemIndex
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
    // TCustomPopuButton is complex class that contains two buttons. BtnAddSize property 
    // specifies the width of the right button (the one that usually activates popup menu).
    property BtnAddSize;
    // Use CoolImages property to specify  TCoolImages component will be used 
    // to load images for wallpapers from. TcoolImages acts much like 
    // TImageList that is behaves as placeholder for images. It can contain
    // images only but images of different sizes and color modes can be stored 
    // together in the same object.
    property CoolImages;
    // There's an alternative for direct assigning of 
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties 
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper 
    // indicates the index of the image from CoolImages to be used. 
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    //
    // See Also:
    //   Options
    //   CoolImages
    //   Wallpaper
    property idWallpaper;
    // Use Flat property to indicate when control should be painted in a modern
    // flat way. In such a case button will be activated upon capturing mouse cursor.
    property Flat;
    // If the control or its items can be painted with the 
    // bitmap image (glyph) use this property to specify the bitmap 
    // image to be painted. Painting glyphs may give 
    // your controls more attractive look yet highlight the control's purpose.
    property Glyph;
    // The Layout property defines the layout of a bitmap within 
    // a control. These are the possible values:
    // 
    // <TABLE>
    // Value            Meaning
    // ------------     --------------
    // blGlyphLeft      The image appears on the left side of the text or caption.
    // blGlyphRight     The image appears on the right side of the text or caption.
    // blGlyphTop       The image appears at the top of the text or caption.
    // blGlyphBottom    The image appears at the bottom of the text or caption.
    // </TABLE>
    property Layout;
    // The margin is the space between the image edge and 
    // the control edge. The format of the edges depends on 
    // the layout of the image and text (specified 
    // in the Layout property). For example, if Layout is 
    // blGlyphLeft, the margin appears between the left edge 
    // of the image and the left edge of the control. If 
    // Margin is 3, three pixels separate the image and the 
    // control edges. If Margin is 0, there is no space between 
    // the image and the control edges.
    // 
    // If Margin is -1 (the default value), the image and text
    // (specified in the Caption property) are centered. The number of 
    // pixels between the image and control edge is equal to the number 
    // of pixels between the opposite edge of the control and the text.
    property Margin;
    // NumGlyphs property indicates the number of images 
    // that are in the graphic specified in the Glyph
    // property for use on a control.
    // If you have multiple images in a bitmap, you must 
    // specify the number of images that are in 
    // the bitmap with the NumGlyphs property. Valid NumGlyphs 
    // values are 1 to 4. The default value is 1.
    // 
    // See Also:
    //   Glyph
    property NumGlyphs;
    property PopupMenu;
    // Spacing determines the number of pixels between the 
    // image (specified in the Glyph property) and the text
    // (specified in the Caption property). The default value 
    // is 4 pixels.
    // 
    // If Spacing is a positive number, its value is the number
    // of pixels between the image and text. If Spacing is 0, no pixels 
    // will be between the image and text. If Spacing is -1, the text
    // appears centered between the image and the control edge. The number of 
    // pixels between the image and text is equal to the number of pixels between the text and 
    // the control edge opposite the glyph.
    property Spacing;
    // In the CoolControls package many controls that 
    // have captions or string items allow to paint 
    // these with the 3D effect. When you use this feature, 
    // use ShadowColor to set the color of the shadow dropped. 
    // The effect being achieved by painting the text 
    // twice - once with the main color and then with the 
    // ShadowColor (allowing ShadowSize offset).
    //
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   SimpleView
    property ShadowColor;
    // In the CoolControls package many controls that have captions
    // or string items allow to paint these with the 3D effect. 
    // When you use this feature, use ShadowSiize to indicate the 
    // offset  of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and then 
    // with the ShadowColor (allowing ShadowSize offset).
    // 
    // See Also:
    //   ShadowPos
    //   ShadowColor
    //   SimpleView
    property ShadowSize;
    // In the CoolControls package many controls that have captions or
    // string items allow to paint these with the 3D effect. When 
    // you use this feature, use ShadowPos to indicate the position 
    // (relatively to the main text) of the shadow dropped. The effect 
    // being achieved by painting the text twice - once with the main
    // color and then with the ShadowColor (allowing ShadowSize offset).
    //
    // <TABLE>
    // Value 			Meaning
    // -----------		----------
    // spLeftTop		Shadow is in the Left Top direction.
    // spLeftBottom		Shadow is in the Left Bottom direction.
    // spRightBottom 		Shadow is in the Right Bottom direction.
    // spRightTop		Shadow is in the Right Top direction.
    // </TABLE>
    // 
    // See Also:
    //   ShadowSize
    //   ShadowColor
    //   SimpleView
    property ShadowPos;
    // In the CoolControls package many controls that have 
    // captions or string items allow to paint these with
    // the 3D effect. When you use this feature, use ShadowPos 
    // to indicate the position (relatively to the main text)
    // of the shadow dropped. The effect being achieved by 
    // painting the text twice - once with the main color and 
    // then with the ShadowColor (allowing ShadowSize offset).
    // Use SimpleView to indicate whether you want to use the 
    // described feature  or you do not.
    // 
    // See Also:
    //   ShadowSize
    //   ShadowPos
    //   ShadowColor
    property SimpleView;
    // Use Transparent property to specify that the
    // control will be drawn transparently. Similar to the
    // meaning of the ocPaintTransparently flag in the Options
    // property of the most controls.
    property Transparent;
    // Use Wallpaper to specify the bitmap image 
    // that will be painted as background wallpaper 
    // for a control. In most cases CoolControls package 
    // requires ocPaintWallpaper flag included into 
    // Options property set in order to actually enable 
    // wallpaper painting. Mind you that there's an 
    // alternative way to attach the image to be painted 
    // on control's background - use CoolImages and idWallpaper 
    // properties for that. This technique allows to save system 
    // resources by sharing the same image between many controls.
    // 
    // See Also:
    //   Options
    //   idWallpaper
    //   CoolImages
    property Wallpaper;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Action;
    property Anchors;
    property BiDiMode;
    {$ENDIF}
    property Caption;
    property Color;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Constraints;
    {$ENDIF}
    property Enabled;
    property Font;
    property ParentColor;
    property ParentFont;
    property ParentShowHint;
    {$IFDEF DELPHI4_OR_ABOVE}
    property ParentBiDiMode;
    {$ENDIF}
    property ShowHint;
    property Visible;
    property OnClick;
    property OnDblClick;
    property OnMouseDown;
    property OnMouseUp;
    property OnMouseMove;
  end;

  // TCoolPopupButton2 control has the same functionality as TCoolPopupButton. 
  // The only difference is that it was derived from the TCoolBtn (windowed control).
  TCoolPopupButton2 = class(TCoolBtn)
  private
    FDownMenu: TPopupMenu;
    {$IFNDEF DELPHI4_OR_ABOVE}
    FMenuHelp: THelpContext;
    {$ENDIF}
  protected
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure WndProc(var Message: TMessage); override;
  public
    constructor Create(AOwner: TComponent); override;
    procedure Click; override;
  published
    // Use DownMenu property to specify the popup menu that will become active each time button is clicked.
    property DownMenu: TPopupMenu read FDownMenu write FDownMenu;
  end;

  // TCoolPopupBox2 control has the same functionality as TCoolPopupBox.
  // The only difference is that it was derived from TCoolBtn (windowed control).
  TCoolPopupBox2 = class(TCoolBtn)
  private
    FListBox: TCoolListBoxEx;
    FPrevMessage: TMessageEvent;
    FOnChange: TNotifyEvent;

    function GetItems: TStrings;
    procedure SetItems(Value: TStrings);

    function GetItemIndex: Integer;
    procedure SetItemIndex(Value: Integer);

    procedure AppMessage(var Msg: TMsg; var Handled: Boolean);
    function IsCloseMsg(var Msg: TMsg): Boolean;
    procedure Change(Sender: TObject);
  protected
    procedure Loaded; override;
  public
    // Use ItemIndex to set/obtain active item of the listbox part of the control.
    //
    // See Also:
    //   Items
    property ItemIndex: Integer read GetItemIndex write SetItemIndex;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Click; override;
  published
    // Use Items to specify items of the listbox part of the control
    //
    // See Also:
    //   ItemIndex
    property Items: TStrings read GetItems write SetItems;
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
  end;

  {$IFNDEF VER90}
  // TCoolSpeedButton is advanced TSpeedButton  component  being used with 
  // TCoolButtonPanel component.
  TCoolSpeedButton = class(TSpeedButton)
  private
    FAboutBox: TCCAboutBox;
    FDowned: Boolean;
    FBkColor: TColor;
    {$IFDEF BL}
    FData: string;
    {$ENDIF}
    {$IFNDEF DELPHI4_OR_ABOVE}
    FTransparent: Boolean;
    {$ENDIF}
    FOnMouseEnter,
    FOnMouseLeave: TNotifyEvent;
    {$IFNDEF DELPHI4_OR_ABOVE}
    procedure SetTransparent(Value: Boolean);
    {$ENDIF}
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  protected
    HasMouse: Boolean;
    procedure Paint; override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure ReadState(Reader: TReader); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    // Run-time and read-only. Read to determine whether button is in down state.
    property Downed: Boolean read FDowned;
    // Run-time and read-only. Returns \color of the parent component.
    property BkColor: TColor read FBkColor default clBtnShadow;
  published   
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    {$IFNDEF DELPHI4_OR_ABOVE}
    // Use Transparent property to specify that the
    // control will be drawn transparently. Similar to the
    // meaning of the ocPaintTransparently flag in the Options
    // property of the most controls.
    property Transparent: Boolean read FTransparent write SetTransparent default True;
    {$ENDIF}
    {$IFDEF BL}
    property Data: string read FData write FData;
    {$ENDIF}
    // OnMouseEnter event occurs immediately after mouse cursor enters the control.
    property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
    // OnMouseLeave event occurs immediately after mouse cursor leaves the control.
    property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  end;

  // TCoolPanel is an advanced panel control. Allows to use wallpapers, supports transparency and other
  // enhancements.
  TCoolPanel = class(TCustomPanel)
  private
    FWallpaper: TBitmap;
    FTransparent: Boolean;
    FTransparencyLevel: Byte;
    FAboutBox: TCCAboutBox;
    FStretched: Boolean;

    FCoolImages: TCoolImages;
    FidWallpaper: Integer;
    FCoolImagesChangeLink: TCoolChangeLink;

    FInactiveFontColor: TColor;

    function GetWallpaper: TBitmap;
    procedure SetWallpaper(Value: TBitmap);
    procedure SetTransparent(Value: Boolean);
    procedure SetTransparencyLevel(Value: Byte);
    procedure WallpaperChanged(Sender: TObject);

    procedure SetStretched(Value: Boolean);

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    function CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
    procedure CoolImagesChange(Sender: TObject);

    procedure SetInactiveFontColor(Value: TColor);

    procedure CMParentColorChanged(var Message: TMessage); message CM_PARENTCOLORCHANGED;
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
  protected
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure Loaded; override;
    procedure Paint; override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    {$IFDEF DELPHI4_OR_ABOVE}
    property DockManager;
    {$ENDIF}
  published   
    // Displays information about the control and package version.
    property About: TCCAboutBox read FAboutBox write FAboutBox;
    // Use CoolImages property to specify  TCoolImages component will be used 
    // to load images for wallpapers from. TcoolImages acts much like
    // TImageList that is behaves as placeholder for images. It can contain 
    // images only but images of different sizes and color modes can be stored 
    // together in the same object.
    property CoolImages: TCoolImages read FCoolImages write SetCoolImages;
    // There's an alternative for direct assigning of 
    // the Wallpaper property for cases when you want 
    // to paint the image background for the 
    // control - use CoolImages and idWallpaper properties 
    // for that. This technique allows to save system resources 
    // by sharing the same image between many controls. IdWallpaper
    // indicates the index of the image from CoolImages to be used. 
    // For controls that have Options property it's necessary to 
    // include ocPaintWallpaper flag (Options property) to enable 
    // the wallpaper painting.
    // 
    // See Also:
    //   Options
    //   CoolImages
    //   Wallpaper
    property idWallpaper: Integer read FidWallpaper write SetidWallpaper default -1;
    // Color to be used for the font when the button is inactive (has no mouse).
    property InactiveFontColor: TColor read FInactiveFontColor write SetInactiveFontColor default clWhite;
    // Determines whether the wallpaper should be stretched to fit into the control's dimensions.
    // Otherwise image will be tiled to cover the control's surface.
    property Stretched: Boolean read FStretched write SetStretched default False;
    // Use Wallpaper to specify the bitmap image
    // that will be painted as background wallpaper
    // for a control. In most cases CoolControls package
    // requires ocPaintWallpaper flag included into
    // Options property set in order to actually enable
    // wallpaper painting. Mind you that there's an
    // alternative way to attach the image to be painted
    // on control's background - use CoolImages and idWallpaper
    // properties for that. This technique allows to save system
    // resources by sharing the same image between many controls.
    //
    // See Also:
    //   Options
    //   idWallpaper
    //   CoolImages
    property Wallpaper: TBitmap read GetWallpaper write SetWallpaper;
    // Use Transparent property to specify that the
    // control will be drawn transparently. Similar to the
    // meaning of the ocPaintTransparently flag in the Options
    // property of the most controls.
    property Transparent: Boolean read FTransparent write SetTransparent default False;
    // Use TransparencyLevel to specify the
    // parent control whose part will be used
    // to draw the background of the component.
    // For example if control placed on the panel
    // that is placed on the form, setting TransparencyLevel
    // to 0 will force part of the panel to be used for
    // painting of the transparent background, setting
    // TransparencyLevel to 1 will force the part of the
    // form to be selected on the controls device context
    // when paint transparently.
    property TransparencyLevel: Byte read FTransparencyLevel write SetTransparencyLevel default 0;
    property Align;
    property Alignment;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Anchors;
    property AutoSize;
    {$ENDIF}
    // Use BevelInner to specify whether the inner bevel has a raised, lowered, or flat look. 
    // 
    // The inner bevel appears immediately inside the outer bevel. If there is no outer bevel (BevelOuter is bvNone), the inner bevel appears immediately inside the border.
    property BevelInner;
    // Use BevelOuter to specify whether the outer bevel has a raised, lowered, or flat look. The outer bevel appears immediately inside the border and outside the inner bevel.
    property BevelOuter;
    property BevelWidth;
    {$IFDEF DELPHI4_OR_ABOVE}
    property BiDiMode;
    {$ENDIF}
    property BorderWidth;
    property BorderStyle;
    property Caption;
    property Color default clBtnShadow;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Constraints;
    {$ENDIF}
    property Ctl3D;
    {$IFDEF DELPHI4_OR_ABOVE}
    property UseDockManager default True;
    property DockSite;
    {$ENDIF}
    property DragCursor;
    {$IFDEF DELPHI4_OR_ABOVE}
    property DragKind;
    {$ENDIF}
    property DragMode;
    property Enabled;
    property FullRepaint;
    property Font;
    property Locked;
    {$IFDEF DELPHI4_OR_ABOVE}
    property ParentBiDiMode;
    {$ENDIF}
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Visible;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnCanResize;
    {$ENDIF}
    property OnClick;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnConstrainedResize;
    property OnDockDrop;
    property OnDockOver;
    {$ENDIF}
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnEndDock;
    {$ENDIF}
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnGetSiteInfo;
    {$ENDIF}
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnResize;
    property OnStartDrag;
    {$IFDEF DELPHI4_OR_ABOVE}
    property OnStartDock;
    property OnUnDock;
    {$ENDIF}
  end;

  //  TCoolButtonPanel is advanced panel/toolbar component, similar to 
  // one that can be found in Microsoft Outlook Express.
  TCoolButtonPanel = class(TCoolPanel)
  private
    FButtonWidth: Integer;
    FButtonHeight: Integer;
    FButtons: TList;
    FScrollUpBtn,
    FScrollDownBtn: TSpeedButton;
    FOnScrollDown,
    FOnScrollUp: TNotifyEvent;

    function GetButton(Index: Integer): TCoolSpeedButton;
    function GetButtonCount: Integer;
    procedure SetButtonWidth(Value: Integer);
    procedure SetButtonHeight(Value: Integer);
    procedure ScrollUp(Sender: TObject);
    procedure ScrollDown(Sender: TObject);

    procedure CMButtonDestroyed(var Message: TMessage); message CM_BUTTONDESTROYED;
    procedure CMButtonMouseUp(var Message: TMessage); message CM_BUTTONMOUSEUP;
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
    procedure CMMouseCaptureChange(var Message: TMessage); message CM_MOUSECAPTURECHANGE;
  protected
    procedure Paint; override;
    procedure Resize; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    // Creates, initializes and adds TCoolSpeedButton instance.
    //
    // Result: created TCoolSpeedbutton control.
    function CreateButton: TCoolSpeedButton;
    // Adjusts buttons in control's bounds.
    procedure ReorderButtons;
    // Used to scroll the contents of the panel.
    //
    // Parameters:
    //   DeltaX - Pixels to scroll horizontally.
    //   DeltaY - Pixels to scroll vertically.
    //   R      - Rectangle that bounds the scrolling region.
    procedure ScrollByEx(DeltaX, DeltaY: Integer; R: TRect);
    // Read-only. The TCoolButtonPanel enables user to have the panel with the series of the speed buttons that can be scrolled up 
    // and down. Use Buttons property to address the particular button.
    property Buttons[Index: Integer]: TCoolSpeedButton read GetButton;
    // Read-only. The TCoolButtonPanel enables user to have the panel with the series of the speed buttons that can be scrolled up 
    // and down. Use ButtonsCount to obtain the number of buttons currently added to the control.
    property ButtonsCount: Integer read GetButtonCount;
    {$IFDEF DELPHI4_OR_ABOVE}
    property DockManager;
    {$ENDIF}
  published
    // The TCoolButtonPanel enables user to have the panel with the series of the speed buttons that can be scrolled up 
    // and down. Use ButtonHeight to set the width of such a button (all and every buttons have the same height).
    property ButtonHeight: Integer read FButtonHeight write SetButtonHeight default 64;
    // The TCoolButtonPanel enables user to have the panel with the series of the speed buttons that can be scrolled up 
    // and down. Use ButtonWidth to set the width of such a button (all and every buttons have the same width).
    property ButtonWidth: Integer read FButtonWidth write SetButtonWidth default 64;
    // Use BevelOuter to specify whether the outer bevel has a raised, lowered, or flat look. The outer bevel appears immediately inside the border and outside the inner bevel.
    property BevelOuter default bvLowered;
    property Color default clBtnShadow;
    {$IFDEF DELPHI4_OR_ABOVE}
    property UseDockManager default True;
    {$ENDIF}
    // Event fires when the panel is being scrolled down.
    property OnScrollDown: TNotifyEvent read FOnScrollDown write FOnScrollDown;
    // Event fires when the panel is being scrolled up.
    property OnScrollUp: TNotifyEvent read FOnScrollUp write FOnScrollUp;
  end;
  {$ENDIF}

{$IFNDEF VER90}
const
  // Advanced paintitng modes.
  //
  CopyModes: array[0..14] of TIdentMapEntry = (
    (Value: cmBlackness; Name: 'cmBlackness'),
    (Value: cmDstInvert; Name: 'cmDstInvert'),
    (Value: cmMergeCopy; Name: 'cmMergeCopy'),
    (Value: cmMergePaint; Name: 'cmMergePaint'),
    (Value: cmNotSrcCopy; Name: 'cmNotSrcCopy'),
    (Value: cmNotSrcErase; Name: 'cmNotSrcErase'),
    (Value: cmPatCopy; Name: 'cmPatCopy'),
    (Value: cmPatInvert; Name: 'cmPatInvert'),
    (Value: cmPatPaint; Name: 'cmPatPaint'),
    (Value: cmSrcAnd; Name: 'cmSrcAnd'),
    (Value: cmSrcCopy; Name: 'cmSrcCopy'),
    (Value: cmSrcErase; Name: 'cmSrcErase'),
    (Value: cmSrcInvert; Name: 'cmSrcInvert'),
    (Value: cmSrcPaint; Name: 'cmSrcPaint'),
    (Value: cmWhiteness; Name: 'cmWhiteness'));
{$ENDIF}

// Checks control and determines whether it's a member of the CoolControls package.
//
// Parameters:
//   Obj - Any control or component you would like to perform check for.
// Result:
//   Boolean value that indicates whether particular component is from CoolControls package.
function IsCoolControl(const Obj: TObject): Boolean;
// Draws flat "smoth" border around the control.
//
// Parameters:
//   DC        - Handle of the device context painting occurs on.
//   Control   - Control that we will paint borders for.
//   InCtrl    - There are different techniques for control capturing and not capturing the cursor.
procedure DrawFlatBorder(DC: HDC; Control: TWinControl; InCtrl: Boolean);
// Draws borders of selected color, and other params around the control.
//
// Parameters:
//   DC        - Handle of the device context painting occurs on.
//   Control   - Control that we will paint borders for.
//   Borders   - What borders should be painted.
//   Pen       - Pen object to paint borders with.
//   Bkcolor   - Non specified borders can be drawn transparently (BkColor=clNone) or with the color BkColor.
procedure DrawBorders(DC: HDC; Control: TWinControl; Borders: TEdgeBorders; Pen: TPen; BkColor: TColor);
{$IFNDEF VER90}
procedure GetCopyModeValues(Proc: TGetStrProc);
{$ENDIF}

implementation

{$R CoolCtrls.res}

{$IFNDEF Registered}
uses
  CoolAboutUnit;
{$ENDIF}

const
  OFFSET         =   4;
  LIGHT_OFFSET   =   2;
  GRADIENT_BANDS = 128;
  SCROLL_COUNT   =   1;

  WS_EX_LAYERED  = $00080000;
  LWA_COLORKEY   = $00000001;
  LWA_ALPHA      = $00000002;
  ULW_COLORKEY   = $00000001;
  ULW_ALPHA      = $00000002;
  ULW_OPAQUE     = $00000004;
  AC_SRC_ALPHA   = $1;

  Colors: array [0..15] of TColor = (
    clBlack,
    clMaroon,
    clGreen,
    clOlive,
    clNavy,
    clPurple,
    clTeal,
    clGray,
    clSilver,
    clRed,
    clLime,
    clYellow,
    clBlue,
    clFuchsia,
    clAqua,
    clWhite);

type
  TCheckWrapper = class(TCollectionItem)
   private
    FData: LongInt;
    FState: TCheckBoxState;
    FLocked: Boolean;
    procedure SetChecked(Check: Boolean);
    function GetChecked: Boolean;
  public
    class function GetDefaultState: TCheckBoxState;
    // Use Checked property to specify and retrieve current
    // state of the control.
    // This property can be used with the State property and 
    // is somewhat faster.
    property Checked: Boolean read GetChecked write SetChecked;
    property State: TCheckBoxState read FState write FState;
    property Locked: Boolean read FLocked write FLocked default False;
  end;

  {TCellWrapper}
  TCellWrapper = class(TObject)
  private
    FFont: TFont;
    FColor: TColor;
    FCol, FRow: Integer;
    FReadOnlyCell: Boolean;
    FWallpaperForCell: Boolean;
    FCellTextAlign: TAlignment;
    procedure SetFont(Value: TFont);
  public
    constructor Create(ACol, ARow: Integer; AGrid: TStringGrid); virtual;
    destructor Destroy; override;
    property Color: TColor read FColor write FColor;
    property ReadOnlyCell: Boolean read FReadOnlyCell write FReadOnlyCell;
    property WallpaperForCell: Boolean read FWallpaperForCell write FWallpaperForCell;
    property Font: TFont read FFont write SetFont;
    property CellTextAlign: TAlignment read FCellTextAlign write FCellTextAlign;
    property Col: Integer read FCol write FCol;
    property Row: Integer read FRow write FRow;
  end;

function IsCoolControl(const Obj: TObject): Boolean;
begin
  Result := Pos('Cool', Obj.ClassName) <> 0;
end;

procedure DrawFlatBorder(DC: HDC; Control: TWinControl; InCtrl: Boolean);
var
  R: TRect;
  BtnBrush,
  WndBrush: HBRUSH;
  ScrollStyle: TScrollStyle;
  ClearDCNeeded: Boolean;
begin
  with Control do
  begin
    ClearDCNeeded := False;
    if DC = 0 then
    begin
      DC := GetWindowDC(Handle);
      ClearDCNeeded := True;
    end;

    try
      GetWindowRect(Handle, R);
      OffsetRect(R, -R.Left, -R.Top);

      BtnBrush := GetSysColorBrush(COLOR_BTNFACE);
      WndBrush := GetSysColorBrush(COLOR_WINDOW);

      FrameRect(DC, R, BtnBrush);
      InflateRect (R, -1, -1);
      FrameRect(DC, R, BtnBrush);

      if InCtrl then
      begin
        InflateRect (R, 1, 1);
        DrawEdge(DC, R, BDR_SUNKENOUTER, BF_RECT or BF_ADJUST);
      end;

      if not ((Control is TCoolListBox) or (Control is TCoolMemo) or (Control is TCustomGrid)) then
        InflateRect(R, -1, -1) else
        begin
          ScrollStyle := ssNone;

          if GetWindowLong(Control.Handle, GWL_STYLE) and WS_VSCROLL <> 0 then
          begin
            ScrollStyle := ssVertical;
            FillRect(DC, Rect(R.Right - GetSystemMetrics(SM_CYHSCROLL), Pred(Pred(R.Bottom)), R.Right, Pred(R.Bottom)), BtnBrush);
          end;

          if GetWindowLong(Control.Handle, GWL_STYLE) and WS_HSCROLL <> 0 then
          begin
            if ScrollStyle = ssNone then
              ScrollStyle := ssHorizontal else
                ScrollStyle := ssBoth;

            FillRect(DC, Rect(Pred(Pred(R.Right)), R.Bottom - GetSystemMetrics(SM_CYHSCROLL), Pred(R.Right), R.Bottom), BtnBrush);
          end;

          case ScrollStyle of
            ssNone:
              InflateRect(R, -1, -1);
            ssBoth:
              InflateRectEx(R, 0, 0, -1, -1);
            ssHorizontal:
              InflateRectEx(R, 0, 0, 0, -1);
            ssVertical:
              InflateRectEx(R, 0, 0, -1, 0);
          end;
        end;

      if not (Control is TCustomGrid) then
        FrameRect(DC, R, WndBrush);

    finally
      if ClearDCNeeded then
        ReleaseDC(Handle, DC);
    end;
  end;
end;

procedure DrawBorders(DC: HDC; Control: TWinControl; Borders: TEdgeBorders; Pen: TPen; BkColor: TColor);
var
  R: TRect;
  Canvas: TCanvas;
  ClearDCNeeded: Boolean;
begin
  if Borders <> [] then
    with Control do
    begin
      ClearDCNeeded := False;
      if DC = 0 then
      begin
        DC := GetWindowDC(Handle);
        ClearDCNeeded := True;
      end;

      GetWindowRect(Handle, R);
      OffsetRect(R, -R.Left, -R.Top);

      Canvas := TCanvas.Create;
      try
        Canvas.Handle := DC;

        if BkColor <> clNone then
        begin
          //Make it transparent
          Canvas.Pen.Color := BkColor;
          Canvas.Pen.Width := 2;
          //Top
          Canvas.MoveTo(R.Left, R.Top+1);
          Canvas.LineTo(R.Right, R.Top+1);
          //Left
          Canvas.MoveTo(R.Left+1, R.Top);
          Canvas.LineTo(R.Left+1, R.Bottom);
          //Right
          Canvas.MoveTo(R.Right-1, R.Top);
          Canvas.LineTo(R.Right-1, R.Bottom);
          //Bottom
          Canvas.MoveTo(R.Left, R.Bottom-1);
          Canvas.LineTo(R.Right, R.Bottom-1);
        end;

        if (ebTop in Borders) then
        begin
          Canvas.Pen.Assign(Pen);
          Canvas.MoveTo(R.Left, R.Top+1);
          Canvas.LineTo(R.Right, R.Top+1);
        end;

        if (ebLeft in Borders) then
        begin
          Canvas.Pen.Assign(Pen);
          Canvas.MoveTo(R.Left+1, R.Top);
          Canvas.LineTo(R.Left+1, R.Bottom);
        end;

        if (ebRight in Borders) then
        begin
          Canvas.Pen.Assign(Pen);
          Canvas.MoveTo(R.Right-1, R.Top);
          Canvas.LineTo(R.Right-1, R.Bottom);
        end;

        if (ebBottom in Borders) then
        begin
          Canvas.Pen.Assign(Pen);
          Canvas.MoveTo(R.Left, R.Bottom-1);
          Canvas.LineTo(R.Right, R.Bottom-1);
        end;
      finally
        Canvas.Free;
      end;

      if ClearDCNeeded then
        ReleaseDC(Handle, DC);
    end;
end;

type
  THackedGraphicControl = class(TGraphicControl);

procedure DrawBorders2(Control: TGraphicControl; Borders: TEdgeBorders; Pen: TPen);
var
  R: TRect;
begin
  THackedGraphicControl(Control).Canvas.Pen.Assign(Pen);
  with Control, THackedGraphicControl(Control).Canvas do
  begin
    R := ClientRect;

    if (ebTop in Borders) then
    begin
      MoveTo(R.Left, R.Top+1);
      LineTo(R.Right, R.Top+1);
    end;

    if (ebLeft in Borders) then
    begin
      MoveTo(R.Left+1, R.Top);
      LineTo(R.Left+1, R.Bottom);
    end;

    if (ebRight in Borders) then
    begin
      MoveTo(R.Right-1, R.Top);
      LineTo(R.Right-1, R.Bottom);
    end;

    if (ebBottom in Borders) then
    begin
      MoveTo(R.Left, R.Bottom-1);
      LineTo(R.Right, R.Bottom-1);
    end;
  end;
end;

{$IFNDEF VER90}
procedure GetCopyModeValues(Proc: TGetStrProc);
var
  I: Integer;
begin
  for I := Low(CopyModes) to High(CopyModes) do
    Proc(CopyModes[I].Name);
end;
{$ENDIF}

{TCheckWrapper}
procedure TCheckWrapper.SetChecked(Check: Boolean);
begin
  if not FLocked then
    if Check then FState := cbChecked else FState := cbUnchecked;
end;

function TCheckWrapper.GetChecked: Boolean;
begin
  Result := FState = cbChecked;
end;

class function TCheckWrapper.GetDefaultState: TCheckBoxState;
begin
  Result := cbUnchecked;
end;

{TCoolChangeLink}
destructor TCoolChangeLink.Destroy;
begin
  if Sender <> nil then Sender.UnRegisterChanges(Self);
  inherited Destroy;
end;

procedure TCoolChangeLink.Change;
begin
  if Assigned(OnChange) then OnChange(Sender);
end;

{TImageItem}
constructor TImageItem.Create(Collection: TCollection);
begin
  inherited;
  FBitmap := TBitmap.Create;
  FPicture := TPicture.Create; // by Starenko
  FPicture.OnChange := OnChange; // by Starenko
end;

destructor TImageItem.Destroy;
begin
  OnChange(Self);
  FPicture.OnChange := nil;
  FPicture.Free;
  FBitmap.Free;
  inherited;
end;

function TImageItem.GetBitmap: TBitmap;
begin
  Result := FBitmap;
end;

procedure TImageItem.Assign(Source: TPersistent);
begin
   if (Source is TImageItem) then
     FPicture := TImageItem(Source).FPicture;

  inherited Assign(Source);
end;

procedure TImageItem.SetPicture(Value: TPicture);
begin
  // Convert any format in FPicture to Bitmap
  FPicture.Assign(Value);
end;
// by Starenko end

procedure TImageItem.OnChange(Sender: TObject);
begin
  FBitmap.Assign(FPicture.Graphic);
  TImages(Collection).FCoolImages.Change;
end;

{TImages}
constructor TImages.Create(CoolImages: TCoolImages);
begin
  inherited Create(TImageItem);
  FCoolImages := CoolImages;
end;

function TImages.GetItem(Index: Integer): TImageItem;
begin
  Result := TImageItem(inherited GetItem(Index));
end;

procedure TImages.SetItem(Index: Integer; Value: TImageItem);
begin
  inherited SetItem(Index, Value);
end;

{$IFNDEF VER90}
function TImages.GetOwner: TPersistent;
begin
  Result := FCoolImages;
end;
{$ENDIF}

procedure TImages.Update(Item: TCollectionItem);
begin
  inherited Update(Item);
end;

function TImages.Add: TImageItem;
begin
  Result := TImageItem(inherited Add);
end;

{TCoolImages}
constructor TCoolImages.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FImages := TImages.Create(Self);
  FClients := TList.Create;
end;

destructor TCoolImages.Destroy;
begin
  while FClients.Count > 0 do
    UnRegisterChanges(TCoolChangeLink(FClients.Last));
  FClients.Free;
  FClients := nil;

  FImages.Free;
  inherited Destroy;
end;

procedure TCoolImages.RegisterChanges(Value: TCoolChangeLink);
begin
  Value.Sender := Self;
  if FClients <> nil then FClients.Add(Value);
end;

procedure TCoolImages.UnRegisterChanges(Value: TCoolChangeLink);
var
  I: Integer;
begin
  if FClients <> nil then
    for I := 0 to FClients.Count - 1 do
      if FClients[I] = Value then
      begin
        Value.Sender := nil;
        FClients.Delete(I);
        Break;
      end;
end;

procedure TCoolImages.Change;
var
  I: Integer;
begin
  if FClients <> nil then
    for I := 0 to FClients.Count - 1 do
      TCoolChangeLink(FClients[I]).Change;
end;

{TCoolListBox}
constructor TCoolListBox.Create(AOwner: TComponent);
begin
  FGlyph := TGlyph.Create;
  TGlyph(FGlyph).SimpleCaption := True;
  TGlyph(FGlyph).OnChange := GlyphChanged;
  inherited Create(AOwner);
  Style := lbOwnerDrawFixed;
  FImageChangeLink := TChangeLink.Create;
  FImageChangeLink.OnChange := ImageListChange;
  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;
  FSelColor := clHighlight;
  FSelFont := TFont.Create;
  FSelFont.Color := clHighlightText;
  FSelFont.OnChange := SelFontChange;
  FCaptionColor := clInactiveCaption;
  FCaptionTextColor := clInactiveCaptionText;

  FBevelInner := bvNone;
  FBevelOuter := bvNone;
  FBevelStyle := bsBevelBoth;

  FShadowColor := clBtnHighlight;
  FShadowSize := 1;
  FShadowPos := spLeftTop;
  FSimpleView := False;

  FBorderPen := TPen.Create;
  FBorderPen.OnChange := BorderPenChange;
  FEdgeBorders := [];
  FBordersTrColor := clNone;
  FOptions := [ocNoCaption, ocBevelOnlyIfSel];
  FFlatCheckBox := False;
  FExtendedStyle := ctCoolControl;
  FExtendedCheck := False;
  FHotTray := False;
  FTrueType := False;
  FWrappers := TCollection.Create(TCheckWrapper);
  ControlStyle := ControlStyle + [csSetCaption] - [csOpaque];
  FMaxWidth := 0;
  FLightColorControl := True;
  FFontValue := TFont.Create;
  FFontValue.OnChange := FontValueChanged;
  FFontAutoUpdate := False;
  FFolderName := '';
  FFileType := [ftDirectory, ftArchive];
  FFileMask := '*.*' ;
  FidWallpaper := -1;
  FidCaptionWallpaper := -1;
  FidSelWallpaper := -1;
  FTransparencyLevel := 0;
end;

destructor TCoolListBox.Destroy;
begin
  if Assigned(FWallpaper) then FWallPaper.Free;
  if Assigned(FSelWallPaper) then FSelWallPaper.Free;
  if Assigned(FCaptionWallPaper) then FCaptionWallPaper.Free;
  FImageChangeLink.Free;
  FCoolImagesChangeLink.Free;
  FSelFont.Free;
  FWrappers.Free;
  FSaveStates.Free;
  FFontValue.Free;
  FBorderPen.Free;
  inherited Destroy;
  TGlyph(FGlyph).Free;
end;

procedure TCoolListBox.SetGlyph(Value: TBitmap);
begin
  TGlyph(FGlyph).Glyph := Value;
  Invalidate;
end;

function TCoolListBox.GetGlyph: TBitmap;
begin
  Result := TGlyph(FGlyph).Glyph;
end;

procedure TCoolListBox.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  FWallPaper.Assign(Value);
  Invalidate;
end;

function TCoolListBox.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolListBox.SetSelWallpaper(Value: TBitmap);
begin
  if FSelWallpaper = nil then FSelWallpaper := TBitmap.Create;
  FSelWallPaper.Assign(Value);
  Invalidate;
end;

function TCoolListBox.GetSelWallpaper: TBitmap;
begin
  if FSelWallpaper = nil then FSelWallpaper := TBitmap.Create;
  Result := FSelWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolListBox.SetCaptionWallpaper(Value: TBitmap);
begin
  if FCaptionWallpaper = nil then FCaptionWallpaper := TBitmap.Create;
  FCaptionWallPaper.Assign(Value);
  NCCtlChanged;
end;

function TCoolListBox.GetCaptionWallpaper: TBitmap;
begin
  if FCaptionWallpaper = nil then FCaptionWallpaper := TBitmap.Create;
  Result := FCaptionWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolListBox.SetOptions(Value: TCoolOptions);
begin
  if FOptions <> Value then
  begin
    if (ocPaintTransparently in Value) and (ocPaintWallpaper in FOptions) then
      Exclude(Value, ocPaintWallpaper) else
        if (ocPaintWallpaper in Value) and (ocPaintTransparently in FOptions) then
          Exclude(Value, ocPaintTransparently);

    FOptions := Value;
    RecreateWnd;
    Perform(CM_COLORCHANGED, 0, 0);
  end;
end;

procedure TCoolListBox.SetImages(Value: TImageList);
begin
  if Assigned(Images) then
    Images.UnRegisterChanges(FImageChangeLink);

  FImages := Value;

  if Assigned(Images) then
    Images.RegisterChanges(FImageChangeLink);

  Invalidate;
end;

procedure TCoolListBox.SetShadowColor(Value: TColor);
begin
  if FShadowColor <> Value then
  begin
    FShadowColor := Value;
    FSimpleView := False;
    Repaint;
  end;
end;

procedure TCoolListBox.SetShadowSize(Value: Byte);
begin
  if FShadowSize <> Value then
  begin
    FShadowSize := Value;
    FSimpleView := False;
    Repaint;
  end;
end;

procedure TCoolListBox.SetShadowPos(Value: TShadowPosition);
begin
  if FShadowPos <> Value then
  begin
    FShadowPos := Value;
    FSimpleView := False;
    Repaint;
  end;
end;

procedure TCoolListBox.SetSimpleView(Value: Boolean);
begin
  if FSimpleView <> Value then
  begin
    FSimpleView := Value;
    Repaint;
  end;
end;

procedure TCoolListBox.SetBevelInner(Value: TPanelBevel);
begin
  if FBevelInner <> Value then
  begin
    FBevelInner := Value;
    Invalidate;
  end;
end;

procedure TCoolListBox.SetBevelOuter(Value: TPanelBevel);
begin
  if FBevelOuter <> Value then
  begin
    FBevelOuter := Value;
    Invalidate;
  end;
end;

procedure TCoolListBox.SetBevelStyleEx(Value: TBevelStyleEx);
begin
  if FBevelStyle <> Value then
  begin
    FBevelStyle := Value;
    Invalidate;
  end;
end;

procedure TCoolListBox.BorderPenChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolListBox.SetEdgeBorders(Value: TEdgeBorders);
begin
  if FEdgeBorders <> Value then
  begin
    FEdgeBorders := Value;
    Invalidate;
  end;
end;

procedure TCoolListBox.SetBorderPen(Value: TPen);
begin
  FBorderPen.Assign(Value);
end;

procedure TCoolListBox.SetBordersTrColor(Value: TColor);
begin
  if FBordersTrColor <> Value then
  begin
    FBordersTrColor := Value;
    Invalidate;
  end;
end;

procedure TCoolListBox.SetCaptionColor(Value: TColor);
begin
  if FCaptionColor <> Value then
  begin
    FCaptionColor := Value;
    NCCtlChanged;
  end;
end;

procedure TCoolListBox.SetCaptionTextColor(Value: TColor);
begin
  if FCaptionTextColor <> Value then
  begin
    FCaptionTextColor := Value;
    NCCtlChanged;
  end;
end;

procedure TCoolListBox.SetSelFont(Value: TFont);
begin
  FSelFont.Assign(Value);
  Invalidate;
end;

procedure TCoolListBox.SetColorValue(Value: TColor);
var
  I: Integer;
begin
  if (FExtendedStyle = ctColorControl) then
    for I := 0 to Items.Count-1 do
      if ColorToString(Value) = MakeColorStr(Items[I]) then
      begin
        FColorValue := Value;
        ItemIndex := I;
        Break;
      end else
      begin
        ItemIndex := -1;
        FColorValue := -1;
      end;
end;

procedure TCoolListBox.SetExtendedStyle(Value: TCoolControlStyle);
begin
  if FExtendedStyle <> Value then
  begin
    FExtendedStyle := Value;

    case FExtendedStyle of
      ctColorControl:
        CreateColorListBox;
      ctFontControl:
        CreateFontListBox;
      ctPrinterControl:
        CreatePrinterListBox;
      ctFolderControl:
        CreateFolderListBox;
      ctCheckControl:
        ExtendedCheck := False;
    end;

    Invalidate;
  end;
end;

procedure TCoolListBox.SetExtendedCheck(Value: Boolean);
begin
  if FExtendedStyle = ctCheckControl then
    Value := False;

  if FExtendedCheck <> Value then
  begin
    FExtendedCheck := Value;
    Invalidate;
  end;
end;

procedure TCoolListBox.SetTrueType(Value: Boolean);
begin
  if FTrueType <> Value then
  begin
    Clear;
    FTrueType := Value;

    if (FExtendedStyle = ctFontControl) then
      CreateFontListBox;
  end;
end;

procedure TCoolListBox.SetFontAutoUpdate(Value: Boolean);
begin
  if FFontAutoUpdate <> Value then
  begin
    FFontAutoUpdate := Value;
    Invalidate;
  end;
end;

function TCoolListBox.GetChecked(Index: Integer): Boolean;
begin
  if HaveWrapper(Index) then
    Result := TCheckWrapper(GetWrapper(Index)).GetChecked
  else
    Result := False;
end;

procedure TCoolListBox.SetChecked(Index: Integer; Value: Boolean);
begin
  if Value <> GetChecked(Index) then
  begin
    TCheckWrapper(GetWrapper(Index)).Checked := Value;
    InvalidateCheck(Index);
  end;
end;

function TCoolListBox.GetState(Index: Integer): TCheckBoxState;
begin
  if HaveWrapper(Index) then
    Result := TCheckWrapper(GetWrapper(Index)).State
  else
    Result := TCheckWrapper.GetDefaultState;
end;

procedure TCoolListBox.SetState(Index: Integer; Value: TCheckBoxState);
begin
  if Value <> GetState(Index) then
  begin
    TCheckWrapper(GetWrapper(Index)).State := Value;
    InvalidateCheck(Index);
  end;
end;

function TCoolListBox.GetLocked(Index: Integer): Boolean;
begin
  if HaveWrapper(Index) then
    Result := TCheckWrapper(GetWrapper(Index)).Locked
  else
    Result := False;
end;

procedure TCoolListBox.SetLocked(Index: Integer; Value: Boolean);
begin
  if Value <> GetLocked(Index) then
    TCheckWrapper(GetWrapper(Index)).Locked := Value;
end;

procedure TCoolListBox.SetFlatCheckBox(Value: Boolean);
begin
  if FFlatCheckBox <> Value then
  begin
    FFlatCheckBox := Value;
    Invalidate;
  end;
end;

procedure TCoolListBox.SetLightColorControl(Value: Boolean);
begin
  if FLightColorControl <> Value then
  begin
    FLightColorControl := Value;
    if FExtendedStyle = ctColorControl then
      CreateColorListBox;
  end;
end;

procedure TCoolListBox.SetFontValue(Value: TFont);
begin
  FFontValue.Assign(Value);
  ItemIndex := Items.IndexOf(FFontValue.Name);
end;

function TCoolListBox.GetFontValue: TFont;
var
  Save: TNotifyEvent;
begin
  Save := FFontValue.OnChange;
  FFontValue.OnChange := nil;

  if ItemIndex <> -1 then
    FFontValue.Name := Items[ItemIndex];

  FFontValue.OnChange := Save;

  Result := FFontValue;
end;

procedure TCoolListBox.FontValueChanged(Sender: TObject);
begin
end;

procedure TCoolListBox.SetFolderName;
begin
  if FFolderName <> Value then
  begin
    FFolderName := Value;

    if FFolderName <> '' then
      if FFolderName[Length(FFolderName)] <> '\' then
        FFolderName := FFolderName + '\';

    if Pos('..', FFolderName) <> 0 then
      FFolderName := GetParentFolder(Copy(FFolderName, 0, Pred(Pos('..', FFolderName))));

    if FExtendedStyle = ctFolderControl then
      CreateFolderListBox;
  end;
end;

procedure TCoolListBox.SetFileType(Value: TFileType);
begin
  if FFileType <> Value then
  begin
    FFileType := Value;

    if FExtendedStyle = ctFolderControl then
      CreateFolderListBox;
  end;
end;

procedure TCoolListBox.SetFileMask(Value: string);
begin
  if FFileMask <> Value then
  begin
    FFileMask := Value;

    if FExtendedStyle = ctFolderControl then
      CreateFolderListBox;
  end;
end;

procedure TCoolListBox.CreateColorListBox;
var
  I: Integer;
  Proc: TGetStrProc;
begin
  Items.BeginUpdate;
  Clear;

  if FLightColorControl then
  begin
    for I := Low(Colors) to High(Colors) do
      Items.Add(ColorToString(Colors[I]));
  end else
  begin
    Proc := Items.Append;
    GetColorValues(Proc);
  end;

  Items.EndUpdate;
end;

function TCoolListBox.MakeColorStr(Value: string): string;
begin
  try
    StringToColor(Value);
    Result := Value;
  except
    Result := 'cl' + Value;
    Application.HandleException(Self);  
  end;
end;

procedure TCoolListBox.WallpaperChanged(Sender: TObject);
begin
  Invalidate;
  Perform(CM_COLORCHANGED, 0, 0);
end;

procedure TCoolListBox.ImageListChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolListBox.SelFontChange(Sender: TObject);
begin
  ParentFont := False;
end;

procedure TCoolListBox.CoolImagesChange(Sender: TObject);
begin
  NCCtlChanged;
  Invalidate;
end;

procedure TCoolListBox.GlyphChanged(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolListBox.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolListBox.SetidCaptionWallpaper(Value: Integer);
begin
  if FidCaptionWallpaper <> Value then
  begin
    FidCaptionWallpaper := Value;
    NCCtlChanged;
  end;
end;

procedure TCoolListBox.SetidSelWallpaper(Value: Integer);
begin
  if FidSelWallpaper <> Value then
  begin
    FidSelWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolListBox.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  Invalidate;
  NCCtlChanged;
end;

function TCoolListBox.CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaper(DC, FWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

function TCoolListBox.IsWallpaperAssigned: Boolean;
begin
  Result := (Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty) or
            (Assigned(FWallpaper) and not FWallpaper.Empty);
end;

function TCoolListBox.IsSelWallpaperAssigned: Boolean;
begin
  Result := (Assigned(FCoolImages) and (FidSelWallpaper >= 0) and (FidSelWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidSelWallpaper].Bitmap) and not FCoolImages.Images.Items[FidSelWallpaper].Bitmap.Empty) or
            (Assigned(FSelWallpaper) and not FSelWallpaper.Empty);
end;

function TCoolListBox.CTLDrawWallpaperEx(DC: HDC; R, SubRect: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaperEx(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, SubRect, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaperEx(DC, FWallpaper, R, SubRect, IsStretch, Mode);
    Result := True;
  end;
end;

function TCoolListBox.CTLDrawCaptionWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidCaptionWallpaper >= 0) and (FidCaptionWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidCaptionWallpaper].Bitmap) and not FCoolImages.Images.Items[FidCaptionWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidCaptionWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FCaptionWallpaper) and not FCaptionWallpaper.Empty then
  begin
    DrawWallpaper(DC, FCaptionWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

function TCoolListBox.CTLDrawSelWallpaperEx(DC: HDC; R, SubRect: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidSelWallpaper >= 0) and (FidSelWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidSelWallpaper].Bitmap) and not FCoolImages.Images.Items[FidSelWallpaper].Bitmap.Empty then
  begin
    DrawWallpaperEx(DC, FCoolImages.Images.Items[FidSelWallpaper].Bitmap, R, SubRect, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FSelWallpaper) and not FSelWallpaper.Empty then
  begin
    DrawWallpaperEx(DC, FSelWallpaper, R, SubRect, IsStretch, Mode);
    Result := True;
  end;
end;

procedure TCoolListBox.CreateFontListBox;
var
  I: Integer;
begin
  Items.BeginUpdate;
  Clear;
  if not FTrueType then
    Items.Assign(Screen.Fonts) else
      for I := 0 to Screen.Fonts.Count-1 do
        if CheckTTFont(Screen.Fonts[I]) then
          Items.Add(Screen.Fonts[I]);
  Items.EndUpdate;
end;

procedure TCoolListBox.CreateFolderListBox;

  procedure BuildFromList(AList: TStringList);
  begin
    Items.Assign(AList);
  end;

const
   Attributes: array[TFileAttr] of Word = (SysUtils.faReadOnly, SysUtils.faHidden, SysUtils.faSysFile,
                                           SysUtils.faVolumeID, SysUtils.faDirectory, SysUtils.faArchive, SysUtils.faAnyFile);
var
  FileList: TStringList;
  Attr: Integer;
  AttrIndex: TFileAttr;
begin
  if FFolderName <> '' then
  begin
    Items.BeginUpdate;
    try
      Clear;

      Attr := 0;
      for AttrIndex := ftReadOnly to ftNormal do
        if AttrIndex in FileType then
          Attr := Attr or Attributes[AttrIndex];

      FileList := GetFileDirList(FFolderName, FFileMask, Attr);
      try
        BuildFromList(FileList);
      finally
        FileList.Free;
      end;

    finally
      Items.EndUpdate;
    end;
  end;
end;

procedure TCoolListBox.CreatePrinterListBox;
var
  I: Integer;
begin
  Items.BeginUpdate;
  Clear;
  for I := 0 to Printer.Printers.Count-1 do
    Items.Add(Printer.Printers[I]);
  Items.EndUpdate;
end;

procedure TCoolListBox.InvalidateCheck(Index: Integer);
var
  R: TRect;
begin
  R := ItemRect(Index);

  {$IFDEF DELPHI4_OR_ABOVE}
  if (DrawTextBiDiModeFlags(0) and DT_RIGHT) = DT_RIGHT then
    R.Left := R.Right - SuccEx(ItemHeight, 2);
    R.Right := R.Left + SuccEx(ItemHeight, 2);
  {$ELSE}
  R.Right := R.Left + SuccEx(ItemHeight, 2);
  {$ENDIF}

  InvalidateRect(Handle, @R, not (csOpaque in ControlStyle));
end;

procedure TCoolListBox.NCCtlChanged;
begin
  if HandleAllocated then
    SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_DRAWFRAME or SWP_NOACTIVATE or SWP_NOMOVE or
                                        SWP_NOSIZE or SWP_NOZORDER);
end;

function TCoolListBox.GetWrapper(Index: Integer): TObject;
begin
  Result := ExtractWrapper(Index);
  if Result = nil then
    Result := CreateWrapper(Index);
end;

function TCoolListBox.ExtractWrapper(Index: Integer): TObject;
begin
  {$IFNDEF VER90}
  Result := TCheckWrapper(inherited GetItemData(Index));
  {$ELSE}
  Result := TCheckWrapper(SendMessage(Handle, LB_GETITEMDATA, Index, 0));
  {$ENDIF}
  if LB_ERR = Integer(Result) then
    raise Exception.Create('Unable to obtain data');

  if (Result <> nil) and (not (Result is TCheckWrapper)) then
    Result := nil;
end;

function TCoolListBox.CreateWrapper(Index: Integer): TObject;
begin
  Result := TCheckWrapper.Create(FWrappers);
  {$IFNDEF VER90}
  inherited SetItemData(Index, LongInt(Result));
  {$ELSE}
  SendMessage(Handle, LB_SETITEMDATA, Index, LongInt(Result));
  {$ENDIF}
end;

function TCoolListBox.HaveWrapper(Index: Integer): Boolean;
begin
  Result := ExtractWrapper(Index) <> nil;
end;

function TCoolListBox.RealWidth(ItemStr: string): Integer;
begin
  Canvas.Font.Assign(FSelFont);
  Result := Canvas.TextWidth(ItemStr);

  Canvas.Font.Assign(Font);

  if Canvas.TextWidth(ItemStr) > Result then
    Result := Canvas.TextWidth(ItemStr);

  Result := Result + Glyph.Width;
end;

function TCoolListBox.MaxWidth: Integer;
var
  I: Integer;
begin
  Result := 0;

  if Items.Count > 0 then
  begin
    for I := 0 to Items.Count-1 do
      if Length(Items[I]) > Length(Items[Result]) then
        Result := I;

    Result := RealWidth(Items[Result]);
  end;
end;

procedure TCoolListBox.SetTransparencyLevel(Value: Byte);
begin
  if FTransparencyLevel <> Value then
  begin
    FTransparencyLevel := Value;
    Invalidate;
  end;
end;

procedure TCoolListBox.CreateWnd;
begin
  inherited CreateWnd;
  if (FExtendedStyle = ctCheckControl) or FExtendedCheck then
    if FSaveStates <> nil then
    begin
      FSaveStates.Free;
      FSaveStates := nil;
    end;
end;

procedure TCoolListBox.Loaded;
begin
  inherited Loaded;
  if FExtendedStyle <> ctColorControl then
    case FExtendedStyle of
      ctColorControl:
        CreateColorListBox;
      ctFontControl:
        CreateFontListBox;
      ctPrinterControl:
        CreatePrinterListBox;
      ctFolderControl:
        CreateFolderListBox;
    end;
end;

procedure TCoolListBox.DestroyWnd;
var
  I: Integer;
begin
  if (FExtendedStyle = ctCheckControl) or FExtendedCheck then
    if Items.Count > 0 then
    begin
      FSaveStates := TList.Create;
      for I := 0 to Items.Count-1 do
        FSaveStates.Add(TObject(State[I]));
    end;

  inherited DestroyWnd;
  FWrappers.Clear;
end;

{$IFNDEF VER90}
procedure TCoolListBox.ResetContent;
var
  I: Integer;
begin
  if (FExtendedStyle = ctCheckControl) or FExtendedCheck then
    for I := 0 to Items.Count - 1 do
      if HaveWrapper(I) then
        GetWrapper(I).Free;
  inherited;
end;

procedure TCoolListBox.DeleteString(Index: Integer);
begin
  if (FExtendedStyle = ctCheckControl) or FExtendedCheck then
    if HaveWrapper(Index) then
      GetWrapper(Index).Free;
  inherited;
end;
{$ENDIF}

procedure TCoolListBox.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FImages) and (AComponent = FImages) then
  begin
    FImages := nil;
    Invalidate;
  end;
  if (Operation = opRemove) and Assigned(FCoolImages) and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

procedure TCoolListBox.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);

  with Params do
  begin
    if not (ocNoCaption in FOptions) then
      Style := Style or WS_CAPTION else
        Style := Style and not WS_CAPTION;

    if Columns = 0 then
      Style := Style or WS_HSCROLL;

    if ocSmallCaption in FOptions then
      ExStyle := ExStyle or WS_EX_TOOLWINDOW else
        ExStyle := ExStyle and not WS_EX_TOOLWINDOW;
  end;
end;

procedure TCoolListBox.SetParent(AParent: TWinControl);
begin
  inherited SetParent(AParent);
end;

procedure TCoolListBox.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  R: TRect;
  Index: Integer;
begin
  inherited MouseDown(Button, Shift, X, Y);
  if (FExtendedStyle = ctCheckControl) or FExtendedCheck then
  begin
    for Index := 0 to Items.Count-1 do
    begin
      {$IFDEF DELPHI4_OR_ABOVE}
      if (DrawTextBiDiModeFlags(0) and DT_RIGHT) = DT_RIGHT then
        R := Rect(ItemRect(Index).Right - SuccEx(ItemHeight, 2), ItemRect(Index).Top, ItemRect(Index).Right, ItemRect(Index).Bottom) else
        R := Rect(ItemRect(Index).Left, ItemRect(Index).Top, ItemRect(Index).Left + SuccEx(ItemHeight, 2), ItemRect(Index).Bottom);
      {$ELSE}
      R := Rect(ItemRect(Index).Left, ItemRect(Index).Top, ItemRect(Index).Left + SuccEx(ItemHeight, 2), ItemRect(Index).Bottom);
      {$ENDIF}

      if PtInRect(R, Point(X, Y)) then
      begin
        Checked[Index] := not Checked[Index];
        InvalidateCheck(Index);
        Break;
      end;
    end;
  end;
end;

procedure TCoolListBox.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
  inherited MouseMove(Shift, X, Y);
  if FHotTray then
    ItemIndex := ItemAtPos(Point(X, Y), False);
end;

procedure TCoolListBox.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited KeyDown(Key, Shift);
  if (FExtendedStyle = ctCheckControl) or FExtendedCheck then
    if (Key = VK_SPACE) and (ItemIndex <> -1) then
    begin
      Checked[ItemIndex] := not Checked[ItemIndex];
      InvalidateCheck(ItemIndex);
    end;

  if (FExtendedStyle = ctColorControl) then
    if (Key = VK_RETURN) and (Shift = [ssCtrl]) then
      with TColorDialog.Create(Self) do
      try
        Color := ColorValue;
        if Execute then
        begin
          ColorValue := Color;
          if ItemIndex = -1 then
          begin
            Items.Add(ColorToString(Color));
            ColorValue := Color;
          end;
        end;
      finally
        Free;
      end;

  if (FExtendedStyle = ctFontControl) then
    if (Key = VK_RETURN) and (Shift = [ssCtrl]) then
     with TFontDialog.Create(Self) do
     try
       Font := FontValue;

       if Execute then
       begin
         FontValue := Font;

         if Assigned(Self.OnClick) then
           Self.OnClick(Self);
       end;
     finally
       Free;
     end;
end;

procedure TCoolListBox.SetItemData(Index: Integer; AData: LongInt);
var
  Wrapper: TCheckWrapper;
begin
  {$IFNDEF VER90}
  inherited SetItemData(Index, AData);
  {$ELSE}
  SendMessage(Handle, LB_SETITEMDATA, Index, AData);
  {$ENDIF}
  if (FExtendedStyle = ctCheckControl) or FExtendedCheck then
  begin
    Wrapper := TCheckWrapper(GetWrapper(Index));
    Wrapper.FData := AData;

    if FSaveStates <> nil then
      if FSaveStates.Count > 0 then
      begin
        Wrapper.FState := TCheckBoxState(FSaveStates[0]);
        FSaveStates.Delete(0);
      end;
  end;
end;

function TCoolListBox.GetItemData(Index: Integer): LongInt;
begin
  {$IFNDEF VER90}
  Result := inherited GetItemData(Index);
  {$ELSE}
  Result := SendMessage(Handle, LB_GETITEMDATA, Index, 0);
  {$ENDIF}
  if (FExtendedStyle = ctCheckControl) or FExtendedCheck then
  begin
    Result := 0;
    if HaveWrapper(Index) then
      Result := TCheckWrapper(GetWrapper(Index)).FData;
  end;
end;

procedure TCoolListBox.WMDestroy(var Message: TMessage);
begin
  inherited;
end;

procedure TCoolListBox.CNCommand(var Message: TWMCommand);
begin
   if Message.NotifyCode = LBN_SELCHANGE then
      if (FExtendedStyle = ctColorControl) and (ItemIndex <> -1) then
        FColorValue := StringToColor(MakeColorStr(Items[ItemIndex]));

  inherited;
end;

procedure TCoolListBox.LBGetTopIndex(var Message: TMessage);
const
  IndexTop: Integer = 0;
begin
  inherited;
  if (IndexTop <> Message.Result) and (((ocPaintWallpaper in FOptions) and IsWallpaperAssigned) or (ocPaintTransparently in FOptions)) then
  begin
    InvalidateRectEx(Handle, ClientRect, False);
    IndexTop := Message.Result;
  end;
end;

procedure TCoolListBox.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
  if (ocPaintTransparently in FOptions) then
    PaintBackground(TrControl(Self, FTransparencyLevel), Message.DC, True) else
      if (ocPaintWallpaper in FOptions) and IsWallpaperAssigned and (Items.Count > 0) then
        CTLDrawWallpaper(Message.DC, ClientRect, (ocStretchWallpaper in FOptions), SRCCOPY) else
          inherited;
end;

procedure TCoolListBox.WMPaint(var Message: TWMPaint);
var
  DC: HDC;
begin
  if not (( (ocPaintWallpaper in FOptions) and IsWallpaperAssigned ) or (ocPaintTransparently in FOptions) ) then
    inherited else
      begin
        Perform(LB_GETTOPINDEX, 0, 0);
        inherited;
        if Items.Count = 0 then
        begin
          DC := GetDC(Handle);
          try
            if ocPaintTransparently in FOptions then
              PaintBackground(TrControl(Self, FTransparencyLevel), DC, True) else
                CTLDrawWallpaper(DC, ClientRect, (ocStretchWallpaper in FOptions), SRCCOPY);
          finally
            ReleaseDC(Handle, DC);
          end;
        end;
      end;

  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, Focused);

  DrawBorders(0, Self, FEdgeBorders, FBorderPen, FBordersTrColor);
end;

procedure TCoolListBox.WMNCPaint(var Message: TMessage);
var
  WR, R: TRect;
  MyDC: HDC;
  MyRgn: HRGN;
  OldFont, MyFont: HFONT;
  MyBrush: HBRUSH;
  DeleteRgn: Boolean;
  NCM: TNonClientMetrics;
begin
  inherited;
  if not (ocNoCaption in FOptions) and ( (FCaptionColor <> clInactiveCaption) or (FCaptionTextColor <> clInactiveCaptionText) or (ocPaintCaptionWallpaper in FOptions) ) then
  begin
    DeleteRgn := FALSE;
    MyRgn := Message.wParam;

    MyDC := GetWindowDC(Handle);
    try
      GetWindowRect(Handle, WR);

      if SelectClipRgn(MyDC, MyRgn) = ERROR then
        with WR do
        begin
          MyRgn := CreateRectRgn(Left, Top, Right, Bottom);
          SelectClipRgn(MyDC, MyRgn);
          DeleteRgn := TRUE;
        end;

      OffsetClipRgn(MyDC, -WR.Left, -WR.Top);
      GetWindowRect(Handle, R);
      OffsetRect(R, -R.Left, -R.Top);
      InflateRect(R, -GetSystemMetrics(SM_CXFIXEDFRAME),  -GetSystemMetrics(SM_CYFIXEDFRAME));
      if (ocSmallCaption in FOptions) then
        R.Bottom := R.Top + GetSystemMetrics(SM_CYSMCAPTION)-1 else
          R.Bottom := R.Top + GetSystemMetrics(SM_CYCAPTION)-1;

      MyBrush := CreateSolidBrush(ColorToRGB(FCaptionColor));
      try
        if not (ocPaintCaptionWallpaper in FOptions) then
          FillRect(MyDC, R, MyBrush) else
            CTLDrawCaptionWallpaper(MyDC, R, True, SRCCOPY);

        NCM.cbSize := SizeOf(NCM);
        SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @NCM, 0);
        if (ocSmallCaption in FOptions) then
          MyFont := CreateFontIndirect(NCM.lfSmCaptionFont) else
            MyFont := CreateFontIndirect(NCM.lfCaptionFont);
        try
          OldFont := SelectObject(MyDC, MyFont);
          try
            OffsetRect(R, 2, 0);
            try
              SetTextColor(MyDC, ColorToRGB(FCaptionTextColor));
              SetBkMode(MyDC, Transparent);
              DrawText(MyDC, PChar(Caption), -1, R, DT_LEFT or DT_VCENTER or DT_SINGLELINE);
            finally
              OffsetRect(R, -2, 0);
            end;
          finally
            SelectObject(MyDC, OldFont);
          end;
        finally
          DeleteObject(MyFont);
        end;
      finally
        DeleteObject(MyBrush);
      end;

      ExcludeClipRect(MyDC, R.Left, R.Top, R.Right, R.Bottom);
      OffsetClipRgn(MyDC, WR.Left, WR.Top);
      GetClipRgn(MyDC, MyRgn);
      Message.Result := DefWindowProc(Handle, Message.Msg, MyRgn, Message.lParam);

    finally
      if DeleteRgn then DeleteObject(MyRgn);
      ReleaseDC(Handle, MyDC);
    end;
  end;
end;

procedure TCoolListBox.CNCtlColorListBox(var Message: TWMCtlColorListBox);
begin
  inherited;
end;

procedure TCoolListBox.CMMouseEnter (var Message: TMessage);
begin
  inherited;
  if (ocFlatBorder in FOptions) and not IsCoolControl(Screen.ActiveControl) then
    DrawFlatBorder(0, Self, True);

  if Assigned(FOnMouseEnter) then
    FOnMouseEnter(Self);
end;

procedure TCoolListBox.CMMouseLeave (var Message: TMessage);
begin
  inherited;
  if (ocFlatBorder in FOptions) and not IsCoolControl(Screen.ActiveControl) then
    DrawFlatBorder(0, Self, False);

  if Assigned(FOnMouseLeave) then
    FOnMouseLeave(Self);
end;

procedure TCoolListBox.WMSetFocus(var Message: TWMSetFocus);
begin
  inherited;
  if (Items.Count = 0) then
    InvalidateRectEx(Handle, ItemRect(0), False);

  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, True);
end;

procedure TCoolListBox.WMKillFocus(var Message: TWMKillFocus);
begin
  inherited;
  if (Items.Count = 0) then
    InvalidateRectEx(Handle, ItemRect(0), False);

  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, False);
end;

procedure TCoolListBox.WMNCLButtonDblClk(var Message: TWMNCLButtonDblClk);
begin
  if Message.HitTest = Windows.htCaption then
    Message.HitTest := Windows.htNoWhere else
      inherited;
end;

procedure TCoolListBox.WMNCHitTest(var Message: TWMNCHitTest);
begin
  inherited;
  if (Message.Result = Windows.htCaption) and (ocNoDragUsingCaption in FOptions) then
    Message.Result := Windows.htNowhere;
end;

procedure TCoolListBox.CMParentFontChanged(var Message: TMessage);
begin
  inherited;
  if ParentFont then
  begin
    FSelFont.OnChange := nil;
    try
      if Message.wParam <> 0 then
        FSelFont.Assign(TFont(Message.lParam)) else
        FSelFont.Assign(Font);

      FSelFont.Color := clHighlightText;
    finally
      FSelFont.OnChange := SelFontChange;
    end;
  end;
end;

procedure TCoolListBox.WMFontChanged(var Message: TMessage);
begin
  inherited;
end;

procedure TCoolListBox.CMEnabledChanged(var Message: TMessage);
begin
  inherited;
  if csDesigning in ComponentState then
    Invalidate;
end;

procedure TCoolListBox.LBAddString(var Message: TMessage);
var
  RW: Integer;
begin
  inherited;
  RW :=  RealWidth(PChar(Message.lParam));
  if (RW > FMaxWidth) and (RW > Width) then
  begin
    FMaxWidth := RW;
    Perform(LB_SETHORIZONTALEXTENT, FMaxWidth, 0);
  end;
end;

procedure TCoolListBox.LBInsertString(var Message: TMessage);
var
  RW: Integer;
begin
  inherited;
  RW :=  RealWidth(PChar(Message.lParam));
  if (RW > FMaxWidth) and (RW > Width) then
  begin
    FMaxWidth := RW;
    Perform(LB_SETHORIZONTALEXTENT, FMaxWidth, 0);
  end;
end;

procedure TCoolListBox.LBDeleteString(var Message: TMessage);
begin
  inherited;
  FMaxWidth := MaxWidth;
  Perform(LB_SETHORIZONTALEXTENT, FMaxWidth, 0);
end;

procedure TCoolListBox.LBResetContent(var Message: TMessage);
begin
  inherited;
  FMaxWidth := MaxWidth;
  Perform(LB_SETHORIZONTALEXTENT, FMaxWidth, 0);
end;

procedure TCoolListBox.CMParentColorChanged(var Message: TMessage);
begin
  inherited;
  if ocPaintTransparently in FOptions then
    Invalidate;
end;

procedure TCoolListBox.WMMove(var Message: TWMMove);
begin
  inherited;
  Invalidate;
end;

procedure TCoolListBox.WMSetText(var Message: TMessage);
begin
  inherited;
  NCCtlChanged;
end;

procedure TCoolListBox.MeasureItem(Index: Integer; var Height: Integer);
begin
  inherited MeasureItem(Index, Height);
end;

function TCoolListBox.GetNumGlyphs: TNumGlyphs;
begin
  Result := TGlyph(FGlyph).NumGlyphs;
end;

procedure TCoolListBox.SetNumGlyphs(Value: TNumGlyphs);
begin
  if Value < 0 then Value := 1 else
      if Value > 2 then Value := 2;

  if Value <> TGlyph(FGlyph).NumGlyphs then
  begin
    TGlyph(FGlyph).NumGlyphs := Value;
    Invalidate;
  end;
end;

procedure TCoolListBox.DrawItem(Index: Integer; Recty: TRect; State: StdCtrls.TOwnerDrawState);

  procedure CreateColorBitmap(const ABitmap: TBitmap; AColor, ABkColor: TColor);
  var
    TempBitmap: TBitmap;
  begin
    TempBitmap := TBitmap.Create;

    with TempBitmap, TempBitmap.Canvas do
    try
      Width := ItemHeight;
      Height := ItemHeight;

      if ColorToRGB(ABkColor) = ColorToRGB(AColor) then
        ABkColor := Pred(ABkColor);

      Brush.Color := ABkColor;
      FillRect(Rect(0, 0, Width, Height));

      Pen.Color := clBlack;
      Brush.Color := AColor;
      Rectangle(0, LIGHT_OFFSET, Width, Height - LIGHT_OFFSET);
    finally
      ABitmap.Assign(TempBitmap);
      TempBitmap.Free;
    end;
  end;

  procedure CreateCheckBitmap(const ABitmap: TBitmap; AState: TCheckBoxState; AFlat: Boolean);
  var
    TempBitmap: TBitmap;
    Mode: Integer;
  begin
    TempBitmap := TBitmap.Create;

    with TempBitmap, TempBitmap.Canvas do
    try
      Width := ItemHeight;
      Height := ItemHeight;

      Brush.Color := clOlive;
      FillRect(Rect(0, 0, ItemHeight, ItemHeight));

      case AState of
        cbChecked:
          Mode := DFCS_BUTTONCHECK or DFCS_CHECKED;
        cbUnchecked:
          Mode := DFCS_BUTTONCHECK;
        else
          Mode := DFCS_BUTTON3STATE or DFCS_CHECKED;
      end;

      if AFlat then
        Mode := Mode or DFCS_FLAT;

      DrawFrameControl(Handle, Rect(1, 1, Pred(ItemHeight), Pred(ItemHeight)), DFC_BUTTON, Mode);
    finally
      ABitmap.Assign(TempBitmap);
      TempBitmap.Free;
    end;
  end;

  procedure CreateFolderFileBitmap(const ABitmap: TBitmap; AFileName: TFileName);
  var
    Info: TShFileInfo;
    TempBitmap: TBitmap;
  begin
    if Pos('..', AFileName) = 0 then
    begin
      TempBitmap := TBitmap.Create;

      with TempBitmap, TempBitmap.Canvas do
      try
        Width := ItemHeight;
        Height := ItemHeight;

        Brush.Color := clOlive;
        FillRect(Rect(0, 0, Width, Height));

        ShGetFileInfo(PChar(AFileName), 0, Info, SizeOf(TShFileInfo), SHGFI_ICON or SHGFI_SMALLICON);
        DrawIconEx(Handle, 0, 0, Info.hIcon, Width, Height, 0, 0, DI_NORMAL);
        {$IFNDEF VER90}
        TransparentColor := clOlive;
        {$ENDIF}
      finally
        ABitmap.Assign(TempBitmap);
        TempBitmap.Free;
      end;
    end;
  end;

const
{$IFNDEF DELPHI4_OR_ABOVE}
  FInnerEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER);
  FOuterEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER);
{$ELSE}
  FInnerEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER, 0);
  FOuterEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER, 0);
{$ENDIF}
  FFontResNames: array[Boolean] of string = ('BITMAP_NTT', 'BITMAP_TT');
var
  R: TRect;
  AGlyph: TGlyph;
  GlAss: Integer; // by Starenko
  ColorText, ColorBack: LongInt;
begin
  DrawBorders(0, Self, FEdgeBorders, FBorderPen, FBordersTrColor);

  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, True);

  if Assigned(OnDrawItem) then
    OnDrawItem(Self, Index, Recty, State) else
    with Canvas do
    begin
      // Initialize!
      ColorText := GetTextColor(Handle);
      ColorBack := GetBkColor(Handle);

      // Here we paint wallpaper and background!
      // **************************************
      if (State = [odSelected, odFocused]) or (State = [odSelected]) then
      begin
        Font.Assign(FSelFont);
        Brush.Color := FSelColor;
        if (ocInvertWallpaperAsSelect in FOptions) and IsWallpaperAssigned then
        begin
          CTLDrawWallpaperEx(Handle, ClientRect, Recty, (ocStretchWallpaper in FOptions), NOTSRCCOPY);
        end else
        if (ocPaintSelWallpaper in FOptions) and IsSelWallpaperAssigned then
        begin
          CTLDrawSelWallpaperEx(Handle, ClientRect, Recty, True, SRCCOPY);
        end else
        begin
          FillRect(Recty);
        end;
      end else
      if (ocPaintWallpaper in FOptions) and IsWallpaperAssigned then
        CTLDrawWallpaperEx(Handle, ClientRect, Recty, (ocStretchWallpaper in FOptions), SRCCOPY) else
        begin
          if not (ocPaintTransparently in FOptions) then
          begin
            Brush.Color := Color;
            FillRect(Recty);
          end else
          begin
            PaintBackgroundEx(TrControl(Self, FTransparencyLevel), Handle, Recty, True);
          end;
        end;

        // Here we paint image text and bevels!
        // ********************
        AGlyph := TGlyph.Create;
        try
          AGlyph.SimpleCaption := True;
          R := Recty;

          if FExtendedCheck then
          begin
            CreateCheckBitmap(AGlyph.Glyph, GetState(Index), FFlatCheckBox);
            AGlyph.DrawImageEx(Canvas, R, Point(0, 0), Items[Index], blGlyphLeft, OFFSET, OFFSET, Enabled, True, clNone, {$IFDEF DELPHI4_OR_ABOVE}DrawTextBiDiModeFlags(0){$ELSE}0{$ENDIF});
            InflateRect(R, -(AGlyph.Glyph.Width + OFFSET), 0);
            AGlyph.Glyph.Assign(nil);
          end;

          case FExtendedStyle of
            ctCoolControl:
              if (ocUseImageList in FOptions) and Assigned(FImages) then
                begin
                  FImages.GetBitmap(Index, AGlyph.Glyph);
                  {$ifndef ver90}
                  AGlyph.Glyph.PixelFormat := pf24bit;
                  {$endif}
                end
               // by Starenko begin
              else  if (ocUseGlyphAssign in FOptions)and Assigned(FCoolImages) then
                      begin
                      //GlAss assign -1 to determinate if user changed it value
                      GlAss:=-1;
                      // if user procedure assigned then we execute it...
                      if Assigned(FOnGlyphDraw) then
                         FOnGlyphDraw(Index,GlAss);
                      // if user's procedure didn't changed we assign standart Glyph,if no - from Coolimages
                      if GlAss<>-1 then
                         AGlyph.Glyph.Assign(FCoolImages.Images.Items[GlAss].Picture.Bitmap)
                         else  AGlyph.Glyph := TGlyph(FGlyph).Glyph;
                        {$ifndef ver90}
                        AGlyph.Glyph.PixelFormat := pf24bit;
                        {$endif}
                      end
               // by Starenko end
              else
                AGlyph.Glyph := TGlyph(FGlyph).Glyph;
            ctPrinterControl:
              AGlyph.Glyph.LoadFromResourceName(HInstance, 'BITMAP_PRN');
            ctColorControl:
              CreateColorBitmap(AGlyph.Glyph, StringToColor(MakeColorStr(Items[Index])), Brush.Color);
            ctFolderControl:
              CreateFolderFileBitmap(AGlyph.Glyph, FFolderName + Items[Index]);
            ctCheckControl:
              CreateCheckBitmap(AGlyph.Glyph, GetState(Index), FFlatCheckBox);
            ctFontControl:
              begin
                AGlyph.Glyph.LoadFromResourceName(HInstance, FFontResNames[CheckTTFont(Items[Index])]);
                if FFontAutoUpdate then Font.Name := Items[Index];
              end;
          end;
          AGlyph.Draw(Canvas, R, Point(0, 0), Items[Index], blGlyphLeft, OFFSET, OFFSET, Enabled, True, clNone, FSimpleView, FShadowPos, FShadowColor, FShadowSize, {$IFDEF DELPHI4_OR_ABOVE}DrawTextBiDiModeFlags(0){$ELSE}0{$ENDIF});

          if not ExtendedCheck or (FBevelStyle = bsBevelBoth) then
            R := Recty;

          if not (ocBevelOnlyIfSel in FOptions) or (State = [odSelected, odFocused]) or (State = [odSelected]) then
            AGlyph.DrawBevels(Canvas, R, Point(0, 0), Items[Index], blGlyphLeft, OFFSET, OFFSET, FBevelInner, FBevelOuter, FBevelStyle, {$IFDEF DELPHI4_OR_ABOVE}DrawTextBiDiModeFlags(0){$ELSE}0{$ENDIF});
        finally
          AGlyph.Free;
        end;

      // Restore!
      SetTextColor(Handle, ColorText);
      SetBkColor(Handle, ColorBack);
    end;
end;

{TCoolComboBox}
constructor TCoolComboBox.Create(AOwner: TComponent);
begin
  FGlyph := TGlyph.Create;
  TGlyph(FGlyph).SimpleCaption := True;
  TGlyph(FGlyph).OnChange := GlyphChanged;
  inherited Create(AOwner);
  Style := csOwnerDrawVariable;
  FImageChangeLink := TChangeLink.Create;
  FImageChangeLink.OnChange := ImageListChange;
  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;
  FSelColor := clHighlight;
  FSelFont := TFont.Create;
  FSelFont.Color := clHighlightText;
  FSelFont.OnChange := SelFontChange;
  FBevelInner := bvNone;
  FBevelOuter := bvNone;
  FBevelStyle := bsBevelBoth;
  HListBox := 0;
  FExtendedStyle := ctCoolControl;
  FTrueType := False;
  FOptions := [ocBevelOnlyIfSel];
  FFlatCheckBox := False;
  FExtendedStyle := ctCoolControl;
  FExtendedCheck := False;
  FTrueType := False;
  FListBoxWidth := Width;
  FWrappers := TCollection.Create(TCheckWrapper);
  FMaxWidth := 0;
  FLightColorControl := True;
  FFontValue := TFont.Create;
  FFontValue.OnChange := FontValueChanged;
  FFontAutoUpdate := False;
  FFolderName := '';
  FFileType := [ftDirectory, ftArchive];
  FFileMask := '*.*';
  FAlignment := paLeft;
  HRect := Rect(0, 0, 0, 0);

  FShadowColor := clBtnHighlight;
  FShadowSize := 1;
  FShadowPos := spLeftTop;
  FSimpleView := False;

  FDefListProc := nil;
  FNewListProc := nil;

  FBorderPen := TPen.Create;
  FBorderPen.OnChange := BorderPenChange;
  FEdgeBorders := [];
  FBordersTrColor := clNone;
  FBorderStyle := bsSingle;

  FidWallpaper := -1;
  FidSelWallpaper := -1;
  FTransparencyLevel := 0;
end;

destructor TCoolComboBox.Destroy;
begin
  if Assigned(FWallpaper) then FWallPaper.Free;
  if Assigned(FSelWallPaper) then FSelWallPaper.Free;
  FImageChangeLink.Free;
  FCoolImagesChangeLink.Free;
  FSelFont.Free;
  FWrappers.Free;
  FSaveStates.Free;
  FFontValue.Free;
  FBorderPen.Free;
  inherited Destroy;
  TGlyph(FGlyph).Free;
end;

procedure TCoolComboBox.SetGlyph(Value: TBitmap);
begin
  TGlyph(FGlyph).Glyph := Value;
  Invalidate;
end;

function TCoolComboBox.GetGlyph: TBitmap;
begin
  Result := TGlyph(FGlyph).Glyph;
end;

procedure TCoolComboBox.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  FWallPaper.Assign(Value);
  Invalidate;
end;

function TCoolComboBox.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolComboBox.SetSelWallpaper(Value: TBitmap);
begin
  if FSelWallpaper = nil then FSelWallpaper := TBitmap.Create;
  FSelWallPaper.Assign(Value);
  Invalidate;
end;

function TCoolComboBox.GetSelWallpaper: TBitmap;
begin
  if FSelWallpaper = nil then FSelWallpaper := TBitmap.Create;
  Result := FSelWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolComboBox.SetOptions(Value: TCoolOptions);
begin
  if FOptions <> Value then
  begin
    if (ocPaintTransparently in Value) and (ocPaintWallpaper in FOptions) then
      Exclude(Value, ocPaintWallpaper) else
        if (ocPaintWallpaper in Value) and (ocPaintTransparently in FOptions) then
          Exclude(Value, ocPaintTransparently);

    FOptions := Value;
    Invalidate;
    Perform(CM_COLORCHANGED, 0, 0);
  end;
end;

procedure TCoolComboBox.SetImages(Value: TImageList);
begin
  if Assigned(Images) then
    Images.UnRegisterChanges(FImageChangeLink);

  FImages := Value;

  if Assigned(Images) then
    Images.RegisterChanges(FImageChangeLink);

  Invalidate;
end;

procedure TCoolComboBox.SetBevelInner(Value: TPanelBevel);
begin
  if FBevelInner <> Value then
  begin
    FBevelInner := Value;
    Invalidate;
  end;
end;

procedure TCoolComboBox.SetBevelOuter(Value: TPanelBevel);
begin
  if FBevelOuter <> Value then
  begin
    FBevelOuter := Value;
    Invalidate;
  end;
end;

procedure TCoolComboBox.SetBevelStyleEx(Value: TBevelStyleEx);
begin
  if FBevelStyle <> Value then
  begin
    FBevelStyle := Value;
    Invalidate;
  end;
end;

procedure TCoolComboBox.SetShadowColor(Value: TColor);
begin
  if FShadowColor <> Value then
  begin
    FShadowColor := Value;
    FSimpleView := False;
    Repaint;
  end;
end;

procedure TCoolComboBox.SetShadowSize(Value: Byte);
begin
  if FShadowSize <> Value then
  begin
    FShadowSize := Value;
    FSimpleView := False;
    Repaint;
  end;
end;

procedure TCoolComboBox.SetShadowPos(Value: TShadowPosition);
begin
  if FShadowPos <> Value then
  begin
    FShadowPos := Value;
    FSimpleView := False;
    Repaint;
  end;
end;

procedure TCoolComboBox.BorderPenChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolComboBox.SetEdgeBorders(Value: TEdgeBorders);
begin
  if FEdgeBorders <> Value then
  begin
    FEdgeBorders := Value;
    Invalidate;
  end;
end;

procedure TCoolComboBox.SetBorderPen(Value: TPen);
begin
  FBorderPen.Assign(Value);
end;

procedure TCoolComboBox.SetBordersTrColor(Value: TColor);
begin
  if FBordersTrColor <> Value then
  begin
    FBordersTrColor := Value;
    Invalidate;
  end;
end;

procedure TCoolComboBox.SetBorderStyle(Value: TBorderStyle);
begin
  if FBorderStyle <> Value then
  begin
    FBorderStyle := Value;
    Invalidate;
  end;
end;

procedure TCoolComboBox.SetSimpleView(Value: Boolean);
begin
  if FSimpleView <> Value then
  begin
    FSimpleView := Value;
    Repaint;
  end;
end;

function TCoolComboBox.GetTopIndex: Integer;
begin
  Result := SendMessage(Handle, CB_GETTOPINDEX, 0, 0);
end;

procedure TCoolComboBox.SetTopIndex(Value: Integer);
begin
  if GetTopIndex <> Value then
    SendMessage(Handle, CB_SETTOPINDEX, Value, 0);
end;

procedure TCoolComboBox.SetColorValue(Value: TColor);
var
  I: Integer;
begin
  if (FExtendedStyle = ctColorControl) then
    for I := 0 to Items.Count-1 do
      if ColorToString(Value) = MakeColorStr(Items[I]) then
      begin
        FColorValue := Value;
        ItemIndex := I;
        Break;
      end else
      begin
        ItemIndex := -1;
        FColorValue := -1;
      end;
end;

procedure TCoolComboBox.SetExtendedStyle(Value: TCoolControlStyle);
begin
  if FExtendedStyle <> Value then
  begin
    FExtendedStyle := Value;

    case FExtendedStyle of
      ctColorControl:
        CreateColorComboBox;
      ctFontControl:
        CreateFontComboBox;
      ctPrinterControl:
        CreatePrinterComboBox;
      ctFolderControl:
        CreateFolderComboBox;
      ctCheckControl:
        ExtendedCheck := False;
    end;

    Invalidate;
  end;
end;

procedure TCoolComboBox.SetExtendedCheck(Value: Boolean);
begin
  if FExtendedStyle = ctCheckControl then
    Value := False;

  if FExtendedCheck <> Value then
  begin
    FExtendedCheck := Value;
    Invalidate;
  end;
end;

procedure TCoolComboBox.SetTrueType(Value: Boolean);
begin
  if FTrueType <> Value then
  begin
    Clear;

    FTrueType := Value;

    if (FExtendedStyle = ctFontControl) then
      CreateFontComboBox;
  end;
end;

procedure TCoolComboBox.SetTransparencyLevel(Value: Byte);
begin
  if FTransparencyLevel <> Value then
  begin
    FTransparencyLevel := Value;
    Invalidate;
  end;
end;

procedure TCoolComboBox.SetFontAutoUpdate(Value: Boolean);
begin
  if FFontAutoUpdate <> Value then
  begin
    FFontAutoUpdate := Value;
    Invalidate;
  end;
end;

procedure TCoolComboBox.SetSelFont(Value: TFont);
begin
  FSelFont.Assign(Value);
end;

function TCoolComboBox.GetItemData(Index: Integer): LongInt;
begin
  Result := SendMessage(Handle, CB_GETITEMDATA, Index, 0);
  if (FExtendedStyle = ctCheckControl) or FExtendedCheck then
  begin
    Result := 0;
    if HaveWrapper(Index) then
      Result := TCheckWrapper(GetWrapper(Index)).FData;
  end;
end;

procedure TCoolComboBox.SetItemData(Index: Integer; AData: LongInt);
var
  Wrapper: TCheckWrapper;
begin
  SendMessage(Handle, CB_SETITEMDATA, Index, AData);
  if (FExtendedStyle = ctCheckControl) or FExtendedCheck then
  begin
    Wrapper := TCheckWrapper(GetWrapper(Index));
    Wrapper.FData := AData;

    if FSaveStates <> nil then
      if FSaveStates.Count > 0 then
      begin
        Wrapper.FState := TCheckBoxState(FSaveStates[0]);
        FSaveStates.Delete(0);
      end;
  end;
end;

function TCoolComboBox.GetChecked(Index: Integer): Boolean;
begin
  if HaveWrapper(Index) then
    Result := TCheckWrapper(GetWrapper(Index)).GetChecked
  else
    Result := False;
end;

procedure TCoolComboBox.SetChecked(Index: Integer; Value: Boolean);
begin
  if Value <> GetChecked(Index) then
    TCheckWrapper(GetWrapper(Index)).SetChecked(Value);
end;

procedure TCoolComboBox.SetFolderName;
begin
  if FFolderName <> Value then
  begin
    FFolderName := Value;

    if FFolderName <> '' then
      if FFolderName[Length(FFolderName)] <> '\' then
        FFolderName := FFolderName + '\';

    if Pos('..', FFolderName) <> 0 then
      FFolderName := GetParentFolder(Copy(FFolderName, 0, Pred(Pos('..', FFolderName))));

    if FExtendedStyle = ctFolderControl then
      CreateFolderComboBox;
  end;
end;

procedure TCoolComboBox.SetFileType(Value: TFileType);
begin
  if FFileType <> Value then
  begin
    FFileType := Value;

    if FExtendedStyle = ctFolderControl then
      CreateFolderComboBox;
  end;
end;

procedure TCoolComboBox.SetFileMask(Value: string);
begin
  if FFileMask <> Value then
  begin
    FFileMask := Value;

    if FExtendedStyle = ctFolderControl then
      CreateFolderComboBox;
  end;
end;

function TCoolComboBox.GetState(Index: Integer): TCheckBoxState;
begin
  if HaveWrapper(Index) then
    Result := TCheckWrapper(GetWrapper(Index)).State
  else
    Result := TCheckWrapper.GetDefaultState;
end;

procedure TCoolComboBox.SetState(Index: Integer; Value: TCheckBoxState);
begin
  if Value <> GetState(Index) then
    TCheckWrapper(GetWrapper(Index)).State := Value;
end;

function TCoolComboBox.GetLocked(Index: Integer): Boolean;
begin
  if HaveWrapper(Index) then
    Result := TCheckWrapper(GetWrapper(Index)).Locked
  else
    Result := False;
end;

procedure TCoolComboBox.SetLocked(Index: Integer; Value: Boolean);
begin
  if Value <> GetLocked(Index) then
    TCheckWrapper(GetWrapper(Index)).Locked := Value;
end;

procedure TCoolComboBox.SetFlatCheckBox(Value: Boolean);
begin
  if FFlatCheckBox <> Value then
  begin
    FFlatCheckBox := Value;
    Invalidate;
  end;
end;

procedure TCoolComboBox.SetListBoxWidth(Value: Integer);
begin
  if Value = 0 then
    FListBoxWidth := Width else
      FListBoxWidth := Value;
end;

procedure TCoolComboBox.WallpaperChanged(Sender: TObject);
begin
  Invalidate;
  Perform(CM_COLORCHANGED, 0, 0);
end;

procedure TCoolComboBox.ImageListChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolComboBox.SelFontChange(Sender: TObject);
begin
  ParentFont := False;
end;

procedure TCoolComboBox.GlyphChanged(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolComboBox.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolComboBox.SetidSelWallpaper(Value: Integer);
begin
  if FidSelWallpaper <> Value then
  begin
    FidSelWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolComboBox.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  Invalidate;
end;

function TCoolComboBox.IsWallpaperAssigned: Boolean;
begin
  Result := (Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty) or
            (Assigned(FWallpaper) and not FWallpaper.Empty);
end;

function TCoolComboBox.IsSelWallpaperAssigned: Boolean;
begin
  Result := (Assigned(FCoolImages) and (FidSelWallpaper >= 0) and (FidSelWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidSelWallpaper].Bitmap) and not FCoolImages.Images.Items[FidSelWallpaper].Bitmap.Empty) or
            (Assigned(FSelWallpaper) and not FSelWallpaper.Empty);
end;

function TCoolComboBox.CTLDrawWallpaperEx(DC: HDC; R, SubRect: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaperEx(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, SubRect, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaperEx(DC, FWallpaper, R, SubRect, IsStretch, Mode);
    Result := True;
  end;
end;

function TCoolComboBox.CTLDrawSelWallpaperEx(DC: HDC; R, SubRect: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidSelWallpaper >= 0) and (FidSelWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidSelWallpaper].Bitmap) and not FCoolImages.Images.Items[FidSelWallpaper].Bitmap.Empty then
  begin
    DrawWallpaperEx(DC, FCoolImages.Images.Items[FidSelWallpaper].Bitmap, R, SubRect, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FSelWallpaper) and not FSelWallpaper.Empty then
  begin
    DrawWallpaperEx(DC, FSelWallpaper, R, SubRect, IsStretch, Mode);
    Result := True;
  end;
end;

procedure TCoolComboBox.CoolImagesChange(Sender: TObject);
begin
  Invalidate;
end;

function TCoolComboBox.RealWidth(ItemStr: string): Integer;
var
  C: TCanvas;
begin
  C := TCanvas.Create;
  try
    C.Handle := GetDC(0);
    try
      C.Font.Assign(FSelFont);
      Result := C.TextWidth(ItemStr);

      C.Font.Assign(Font);
      if C.TextWidth(ItemStr) > Result then
        Result := C.TextWidth(ItemStr);

      Result := Result + Glyph.Width;
    finally
      ReleaseDC(0, C.Handle);
    end;
  finally
    C.Free;
  end;
end;

function TCoolComboBox.MaxWidth: Integer;
var
  I: Integer;
begin
  Result := 0;

  if Items.Count > 0 then
  begin
    for I := 0 to Items.Count-1 do
      if Length(Items[I]) > Length(Items[Result]) then
        Result := I;

    Result := RealWidth(Items[Result]);
  end;
end;

function TCoolComboBox.GetWrapper(Index: Integer): TObject;
begin
  Result := ExtractWrapper(Index);
  if Result = nil then
    Result := CreateWrapper(Index);
end;

function TCoolComboBox.ExtractWrapper(Index: Integer): TObject;
begin
  Result := TCheckWrapper(SendMessage(Handle, CB_GETITEMDATA, Index, 0));
end;

function TCoolComboBox.CreateWrapper(Index: Integer): TObject;
begin
  Result := TCheckWrapper.Create(FWrappers);
  SendMessage(Handle, CB_SETITEMDATA, Index, LongInt(Result));
end;

function TCoolComboBox.HaveWrapper(Index: Integer): Boolean;
begin
  Result := ExtractWrapper(Index) <> nil;
end;

procedure TCoolComboBox.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FImages) and (AComponent = FImages) then
  begin
    FImages := nil;
    Invalidate;
  end;
  if (Operation = opRemove) and Assigned(FCoolImages) and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

procedure TCoolComboBox.WndProc(var Message: TMessage);
var
  R: TRect;
begin
  inherited WndProc(Message);
  try
    case Message.Msg of

      WM_CTLCOLORLISTBOX:
        with TWMCtlColorListBox(Message) do
          if HListBox <> ChildWnd then
          begin
            HListBox := ChildWnd;
            if (FListBoxWidth <> Width) and (HListBox <> 0) then
            begin
              GetWindowRect(HListBox, R);
              with R do
                if Right - Left <> FListBoxWidth then
                  case FAlignment of
                    paLeft:
                      MoveWindow(HListBox, Left, Top, FListBoxWidth, Bottom-Top, True);
                    paRight:
                      MoveWindow(HListBox, Right - FListBoxWidth , Top, FListBoxWidth, Bottom-Top, True);
                    paCenter:
                      MoveWindow(HListBox, Left + ((Right - Left) div 2 - FListBoxWidth div 2), Top, FListBoxWidth, Bottom-Top, True);
                  end;
            end;

            GetWindowRect(HListBox, HRect);
            Windows.ScreenToClient(HListBox, HRect.TopLeft);
            Windows.ScreenToClient(HListBox, HRect.BottomRight);

            if GetWindowLong(HListBox, GWL_STYLE) and WS_HSCROLL <> 0 then
              GetScrollRange(HListBox, SB_HORZ, HRect.Left, HRect.Right);

            if not Assigned(FDefListProc) and not Assigned(FNewListProc) then
            begin
              FNewListProc := MakeObjectInstance(ListWndProc);
              FDefListProc := Pointer(SetWindowLong(HListBox, GWL_WNDPROC, LongInt(FNewListProc)));
            end;

            if FBorderStyle = bsNone then
              Invalidate;
          end;

      WM_KEYDOWN:
        begin
          if (FExtendedStyle = ctCheckControl) or FExtendedCheck then
            if Message.wParam = vk_space then
            begin
              Checked[ItemIndex] := not Checked[ItemIndex];
              R := ClientRect;
              InflateRectEx(R, 2, 2, -2, 0);
              R.Right := R.Left + ItemHeight;
              InvalidateRect(Handle, @R, False);
              if (HListBox <> 0) then
              begin
                SendMessage(HListBox, LB_GETITEMRECT, ItemIndex, Integer(@R));
                R.Right := R.Left + ItemHeight + 2;
                InvalidateRect(HListBox, @R, False);
              end;
            end;
        end;
    end;
  except
    Application.HandleException(Self);
  end;
end;

procedure TCoolComboBox.ComboWndProc(var Message: TMessage; ComboWnd: HWnd; ComboProc: Pointer);
begin
  inherited ComboWndProc(Message, ComboWnd, ComboProc);
end;

procedure TCoolComboBox.ListWndProc(var Message: TMessage);
begin
  try
    case Message.Msg of
      WM_PAINT:
        Perform(CB_GETTOPINDEX, 0, 0);
    end;

    with Message do
      Result := CallWindowProc(FDefListProc, HListBox, Msg, wParam, lParam);
  except
    Application.HandleException(Self);
  end;
end;

procedure TCoolComboBox.Loaded;
begin
  inherited Loaded;
  if FExtendedStyle <> ctColorControl then
    case FExtendedStyle of
      ctColorControl:
        CreateColorComboBox;
      ctFontControl:
        CreateFontComboBox;
      ctPrinterControl:
        CreatePrinterComboBox;
      ctFolderControl:
        CreateFolderComboBox;
    end;
end;

procedure TCoolComboBox.CreateWnd;
begin
  inherited CreateWnd;
  if (FExtendedStyle = ctCheckControl) or FExtendedCheck then
    if FSaveStates <> nil then
    begin
      FSaveStates.Free;
      FSaveStates := nil;
    end;
end;

procedure TCoolComboBox.DestroyWnd;
var
  I: Integer;
begin
  if (FExtendedStyle = ctCheckControl) or FExtendedCheck then
    if Items.Count > 0 then
    begin
      FSaveStates := TList.Create;
      for I := 0 to Items.Count-1 do
        FSaveStates.Add(TObject(State[I]));
    end;

  inherited DestroyWnd;
end;

procedure TCoolComboBox.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do
    Style := Style or WS_HSCROLL;
end;

procedure TCoolComboBox.SetParent(AParent: TWinControl);
begin
  inherited SetParent(AParent);
end;

procedure TCoolComboBox.SetLightColorControl(Value: Boolean);
begin
  if FLightColorControl <> Value then
  begin
    FLightColorControl := Value;
    if FExtendedStyle = ctColorControl then
      CreateColorComboBox;
  end;
end;

procedure TCoolComboBox.SetFontValue(Value: TFont);
begin
  FFontValue.Assign(Value);
  ItemIndex := Items.IndexOf(FFontValue.Name);
end;

function TCoolComboBox.GetFontValue: TFont;
var
  Save: TNotifyEvent;
begin
  Save := FFontValue.OnChange;
  FFontValue.OnChange := nil;

  if ItemIndex <> -1 then
    FFontValue.Name := Items[ItemIndex];

  FFontValue.OnChange := Save;

  Result := FFontValue;
end;

procedure TCoolComboBox.FontValueChanged(Sender: TObject);
begin
end;

procedure TCoolComboBox.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited KeyDown(Key, Shift);

  if (FExtendedStyle = ctColorControl) then
    if (Key = VK_RETURN) and (Shift = [ssCtrl]) then
      with TColorDialog.Create(Self) do
      try
        Color := ColorValue;
        if Execute then
        begin
          ColorValue := Color;
          if ItemIndex = -1 then
          begin
            Items.Add(ColorToString(Color));
            ColorValue := Color;
          end;
        end;
      finally
        Free;
      end;

  if (FExtendedStyle = ctFontControl) then
    if (Key = VK_RETURN) and (Shift = [ssCtrl]) then
      with TFontDialog.Create(Self) do
      try
        Font := FontValue;

       if Execute then
       begin
         FontValue := Font;

         if Assigned(Self.OnChange) then
           Self.OnChange(Self);
       end;
      finally
        Free;
      end;
end;

procedure TCoolComboBox.CreateColorComboBox;
var
  I: Integer;
  Proc: TGetStrProc;
begin
  Items.BeginUpdate;
  Clear;

  if FLightColorControl then
  begin
    for I := Low(Colors) to High(Colors) do
      Items.Add(ColorToString(Colors[I]));
  end else
  begin
    Proc := Items.Append;
    GetColorValues(Proc);
  end;

  Items.EndUpdate;
end;

function TCoolComboBox.MakeColorStr(Value: string): string;
begin
  try
    StringToColor(Value);
    Result := Value;
  except
    Result := 'cl' + Value;
    Application.HandleException(Self);  
  end;
end;

procedure TCoolComboBox.CreateFontComboBox;
var
  I: Integer;
begin
  Items.BeginUpdate;
  Clear;
  if not FTrueType then
    Items.Assign(Screen.Fonts) else
      for I := 0 to Screen.Fonts.Count-1 do
        if CheckTTFont(Screen.Fonts[I]) then
          Items.Add(Screen.Fonts[I]);
  Items.EndUpdate;
end;

procedure TCoolComboBox.CreateFolderComboBox;

  procedure BuildFromList(AList: TStringList);
  begin
    Items.Assign(AList);
  end;

const
   Attributes: array[TFileAttr] of Word = (SysUtils.faReadOnly, SysUtils.faHidden, SysUtils.faSysFile,
                                           SysUtils.faVolumeID, SysUtils.faDirectory, SysUtils.faArchive, SysUtils.faAnyFile);
var
  FileList: TStringList;
  Attr: Integer;
  AttrIndex: TFileAttr;
begin
  if FFolderName <> '' then
  begin
    Items.BeginUpdate;
    try
      Clear;

      Attr := 0;
      for AttrIndex := ftReadOnly to ftNormal do
        if AttrIndex in FileType then
          Attr := Attr or Attributes[AttrIndex];

      FileList := GetFileDirList(FFolderName, FFileMask, Attr);
      try
        BuildFromList(FileList);
      finally
        FileList.Free;
      end;

    finally
      Items.EndUpdate;
    end;
  end;
end;

procedure TCoolComboBox.CreatePrinterComboBox;
var
  I: Integer;
begin
  Items.BeginUpdate;
  Clear;
  for I := 0 to Printer.Printers.Count-1 do
    Items.Add(Printer.Printers[I]);
  Items.EndUpdate;
end;

procedure TCoolComboBox.CNCommand(var Message: TWMCommand);
begin
  if Message.NotifyCode = CBN_SELCHANGE then
    if (FExtendedStyle = ctColorControl) and (ItemIndex <> -1) then
      FColorValue := StringToColor(MakeColorStr(Items[ItemIndex]));

  if Message.NotifyCode = CBN_CLOSEUP then
  begin
    if Assigned(FDefListProc) then
    begin
      SetWindowLong(HListBox, GWL_WNDPROC, LongInt(FDefListProc));
      FDefListProc := nil;
    end;

    if Assigned(FNewListProc) then
    begin
      FreeObjectInstance(FNewListProc);
      FNewListProc := nil;
    end;

    HListBox := 0;
  end;
    
  inherited;
end;

procedure TCoolComboBox.CBGetTopIndex(var Message: TMessage);
const
  IndexTop: Integer = 0;
begin
  inherited;
  if (IndexTop <> Message.Result) and (((ocPaintWallpaper in FOptions) and IsWallpaperAssigned) or (ocPaintTransparently in FOptions)) then
  begin
    InvalidateRectEx(HListBox, HRect, False);
    IndexTop := Message.Result;
  end;
end;

procedure TCoolComboBox.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
  inherited;
end;

procedure TCoolComboBox.WMPaint(var Message: TWMPaint);
var
  Canvas: TControlCanvas;
  R: TRect;
begin
  inherited;

  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, Screen.ActiveControl = Self);

  if FBorderStyle = bsNone then
  begin
    Canvas := TControlCanvas.Create;
    try
      Canvas.Control := Self;
      R := ClientRect;
      InflateRect(R, -2, -2);
      PaintBackgroundCombineRgn(TrControl(Self, FTransparencyLevel), Canvas.Handle, ClientRect, R, RGN_DIFF, True);
      DrawBorders(0, Self, FEdgeBorders, FBorderPen, FBordersTrColor);
    finally
      Canvas.Free;
    end;
  end;
end;

procedure TCoolComboBox.WMNCPaint(var Message: TMessage);
begin
  inherited;
end;

procedure TCoolComboBox.CMMouseEnter(var Message: TMessage);
begin
  inherited;
  if (ocFlatBorder in FOptions) and not IsCoolControl(Screen.ActiveControl) then
    DrawFlatBorder(0, Self, True);

  if Assigned(FOnMouseEnter) then
    FOnMouseEnter(Self);
end;

procedure TCoolComboBox.CMMouseLeave (var Message: TMessage);
begin
  inherited;
  if (ocFlatBorder in FOptions) and not IsCoolControl(Screen.ActiveControl) then
    DrawFlatBorder(0, Self, False);

  if Assigned(FOnMouseLeave) then
    FOnMouseLeave(Self);
end;

procedure TCoolComboBox.WMSetFocus(var Message: TWMSetFocus);
begin
  inherited;
  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, True);
end;

procedure TCoolComboBox.WMKillFocus(var Message: TWMKillFocus);
begin
  inherited;
  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, False);
end;

procedure TCoolComboBox.CMParentFontChanged(var Message: TMessage);
begin
  inherited;
  if ParentFont then
  begin
    FSelFont.OnChange := nil;
    try
      if Message.wParam <> 0 then
        FSelFont.Assign(TFont(Message.lParam)) else
        FSelFont.Assign(Font);

      FSelFont.Color := clHighlightText;
    finally
      FSelFont.OnChange := SelFontChange;
    end;
  end;
end;

procedure TCoolComboBox.CMEnabledChanged(var Message: TMessage);
begin
  inherited;
  if csDesigning in ComponentState then
    Invalidate;
end;

procedure TCoolComboBox.WMSize(var Message: TWMSize);
begin
  inherited;
  if (csDesigning in ComponentState) and not (csLoading in ComponentState) then
    FListBoxWidth := Width;
end;

procedure TCoolComboBox.CBAddString(var Message: TMessage);
var
  RW: Integer;
begin
  inherited;
  RW := RealWidth(PChar(Message.lParam));
  if (RW > FMaxWidth) and (RW > FListBoxWidth) then
  begin
    FMaxWidth := RW;
    Perform(CB_SETHORIZONTALEXTENT, FMaxWidth, 0);
  end;
end;

procedure TCoolComboBox.CBInsertString(var Message: TMessage);
var
  RW: Integer;
begin
  inherited;
  RW := RealWidth(PChar(Message.lParam));
  if (RW > FMaxWidth) and (RW > FListBoxWidth) then
  begin
    FMaxWidth := RW;
    Perform(CB_SETHORIZONTALEXTENT, FMaxWidth, 0);
  end;
end;

procedure TCoolComboBox.CBDeleteString(var Message: TMessage);
begin
  inherited;
  FMaxWidth := MaxWidth;
  Perform(CB_SETHORIZONTALEXTENT, FMaxWidth, 0);
end;

procedure TCoolComboBox.CBResetContent(var Message: TMessage);
begin
  inherited;
  FMaxWidth := MaxWidth;
  Perform(CB_SETHORIZONTALEXTENT, FMaxWidth, 0);
end;

procedure TCoolComboBox.CMParentColorChanged(var Message: TMessage);
begin
  inherited;
  if ocPaintTransparently in FOptions then
    Invalidate;
end;

procedure TCoolComboBox.WMMove(var Message: TWMMove);
begin
  inherited;
  Invalidate;
end;

procedure TCoolComboBox.CMPaintListBoxPart(var Message: TMessage);
begin
end;

procedure TCoolComboBox.MeasureItem(Index: Integer; var Height: Integer);
begin
  inherited MeasureItem(Index, Height);
end;

function TCoolComboBox.GetNumGlyphs: TNumGlyphs;
begin
  Result := TGlyph(FGlyph).NumGlyphs;
end;

procedure TCoolComboBox.SetNumGlyphs(Value: TNumGlyphs);
begin
  if Value < 0 then Value := 1 else
      if Value > 2 then Value := 2;

  if Value <> TGlyph(FGlyph).NumGlyphs then
  begin
    TGlyph(FGlyph).NumGlyphs := Value;
    Invalidate;
  end;
end;

procedure TCoolComboBox.DrawItem(Index: Integer; Recty: TRect; State: StdCtrls.TOwnerDrawState);

  procedure CreateColorBitmap(const ABitmap: TBitmap; AColor, ABkColor: TColor);
  var
    TempBitmap: TBitmap;
  begin
    TempBitmap := TBitmap.Create;

    with TempBitmap, TempBitmap.Canvas do
    try
      Width := ItemHeight;
      Height := ItemHeight;

      if ColorToRGB(ABkColor) = ColorToRGB(AColor) then
        ABkColor := Pred(ABkColor);

      Brush.Color := ABkColor;
      FillRect(Rect(0, 0, Width, Height));

      Pen.Color := clBlack;
      Brush.Color := AColor;
      Rectangle(0, LIGHT_OFFSET, Width, Height - LIGHT_OFFSET);
    finally
      ABitmap.Assign(TempBitmap);
      TempBitmap.Free;
    end;
  end;

  procedure CreateCheckBitmap(const ABitmap: TBitmap; AState: TCheckBoxState; AFlat: Boolean);
  var
    TempBitmap: TBitmap;
    Mode: Integer;
  begin
    TempBitmap := TBitmap.Create;

    with TempBitmap, TempBitmap.Canvas do
    try
      Width := ItemHeight;
      Height := ItemHeight;

      Brush.Color := clOlive;
      FillRect(Rect(0, 0, ItemHeight, ItemHeight));

      case AState of
        cbChecked:
          Mode := DFCS_BUTTONCHECK or DFCS_CHECKED;
        cbUnchecked:
          Mode := DFCS_BUTTONCHECK;
        else
          Mode := DFCS_BUTTON3STATE or DFCS_CHECKED;
      end;

      if AFlat then
        Mode := Mode or DFCS_FLAT;

      DrawFrameControl(Handle, Rect(1, 1, Pred(ItemHeight), Pred(ItemHeight)), DFC_BUTTON, Mode);
    finally
      ABitmap.Assign(TempBitmap);
      TempBitmap.Free;
    end;
  end;

  procedure CreateFolderFileBitmap(const ABitmap: TBitmap; AFileName: TFileName);
  var
    Info: TShFileInfo;
    TempBitmap: TBitmap;
  begin
    if Pos('..', AFileName) = 0 then
    begin
      TempBitmap := TBitmap.Create;

      with TempBitmap, TempBitmap.Canvas do
      try
        Width := ItemHeight;
        Height := ItemHeight;

        Brush.Color := clOlive;
        FillRect(Rect(0, 0, Width, Height));

        ShGetFileInfo(PChar(AFileName), 0, Info, SizeOf(TShFileInfo), SHGFI_ICON or SHGFI_SMALLICON);
        DrawIconEx(Handle, 0, 0, Info.hIcon, Width, Height, 0, 0, DI_NORMAL);
        {$IFNDEF VER90}
        TransparentColor := clOlive;
        {$ENDIF}
      finally
        ABitmap.Assign(TempBitmap);
        TempBitmap.Free;
      end;
    end;
  end;

const
{$IFNDEF DELPHI4_OR_ABOVE}
  FInnerEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER);
  FOuterEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER);
{$ELSE}
  FInnerEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER, 0);
  FOuterEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER, 0);
{$ENDIF}
  FFontResNames: array[Boolean] of string = ('BITMAP_NTT', 'BITMAP_TT');
var
  R: TRect;
  AGlyph: TGlyph;
  GlAss: Integer; // by Starenko
  ColorText, ColorBack: LongInt;
  C: TControlCanvas;
begin
  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, Screen.ActiveControl = Self);

  if FBorderStyle = bsNone then
  begin
    C := TControlCanvas.Create;
    try
      C.Control := Self;
      R := ClientRect;
      InflateRect(R, -2, -2);
      PaintBackgroundCombineRgn(TrControl(Self, FTransparencyLevel), C.Handle, ClientRect, R, RGN_DIFF, True);
      DrawBorders(0, Self, FEdgeBorders, FBorderPen, FBordersTrColor);
    finally
      C.Free;
    end;
  end;

  if Assigned(OnDrawItem) then
    OnDrawItem(Self, Index, Recty, State) else
    with Canvas do
    begin
      // Initialize!
      ColorText := GetTextColor(Handle);
      ColorBack := GetBkColor(Handle);

      // Initial draw.
      if EqualRect(HRect, Rect(0, 0, 0, 0)) then
        HRect := ClientRect;

      // Here we paint wallpaper and background!
      // **************************************
      if (State = [odSelected, odFocused {$IFDEF DELPHI5_OR_ABOVE} , odComboBoxEdit {$ENDIF}]) or (State = [odSelected, odFocused]) or (State = [odSelected]) then
      begin
        Font.Assign(FSelFont);
        Brush.Color := FSelColor;

        if (ocInvertWallpaperAsSelect in FOptions) and IsWallpaperAssigned then
        begin
          CTLDrawWallpaperEx(Handle, HRect, Recty, (ocStretchWallpaper in FOptions), NOTSRCCOPY);
        end else
        if (ocPaintSelWallpaper in FOptions) and IsSelWallpaperAssigned then
        begin
          CTLDrawSelWallpaperEx(Handle, HRect, Recty, (ocStretchWallpaper in FOptions), SRCCOPY);
        end else
        begin
          FillRect(Recty);
        end;
      end else
      if (ocPaintWallpaper in FOptions) and IsWallpaperAssigned then
        CTLDrawWallpaperEx(Handle, HRect, Recty, (ocStretchWallpaper in FOptions), SRCCOPY) else
        begin
          if not (ocPaintTransparently in FOptions) then
          begin
            Brush.Color := Color;
            FillRect(Recty);
          end else
          begin
            PaintBackgroundEx(TrControl(Self, FTransparencyLevel), Handle, Recty, True);
          end;
        end;

        // Here we paint image text and bevels!
        // ********************
        AGlyph := TGlyph.Create;
        try
          AGlyph.SimpleCaption := True;
          R := Recty;

          if FExtendedCheck then
          begin
            CreateCheckBitmap(AGlyph.Glyph, GetState(Index), FFlatCheckBox);
            AGlyph.DrawImageEx(Canvas, R, Point(0, 0), Items[Index], blGlyphLeft, OFFSET, OFFSET, Enabled, True, clNone, {$IFDEF DELPHI4_OR_ABOVE}DrawTextBiDiModeFlags(0){$ELSE}0{$ENDIF});
            InflateRect(R, -(AGlyph.Glyph.Width + OFFSET), 0);
            AGlyph.Glyph.Assign(nil);
          end;

          case FExtendedStyle of
            ctCoolControl:
              if (ocUseImageList in FOptions) and Assigned(FImages) then
                begin
                  FImages.GetBitmap(Index, AGlyph.Glyph);
                  {$ifndef ver90}
                  AGlyph.Glyph.PixelFormat := pf24bit;
                  {$endif}
                end
                // by Starenko begin
              else  if (ocUseGlyphAssign in FOptions)and Assigned(FCoolImages) then
                      begin
                      //GlAss assign -1 to determinate if user changed it value
                      GlAss:=-1;
                      // if user procedure assigned then we execute it...
                      if Assigned(FOnGlyphDraw) then
                         FOnGlyphDraw(Index,GlAss);
                      // if user's procedure didn't changed we assign standart Glyph,if no - from Coolimages
                      if GlAss<>-1 then
                         AGlyph.Glyph.Assign(FCoolImages.Images.Items[GlAss].Picture.Bitmap)
                         else  AGlyph.Glyph := TGlyph(FGlyph).Glyph;
                        {$ifndef ver90}
                        AGlyph.Glyph.PixelFormat := pf24bit;
                        {$endif}
                      end
               // by Starenko end
              else
                AGlyph.Glyph := TGlyph(FGlyph).Glyph;
            ctPrinterControl:
              AGlyph.Glyph.LoadFromResourceName(HInstance, 'BITMAP_PRN');
            ctColorControl:
              CreateColorBitmap(AGlyph.Glyph, StringToColor(MakeColorStr(Items[Index])), Brush.Color);
            ctFolderControl:
              CreateFolderFileBitmap(AGlyph.Glyph, FFolderName + Items[Index]);
            ctCheckControl:
              CreateCheckBitmap(AGlyph.Glyph, GetState(Index), FFlatCheckBox);
            ctFontControl:
              begin
                AGlyph.Glyph.LoadFromResourceName(HInstance, FFontResNames[CheckTTFont(Items[Index])]);
                if FFontAutoUpdate then Font.Name := Items[Index];
              end;
          end;
          AGlyph.Draw(Canvas, R, Point(0, 0), Items[Index], blGlyphLeft, OFFSET, OFFSET, Enabled, True,
              clNone, FSimpleView, {$IFDEF BCB}{$IFDEF VER100}SPToInt({$ENDIF}{$ENDIF} FShadowPos {$IFDEF BCB}{$IFDEF VER100}){$ENDIF}{$ENDIF}, FShadowColor, FShadowSize, {$IFDEF DELPHI4_OR_ABOVE}DrawTextBiDiModeFlags(0){$ELSE}0{$ENDIF});

          if not ExtendedCheck or (FBevelStyle = bsBevelBoth) then
            R := Recty;

          if not (ocBevelOnlyIfSel in FOptions) or (State = [odSelected, odFocused]) or (State = [odSelected]) then
            AGlyph.DrawBevels(Canvas, R, Point(0, 0), Items[Index], blGlyphLeft, OFFSET, OFFSET, FBevelInner,
              FBevelOuter, {$IFDEF BCB}{$IFDEF VER100}BSEToInt({$ENDIF}{$ENDIF} FBevelStyle {$IFDEF BCB}{$IFDEF VER100}){$ENDIF}{$ENDIF}, {$IFDEF DELPHI4_OR_ABOVE}DrawTextBiDiModeFlags(0){$ELSE}0{$ENDIF});

        finally
          AGlyph.Free;
        end;

      // Restore!
      SetTextColor(Handle, ColorText);
      SetBkColor(Handle, ColorBack);
    end;
end;

{TCellWrapper}
constructor TCellWrapper.Create(ACol, ARow: Integer; AGrid: TStringGrid);
begin
  Col := ACol;
  Row := ARow;
  FFont := TFont.Create;

  if (ACol < AGrid.FixedCols) or (ARow < AGrid.FixedRows) then
    FColor := AGrid.FixedColor else
      FColor := AGrid.Color;

  FFont.Assign(AGrid.Font);
  FReadOnlyCell := False;
  FWallpaperForCell := True;
  FCellTextAlign := taLeftJustify;
end;

destructor TCellWrapper.Destroy;
begin
  FFont.Free;
  inherited Destroy;
end;

procedure TCellWrapper.SetFont(Value: TFont);
begin
  FFont.Assign(Value);
end;

{TCoolInplaceEdit}
constructor TCoolInplaceEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FTextAlign := taLeftJustify;
  FBeingPainted := False;

  FBorderPen := TPen.Create;
  FBorderPen.OnChange := BorderPenChange;

  FOptions := [];
  FEdgeBorders := [];
  FBordersTrColor := clNone;

  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;
  FidWallpaper := -1;
end;

destructor TCoolInplaceEdit.Destroy;
begin
  FBorderPen.Free;
  FCoolImagesChangeLink.Free;
  if Assigned(FWallpaper) then FWallpaper.Free;
  inherited Destroy;
end;

procedure TCoolInplaceEdit.CreateWnd;
begin
  inherited CreateWnd;
end;

procedure TCoolInplaceEdit.CreateParams(var Params: TCreateParams);
const
   Alignments: array [TAlignment] of DWord = (ES_LEFT, ES_RIGHT, ES_CENTER);
begin
  inherited CreateParams(Params);
  with Params do
    Style := Params.Style or ES_MULTILINE or Alignments[FTextAlign];
end;

procedure TCoolInplaceEdit.SetParent(AParent: TWinControl);
begin
  inherited SetParent(AParent);
end;

procedure TCoolInplaceEdit.SetOptions(Value: TCoolOptions);
begin
  if FOptions <> Value then
  begin
    if (ocPaintTransparently in Value) and (ocPaintWallpaper in FOptions) then
      Exclude(Value, ocPaintWallpaper) else
        if (ocPaintWallpaper in Value) and (ocPaintTransparently in FOptions) then
          Exclude(Value, ocPaintTransparently);

    FOptions := Value;
    RecreateWnd;
    Perform(CM_COLORCHANGED, 0, 0);
  end;
end;

procedure TCoolInplaceEdit.SetTextAlign(Value: TAlignment);
begin
  if FTextAlign <> Value then
  begin
    FTextAlign := Value;
    RecreateWnd;
  end;
end;

procedure TCoolInplaceEdit.SetTransparencyLevel(Value: Byte);
begin
  if FTransparencyLevel <> Value then
  begin
    FTransparencyLevel := Value;
    Invalidate;
  end;
end;

procedure TCoolInplaceEdit.SetBorderPen(Value: TPen);
begin
  FBorderPen.Assign(Value);
end;

procedure TCoolInplaceEdit.SetBordersTrColor(Value: TColor);
begin
  if FBordersTrColor <> Value then
  begin
    FBordersTrColor := Value;
    Invalidate;
  end;
end;

procedure TCoolInplaceEdit.SetEdgeBorders(Value: TEdgeBorders);
begin
  if FEdgeBorders <> Value then
  begin
    FEdgeBorders := Value;
    Invalidate;
  end;
end;

procedure TCoolInplaceEdit.BorderPenChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolInplaceEdit.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  FWallpaper.Assign(Value);
  Invalidate;
end;

function TCoolInplaceEdit.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolInplaceEdit.WallpaperChanged(Sender: TObject);
begin
  Invalidate;
  Perform(CM_COLORCHANGED, 0, 0);
end;

procedure TCoolInplaceEdit.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolInplaceEdit.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  Invalidate;
end;

function TCoolInplaceEdit.CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaper(DC, FWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

function TCoolInplaceEdit.IsWallpaperAssigned: Boolean;
begin
  Result := (Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty) or
            (Assigned(FWallpaper) and not FWallpaper.Empty);
end;

procedure TCoolInplaceEdit.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FCoolImages) and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

procedure TCoolInplaceEdit.CoolImagesChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolInplaceEdit.WndProc(var Message: TMessage);
begin
  inherited WndProc(Message);
end;

procedure TCoolInplaceEdit.DoPaint;
const
  BorderOffsets: array[TBorderStyle] of Integer = (1, -1);
var
  MyDC: HDC;
  TempDC: HDC;
  OldBmp, TempBmp: HBITMAP;
begin
  FBeingPainted := True;

  if ((ocPaintWallpaper in FOptions) and IsWallpaperAssigned) or (ocPaintTransparently in FOptions) then
  begin
    MyDC := GetDC(Handle);
    try
      TempDC := CreateCompatibleDC(MyDC);
      try
        TempBmp := CreateCompatibleBitmap(MyDC, Succ(ClientWidth), Succ(ClientHeight));
        try
          OldBmp := SelectObject(TempDC, TempBmp);

          PaintTo(TempDC, 0, 0);

          if (ocFlatBorder in FOptions) then
            DrawFlatBorder(TempDC, Self, True);

          DrawBorders(TempDC, Self, FEdgeBorders, FBorderPen, FBordersTrColor);

          BitBlt(MyDC, BorderOffsets[BorderStyle], BorderOffsets[BorderStyle], ClientWidth, ClientHeight, TempDC, 1, 1, SRCCOPY);

          SelectObject(TempDC, OldBmp);
        finally
          DeleteObject(TempBmp);
        end;
      finally
        DeleteDC(TempDC);
      end;
    finally
      ReleaseDC(Handle, MyDC);
    end;
  end;

  FBeingPainted := False;
end;

procedure TCoolInplaceEdit.Change;
begin
  DoPaint;
  inherited Change;
end;

procedure TCoolInplaceEdit.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited KeyDown(Key, Shift);
  FReturnWanted := (Key = VK_RETURN) and (Shift = [ssCtrl]);
end;

procedure TCoolInplaceEdit.KeyUp(var Key: Word; Shift: TShiftState);
begin
  inherited KeyUp(Key, Shift);
end;

procedure TCoolInplaceEdit.KeyPress(var Key: Char);
begin
  inherited KeyPress(Key);
  if (Key = Char(VK_RETURN)) or FReturnWanted then
  begin
    Key := #0;
    MessageBeep(0);
  end;
end;

procedure TCoolInplaceEdit.CMMouseEnter (var Message: TMessage);
begin
  inherited;
  if (ocFlatBorder in FOptions) and not IsCoolControl(Screen.ActiveControl) then
    DrawFlatBorder(0, Self, True);

  if Assigned(FOnMouseEnter) then
    FOnMouseEnter(Self);
end;

procedure TCoolInplaceEdit.CMMouseLeave (var Message: TMessage);
begin
  inherited;
  if (ocFlatBorder in FOptions) and not IsCoolControl(Screen.ActiveControl) then
    DrawFlatBorder(0, Self, False);

  if Assigned(FOnMouseLeave) then
    FOnMouseLeave(Self);
end;

procedure TCoolInplaceEdit.WMSetFocus(var Message: TWMSetFocus);
begin
  inherited;
  if AutoSelect and not (csLButtonDown in ControlState) then
    SelectAll;

  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, True);
end;

procedure TCoolInplaceEdit.WMKillFocus(var Message: TWMKillFocus);
begin
  inherited;
  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, False);
end;

procedure TCoolInplaceEdit.WMEraseBkGnd(var Message: TWMEraseBkGnd);
begin
  if (ocPaintTransparently in FOptions) then
    PaintBackground(TrControl(Self, FTransparencyLevel), Message.DC, True) else
      if (ocPaintWallpaper in FOptions) and IsWallpaperAssigned then
        CTLDrawWallpaper(Message.DC, ClientRect, (ocStretchWallpaper in FOptions), SRCCOPY) else
          inherited;
end;

procedure TCoolInplaceEdit.WMPaint(var Message: TWMPaint);
begin
  inherited;

  if (ocPaintTransparently in FOptions) or ((ocPaintWallpaper in FOptions) and IsWallpaperAssigned) then
    if not FBeingPainted then
      DoPaint;

  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, Focused);
end;

procedure TCoolInplaceEdit.WMNCPaint(var Message: TMessage);
begin
  inherited;
end;

procedure TCoolInplaceEdit.CNCtlColorEdit(var Message: TWMCtlColorEdit);
begin
  inherited;
  if ((ocPaintWallpaper in FOptions) and IsWallpaperAssigned) or (ocPaintTransparently in FOptions) then
    SetBkMode(Message.ChildDC, TRANSPARENT);
end;

procedure TCoolInplaceEdit.CNCtlColorStatic(var Message: TWMCtlColorStatic);
begin
  inherited;
  if ((ocPaintWallpaper in FOptions) and IsWallpaperAssigned) or (ocPaintTransparently in FOptions) then
    SetBkMode(Message.ChildDC, TRANSPARENT);
end;

procedure TCoolInplaceEdit.CMParentColorChanged(var Message: TMessage);
begin
  inherited;
  if ocPaintTransparently in FOptions then
    Invalidate;
end;

procedure TCoolInplaceEdit.WMSize(var Message: TWMSize);
begin
  inherited;
end;

procedure TCoolInplaceEdit.WMMove(var Message: TWMMove);
begin
  inherited;
  Invalidate;
end;

{TCoolStringGrid}
constructor TCoolStringGrid.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FCaptionColor := clInactiveCaption;
  FCaptionTextColor := clInactiveCaptionText;
  FWrappers := TList.Create;
  FTextAlign := taLeftJustify;
  FFixedTextAlign := taLeftJustify;
  FSelColor := clHighLight;
  FInnerCellsBevel := bvNone;
  FOuterCellsBevel := bvNone;
  FExOptions := [ocNoCaption];
  FCanEdit := True;
  ControlStyle := ControlStyle + [csSetCaption] - [csOpaque];

  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;

  FidWallpaper := -1;
  FidCaptionWallpaper := -1;
  FidSelWallpaper := -1;
  FTransparencyLevel := 0;

  FCellMarginTop := 2;
  FCellMarginLeft := 2;
  FCellMarginRight := -2;
  FCellMarginBottom := -2;

  FGridFormat := RegisterClipboardFormat('GRID DATA');
end;

destructor TCoolStringGrid.Destroy;
var
  I: Integer;
begin
  for I := 0 to FWrappers.Count-1 do
    TCellWrapper(FWrappers[I]).Free;

  FCoolImagesChangeLink.Free;
  FWrappers.Free;
  if Assigned(FWallpaper) then FWallPaper.Free;
  if Assigned(FSelWallPaper) then FSelWallPaper.Free;
  if Assigned(FCaptionWallPaper) then FCaptionWallPaper.Free;
  inherited Destroy;
end;

procedure TCoolStringGrid.SetCaptionColor(Value: TColor);
begin
  if FCaptionColor <> Value then
  begin
    FCaptionColor := Value;
    NCCtlChanged;
  end;
end;

procedure TCoolStringGrid.SetCaptionTextColor(Value: TColor);
begin
  if FCaptionTextColor <> Value then
  begin
    FCaptionTextColor := Value;
    NCCtlChanged;
  end;
end;

procedure TCoolStringGrid.SetCaptionWallpaper(Value: TBitmap);
begin
  if FCaptionWallpaper = nil then FCaptionWallpaper := TBitmap.Create;
  FCaptionWallpaper.Assign(Value);
  NCCtlChanged;
end;

function TCoolStringGrid.GetCaptionWallpaper: TBitmap;
begin
  if FCaptionWallpaper = nil then FCaptionWallpaper := TBitmap.Create;
  Result := FCaptionWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolStringGrid.SetExOptions(Value: TCoolOptions);
begin
  if FExOptions <> Value then
  begin
    if (ocPaintTransparently in Value) and (ocPaintWallpaper in FExOptions) then
      Exclude(Value, ocPaintWallpaper) else
        if (ocPaintWallpaper in Value) and (ocPaintTransparently in FExOptions) then
          Exclude(Value, ocPaintTransparently);

    FExOptions := Value;
    RecreateWnd;
  end;
end;

procedure TCoolStringGrid.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  FWallPaper.Assign(Value);
  Invalidate;
end;

function TCoolStringGrid.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolStringGrid.SetSelWallpaper(Value: TBitmap);
begin
  if FSelWallpaper = nil then FSelWallpaper := TBitmap.Create;
  FSelWallPaper.Assign(Value);
  Invalidate;
end;

function TCoolStringGrid.GetSelWallpaper: TBitmap;
begin
  if FSelWallpaper = nil then FSelWallpaper := TBitmap.Create;
  Result := FSelWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolStringGrid.SetTextAlign(Value: TAlignment);
begin
  if FTextAlign <> Value then
  begin
    FTextAlign := Value;
    Invalidate;
  end;
end;

procedure TCoolStringGrid.SetFixedTextAlign(Value: TAlignment);
begin
  if FFixedTextAlign <> Value then
  begin
    FFixedTextAlign := Value;
    Invalidate;
  end;
end;

procedure TCoolStringGrid.SetSelColor(Value: TColor);
begin
  if FSelColor <> Value then
  begin
    FSelColor := Value;
    Invalidate;
  end;
end;

procedure TCoolStringGrid.SetInnerCellsBevel(Value: TPanelBevel);
begin
  if FInnerCellsBevel <> Value then
  begin
    FInnerCellsBevel := Value;
    Invalidate;
  end;
end;

procedure TCoolStringGrid.SetOuterCellsBevel(Value: TPanelBevel);
begin
  if FOuterCellsBevel <> Value then
  begin
    FOuterCellsBevel := Value;
    Invalidate;
  end;
end;

procedure TCoolStringGrid.SetTransparencyLevel(Value: Byte);
begin
  if FTransparencyLevel <> Value then
  begin
    FTransparencyLevel := Value;
    Invalidate;
  end;
end;

function TCoolStringGrid.GetColors(ACol, ARow: Integer): TColor;
begin
  if HaveWrapper(ACol, ARow) then
    Result := TCellWrapper(GetWrapper(ACol, ARow)).Color else
    begin
      if (ACol < FixedCols) or (ARow < FixedRows) then
        Result := FixedColor else
          Result := Color;
    end;
end;

procedure TCoolStringGrid.SetColors(ACol, ARow: Integer; Value: TColor);
begin
  TCellWrapper(GetWrapper(ACol, ARow)).Color := Value;
  InvalidateCell(ACol, ARow);
end;

function TCoolStringGrid.GetReadOnlyCells(ACol, ARow: Integer): Boolean;
begin
  if HaveWrapper(ACol, ARow) then
    Result := TCellWrapper(GetWrapper(ACol, ARow)).ReadOnlyCell else
      Result := False;
end;

procedure TCoolStringGrid.SetReadOnlyCells(ACol, ARow: Integer; Value: Boolean);
begin
  if Value <> GetReadOnlyCells(ACol, ARow) then
    TCellWrapper(GetWrapper(ACol, ARow)).ReadOnlyCell := Value;

  InvalidateCell(ACol, ARow);
end;

function TCoolStringGrid.GetWallpaperForCells(ACol, ARow: Integer): Boolean;
begin
  if HaveWrapper(ACol, ARow) then
    Result := TCellWrapper(GetWrapper(ACol, ARow)).WallpaperForCell else
      Result := False;
end;

procedure TCoolStringGrid.SetWallpaperForCells(ACol, ARow: Integer; Value: Boolean);
begin
  TCellWrapper(GetWrapper(ACol, ARow)).WallpaperForCell := Value;
  InvalidateCell(ACol, ARow);
end;

function TCoolStringGrid.GetFonts(ACol, ARow: Integer): TFont;
begin
  Result := TCellWrapper(GetWrapper(ACol, ARow)).Font;
end;

procedure TCoolStringGrid.SetFonts(ACol, ARow: Integer; Value: TFont);
begin
  if Value <> GetFonts(ACol, ARow) then
  begin
    TCellWrapper(GetWrapper(ACol, ARow)).Font := Value;
    InvalidateCell(ACol, ARow);
  end;
end;

function TCoolStringGrid.GetCellTextAligns(ACol, ARow: Integer): TAlignment;
begin
  Result := TCellWrapper(GetWrapper(ACol, ARow)).CellTextAlign;
end;

procedure TCoolStringGrid.SetCellTextAligns(ACol, ARow: Integer; Value: TAlignment);
begin
  TCellWrapper(GetWrapper(ACol, ARow)).CellTextAlign := Value;
  InvalidateCell(ACol, ARow);
end;

function TCoolStringGrid.GetWrapper(ACol, ARow: Integer): TObject;
begin
  Result := ExtractWrapper(ACol, ARow);
  if Result = nil then
    Result := CreateWrapper(ACol, ARow);
end;

function TCoolStringGrid.ExtractWrapper(ACol, ARow: Integer): TObject;
var
  I: Integer;
begin
  Result := nil;

  for I := 0 to FWrappers.Count-1 do
    if (TCellWrapper(FWrappers[I]).Col = ACol) and (TCellWrapper(FWrappers[I]).Row = ARow) then
    begin
      Result := FWrappers[I];
      Break;
    end;
end;

function TCoolStringGrid.CreateWrapper(ACol, ARow: Integer): TObject;
begin
  Result := TCellWrapper.Create(ACol, ARow, Self);
  TCellWrapper(Result).Font.Assign(Font);
  if (ACol > FixedCols-1) and (ARow > FixedRows-1) then
  begin
    TCellWrapper(Result).CellTextAlign := FTextAlign;
    TCellWrapper(Result).Color := Color;
  end else
  begin
    TCellWrapper(Result).CellTextAlign := FFixedTextAlign;
    TCellWrapper(Result).Color := FixedColor;
  end;

  FWrappers.Add(Result);
end;

function TCoolStringGrid.HaveWrapper(ACol, ARow: Integer): Boolean;
begin
  Result := ExtractWrapper(ACol, ARow) <> nil;
end;

procedure TCoolStringGrid.WallpaperChanged(Sender: TObject);
begin
  Invalidate;
  Perform(CM_COLORCHANGED, 0, 0);
end;

procedure TCoolStringGrid.NCCtlChanged;
begin
  if HandleAllocated then
    SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_DRAWFRAME or SWP_NOACTIVATE or SWP_NOMOVE or
                                        SWP_NOSIZE or SWP_NOZORDER);
end;

procedure TCoolStringGrid.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolStringGrid.SetidCaptionWallpaper(Value: Integer);
begin
  if FidCaptionWallpaper <> Value then
  begin
    FidCaptionWallpaper := Value;
    NCCtlChanged;
  end;
end;

procedure TCoolStringGrid.SetidSelWallpaper(Value: Integer);
begin
  if FidSelWallpaper <> Value then
  begin
    FidSelWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolStringGrid.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  Invalidate;
  NCCtlChanged;
end;

procedure TCoolStringGrid.SetCellMarginTop(Value: Integer);
begin
  if FCellMarginTop <> Value then
  begin
    FCellMarginTop := Value;
    Invalidate;
  end;
end;

procedure TCoolStringGrid.SetCellMarginLeft(Value: Integer);
begin
  if FCellMarginLeft <> Value then
  begin
    FCellMarginLeft := Value;
    Invalidate;
  end;
end;

procedure TCoolStringGrid.SetCellMarginRight(Value: Integer);
begin
  if FCellMarginRight <> Value then
  begin
    FCellMarginRight := Value;
    Invalidate;
  end;
end;

procedure TCoolStringGrid.SetCellMarginBottom(Value: Integer);
begin
  if FCellMarginBottom <> Value then
  begin
    FCellMarginBottom := Value;
    Invalidate;
  end;
end;

function TCoolStringGrid.IsWallpaperAssigned: Boolean;
begin
  Result := (Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty) or
            (Assigned(FWallpaper) and not FWallpaper.Empty);
end;

function TCoolStringGrid.IsSelWallpaperAssigned: Boolean;
begin
  Result := (Assigned(FCoolImages) and (FidSelWallpaper >= 0) and (FidSelWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidSelWallpaper].Bitmap) and not FCoolImages.Images.Items[FidSelWallpaper].Bitmap.Empty) or
            (Assigned(FSelWallpaper) and not FSelWallpaper.Empty);
end;

function TCoolStringGrid.CTLDrawCaptionWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidCaptionWallpaper >= 0) and (FidCaptionWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidCaptionWallpaper].Bitmap) and
    not FCoolImages.Images.Items[FidCaptionWallpaper].Bitmap.Empty then
    begin
      DrawWallpaper(DC, FCoolImages.Images.Items[FidCaptionWallpaper].Bitmap, R, IsStretch, Mode);
      Result := True;
    end else
    if Assigned(FCaptionWallpaper) and not FCaptionWallpaper.Empty then
    begin
      DrawWallpaper(DC, FCaptionWallpaper, R, IsStretch, Mode);
      Result := True;
    end;
end;

function TCoolStringGrid.CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaper(DC, FWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

function TCoolStringGrid.CTLDrawWallpaperEx(DC: HDC; R, SubRect: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaperEx(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, SubRect, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaperEx(DC, FWallpaper, R, SubRect, IsStretch, Mode);
    Result := True;
  end;
end;

function TCoolStringGrid.CTLDrawSelWallpaperEx(DC: HDC; R, SubRect: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidSelWallpaper >= 0) and (FidSelWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidSelWallpaper].Bitmap) and not FCoolImages.Images.Items[FidSelWallpaper].Bitmap.Empty then
  begin
    DrawWallpaperEx(DC, FCoolImages.Images.Items[FidSelWallpaper].Bitmap, R, SubRect, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FSelWallpaper) and not FSelWallpaper.Empty then
  begin
    DrawWallpaperEx(DC, FSelWallpaper, R, SubRect, IsStretch, Mode);
    Result := True;
  end;
end;

procedure TCoolStringGrid.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FCoolImages) and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

procedure TCoolStringGrid.CoolImagesChange(Sender: TObject);
begin
  NCCtlChanged;
  Invalidate;
end;

procedure TCoolStringGrid.SetEditText(ACol, ARow: Longint; const Value: string);
begin
  inherited SetEditText(ACol, ARow, Value);
  if EditValue <> Cells[ACol, ARow] then
    PostMessage(Handle, CM_ENDEDITING, ACol, ARow);
end;

function TCoolStringGrid.GetEditText(ACol, ARow: Longint): string;

  procedure DrawWallpaperExOld(DC: HDC; Bitmap: TBitmap; Recty, SubRect: TRect; IsStretch: Boolean; Mode: Integer);
  var
    TempBmp: TBitmap;
  begin
    if EqualRect(SubRect, Recty) or not IsStretch then
      DrawWallpaper(DC, Bitmap, SubRect, IsStretch, Mode) else
      begin
        TempBmp := TBitmap.Create;
        try
          TempBmp.Width := Recty.Right - Recty.Left;
          TempBmp.Height := Recty.Bottom - Recty.Top;
          {$IFNDEF VER90}
          TempBmp.PixelFormat := pf24bit;
          {$ENDIF}

          DrawWallpaper(TempBmp.Canvas.Handle, Bitmap, Recty, (ocStretchWallpaper in FExOptions), Mode);
          BitBlt(DC, SubRect.Left, SubRect.Top, SubRect.Right - SubRect.Left, SubRect.Bottom - SubRect.Top, TempBmp.Canvas.Handle, SubRect.Left, SubRect.Top, SRCCOPY);
        finally
          TempBmp.Free;
        end;
      end;
  end;

var
  TmpW, W: TBitmap;
begin
  Result := inherited GetEditText(ACol, ARow);

  EditValue := Result;

  TCoolInplaceEdit(InplaceEditor).Color := Color;
  TCoolInplaceEdit(InplaceEditor).Font := Font;
  TCoolInplaceEdit(InplaceEditor).Options := FExOptions - [ocFlatBorder];
  TCoolInplaceEdit(InplaceEditor).Wallpaper.Assign(nil);

  if HaveWrapper(ACol, ARow) and not WallpaperForCells[ACol, ARow] then
  begin
    TCoolInplaceEdit(InplaceEditor).Color := Colors[ACol, ARow];
    TCoolInplaceEdit(InplaceEditor).Font := Fonts[ACol, ARow];
  end else
  if IsWallpaperAssigned and (ocPaintWallpaper in FExOptions) then
  begin
    TmpW := TBitmap.Create;
    try
      W := TBitmap.Create;
      try
        TmpW.Width := ClientWidth;
        TmpW.Height := ClientHeight;

        CTLDrawWallpaper(TmpW.Canvas.Handle, ClientRect, (ocStretchWallpaper in FExOptions), SRCCOPY);
        W.Width := CellRect(ACol, ARow).Right - CellRect(ACol, ARow).Left;
        W.Height := CellRect(ACol, ARow).Bottom - CellRect(ACol, ARow).Top;
        W.Canvas.CopyRect(Rect(0, 0, W.Width, W.Height), TmpW.Canvas, CellRect(ACol, ARow));

        TCoolInplaceEdit(InplaceEditor).Wallpaper.Assign(W);
      finally
        W.Free;
      end;
    finally
      TmpW.Free;
    end;
  end;
end;

function TCoolStringGrid.CreateEditor: TInplaceEdit;
begin
  Result := TCoolInplaceEdit.Create(Self);
end;

function TCoolStringGrid.SelectCell(ACol, ARow: Longint): Boolean;
begin
  Result := inherited SelectCell(ACol, ARow);

  FCanEdit := True;
  if HaveWrapper(ACol, ARow) then
    if (goEditing in Options) or (goAlwaysShowEditor in Options) then
      if ReadOnlyCells[ACol, ARow] then
        FCanEdit := False else
          FCanEdit := True;
end;

function TCoolStringGrid.CanEditShow: Boolean;
begin
  Result := inherited CanEditShow and FCanEdit;
end;

procedure TCoolStringGrid.TopLeftChanged;
begin
  if ((ocPaintWallpaper in FExOptions) and IsWallpaperAssigned) or (ocPaintTransparently in FExOptions) then
    InvalidateRectEx(Handle, ClientRect, False);
  inherited TopLeftChanged;
end;

procedure TCoolStringGrid.ColumnMoved(FromIndex, ToIndex: Longint);
var
  I: Integer;
begin
  for I := 0 to FWrappers.Count-1 do
    with TCellWrapper(FWrappers[I]) do
    begin
      if (Col = FromIndex) then
      begin
        Col := ToIndex;
        Continue;
      end;

      if (FromIndex < Col) and (Col <= ToIndex) then
      begin
        Col := Pred(Col);
        Continue;
      end;

      if (FromIndex > Col) and (Col >= ToIndex) then
      begin
        Col := Succ(Col);
        Continue;
      end;
    end;

  inherited ColumnMoved(FromIndex, ToIndex);
end;

procedure TCoolStringGrid.RowMoved(FromIndex, ToIndex: Longint);
var
  I: Integer;
begin
  for I := 0 to FWrappers.Count-1 do
    with TCellWrapper(FWrappers[I]) do
    begin
      if (Row = FromIndex) then
      begin
        Row := ToIndex;
        Continue;
      end;

      if (FromIndex < Row) and (Row <= ToIndex) then
      begin
        Row := Pred(Row);
        Continue;
      end;

      if (FromIndex > Row) and (Row >= ToIndex) then
      begin
        Row := Succ(Row);
        Continue;
      end;
    end;

  inherited RowMoved(FromIndex, ToIndex);
end;

procedure TCoolStringGrid.AdjustSize(Index, Amount: Longint; Rows: Boolean);
begin
  inherited AdjustSize(Index, Amount, Rows);
end;

procedure TCoolStringGrid.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
const
{$IFNDEF DELPHI4_OR_ABOVE}
  FInnerEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER);
  FOuterEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER);
{$ELSE}
  FInnerEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER, 0);
  FOuterEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER, 0);
{$ENDIF}
var
  R: TRect;
  ASelected: Boolean;
  AAlign: TAlignment;
  Mode,tWidth, tHeight: Integer;
begin
  with Canvas do
  begin
    if HaveWrapper(ACol, ARow) then
    begin
      Brush.Color := Colors[ACol, ARow];
      Canvas.Font := Fonts[ACol, ARow];
      AAlign := CellTextAligns[ACol, ARow];
    end else
    begin
      if AState = [gdFixed] then
        AAlign := FFixedTextAlign else
        AAlign := FTextAlign;
    end;

    case AAlign of
      taLeftJustify:
        Mode := DT_LEFT or DT_WORDBREAK;
      taRightJustify:
        Mode := DT_RIGHT or DT_WORDBREAK;
      taCenter:
        Mode := DT_CENTER or DT_WORDBREAK;
      else
        Mode := 0;
    end;

    if ((goDrawFocusSelected in Options) or (goRowSelect in Options)) and ((AState = [gdSelected..gdFocused]) or (AState = [gdSelected])) then
    begin
      Font.Color := clHighlightText;
      Brush.Color := SelColor;
      ASelected := True;
    end else
    if (AState = [gdSelected]) then
    begin
      Font.Color := clHighlightText;
      Brush.Color := SelColor;
      ASelected := True;
    end else
    begin
      ASelected := False;
    end;

    if not ASelected then
    begin
      if (ocPaintTransparently in FExOptions) and (AState <> [gdFixed]) and not ASelected then
        PaintBackgroundEx(TrControl(Self, FTransparencyLevel), Handle, ARect, True) else
          if (AState <> [gdFixed]) and (ocPaintWallpaper in FExOptions) and IsWallpaperAssigned and (not HaveWrapper(ACol, ARow) or (HaveWrapper(ACol, ARow) and WallpaperForCells[ACol, ARow])) then
            CTLDrawWallpaperEx(Handle, ClientRect, ARect, (ocStretchWallpaper in FExOptions), SRCCOPY) else
              FillRect(ARect);
    end else
    if (AState <> [gdFixed]) then
    begin
      if (ocInvertWallpaperAsSelect in FExOptions) and IsWallpaperAssigned then
        CTLDrawWallpaperEx(Handle, ClientRect, ARect, (ocStretchWallpaper in FExOptions), NOTSRCCOPY) else
          if (ocPaintSelWallpaper in FExOptions) and IsSelWallpaperAssigned then
            CTLDrawSelWallpaperEx(Handle, ClientRect, ARect, True, SRCCOPY) else
              FillRect(ARect);
    end;

    if AState <> [gdFixed] then
      DrawEdge(Handle, ARect, FInnerEdges[FInnerCellsBevel] or FOuterEdges[FOuterCellsBevel], BF_RECT);

//--------------------------------------------------
    R := Rect(0, 0, ColWidths[ACol], 0);

    DrawText(Handle, PChar(Cells[ACol, ARow]), Length(Cells[ACol, ARow]), R, Mode or DT_CALCRECT);
    tHeight := (R.Bottom - R.Top);
    tWidth := (R.Right - R.Left);

    if tWidth > ColWidths[ACol] then
      ColWidths[ACol] := tWidth + 10;

    if tHeight > RowHeights[ARow] then
      RowHeights[ARow] := tHeight + 10;
//--------------------------------------------------

    R := ARect;
    InflateRectEx(R, FCellMarginLeft, FCellMarginTop, FCellMarginRight, FCellMarginBottom);
    SetBkMode(Handle, TRANSPARENT);

    if not Enabled then
      SetTextColor(Handle, ColorToRGB(clGray));

    if not Enabled then
      Draw3DText(Handle, R, {$IFDEF BCB}{$IFDEF VER100}SPToInt({$ENDIF}{$ENDIF} spRightBottom {$IFDEF BCB}{$IFDEF VER100}){$ENDIF}{$ENDIF}, PChar(Cells[ACol, ARow]), Mode, clBtnShadow, clBtnHighlight, 1) else
        DrawText(Handle, PChar(Cells[ACol, ARow]), Length(Cells[ACol, ARow]), R, Mode);

    // Restore!
    Font.Assign(Self.Font);
  end;

  if Assigned(OnDrawCell) then
    OnDrawCell(Self, ACol, ARow, ARect, AState);
end;

procedure TCoolStringGrid.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);

  with Params do
  begin
    if not (ocNoCaption in FExOptions) then
      Style := Style or WS_CAPTION else
        Style := Style and not WS_CAPTION;

    if ocSmallCaption in FExOptions then
      ExStyle := ExStyle or WS_EX_TOOLWINDOW else
        ExStyle := ExStyle and not WS_EX_TOOLWINDOW;
  end;
end;

procedure TCoolStringGrid.SetParent(AParent: TWinControl);
begin
  inherited SetParent(AParent);
end;

procedure TCoolStringGrid.DeleteRows(RowIndex, Amount : LongInt);
var
  I: LongInt;
begin
  for I := Pred(Amount + RowIndex) downto RowIndex do
    DeleteRow(I);
end;

procedure TCoolStringGrid.InsertRows(RowIndex, Amount : LongInt);
var
  I: LongInt;
begin
  RowCount := RowCount + Amount;
  for I := RowCount-1 downto RowIndex+Amount do
    MoveRow(I-Amount, I);
end;

procedure TCoolStringGrid.DeleteCols(ColIndex, Amount: LongInt);
var
  I: LongInt;
begin
  for I := Pred(Amount + ColIndex) downto ColIndex do
    DeleteColumn(I);
end;

procedure TCoolStringGrid.InsertCols(ColIndex, Amount: LongInt);
var
  I: LongInt;
begin
  ColCount := ColCount + Amount;
  for I := ColCount-1 downto ColIndex+Amount do
    MoveColumn(I-Amount, I);
end;

procedure TCoolStringGrid.Clear;
var
  I: LongInt;
begin
  for I := 0 to ColCount - 1 do
    Cols[I].Clear;
end;

function TCoolStringGrid.PosCell(SubStr: string; var ACol, ARow: LongInt): Boolean;
var
  I, J: LongInt;
begin
  Result := False;
  for I := 0 to RowCount-1 do
    for J := 0 to ColCount-1 do
      if CompareText(Rows[I].Strings[J], SubStr) = 0 then
      begin
        Result := True;
        ARow := I;
        ACol := J;
        Break;
      end;
end;

procedure TCoolStringGrid.SaveToStream(AStream: TStream);
var
  I, J: LongInt;
begin
  with TWriter.Create(AStream, 4096) do
  try
    for I := 0 to Pred(ColCount) do
      for J := 0 to Pred(RowCount) do
        if Cells[I, J] <> '' then
        begin
          WriteInteger(I);
          WriteInteger(J);
          WriteString(Cells[I, J]);
        end;
  finally
    Free;
  end;
end;

procedure TCoolStringGrid.LoadFromStream(AStream: TStream);
var
  I, J: LongInt;
begin
  with TReader.Create(AStream, 4096) do
  try
    while Position < Pred(AStream.Size) do
    begin
      I := ReadInteger;
      J := ReadInteger;
      Cells[I, J] := ReadString;
    end;
  finally
    Free;
  end;
end;

procedure TCoolStringGrid.SaveToFile(AFileName: String);
var
  Stream: TFileStream;
begin
  Stream := TFileStream.Create(AFileName, fmCreate);
  try
    SaveToStream(Stream);
  finally
    Stream.Free;
  end;
end;

procedure TCoolStringGrid.LoadFromFile(AFileName: String);
var
  Stream: TFileStream;
begin
  Stream := TFileStream.Create(AFileName, fmOpenRead);
  try
    LoadFromStream(Stream);
  finally
    Stream.Free;
  end;
end;

procedure TCoolStringGrid.SaveToHTMLFile(AFileName: string);
var
  F: TextFile;
  I, J: LongInt;
  AlignStr, S: string;
begin
  AssignFile(F, AFileName);
  try
    Rewrite(F);

    Writeln(F, '<HTML>');
    Writeln(F, '<BODY>');
    Writeln(F);
    Writeln(F, '<TABLE CELLPADDING="1" CELLSPACING="1" WIDTH=' + IntToStr(Width) + ' HEIGHT=' + IntToStr(Height) + ' BORDER="1">');

    for I := 0 to RowCount-1 do
      for J := 0 to ColCount-1 do
      begin
        if J = 0 then
          Writeln(F, '<TR>');

        if Cells[J, I] = '' then
          S := '&nbsp;' else
            S := Cells[J, I];

        if (J < FixedCols) or (I < FixedRows) then
          case FixedTextAlign of
            taLeftJustify:
              AlignStr := ' ALIGN="LEFT"';
            taRightJustify:
              AlignStr := ' ALIGN="RIGHT"';
            taCenter:
              AlignStr := ' ALIGN="CENTER"';
          end else
          case TextAlign of
            taLeftJustify:
              AlignStr := ' ALIGN="LEFT"';
            taRightJustify:
              AlignStr := ' ALIGN="RIGHT"';
            taCenter:
              AlignStr := ' ALIGN="CENTER"';
          end;

        Writeln(F, '<TD BGCOLOR="#' + IntToHex(ColorToRGB(Colors[J, I]), 6) + '" WIDTH="' +
                   IntToStr(CellRect(J, I).Right - CellRect(J, I).Left) + '" HEIGHT="' +
                   IntToStr(CellRect(J, I).Bottom - CellRect(J, I).Top) + '"' + AlignStr + '>' +
                   S + '</TD>');

        if J = ColCount-1 then
          Writeln(F, '</TR>');
      end;

    Writeln(F, '</TABLE>');
    Writeln(F);    
    Writeln(F, '</BODY>');
    Writeln(F, '</HTML>');
  finally
    CloseFile(F);
  end;
end;

procedure TCoolStringGrid.CopyToClipboard;
var
  Stream: TMemoryStream;
  hbuf: THandle;
  bufptr: Pointer;
begin
  Stream := TMemoryStream.Create;
  try
    SaveToStream(Stream);
    hbuf := GlobalAlloc(GMEM_MOVEABLE, Stream.size);
    try
      bufptr := GlobalLock(hbuf);
      try
        Move(Stream.Memory^, bufptr^, Stream.size);
        Clipboard.SetAsHandle(FGridFormat, hbuf);
      finally
        GlobalUnlock(hbuf);
      end;
    except
      GlobalFree(hbuf);
      raise;
    end;
  finally
    Stream.Free;
  end;
end;

procedure TCoolStringGrid.PasteFromClipboard;
var
  Stream: TMemoryStream;
  hbuf: THandle;
  bufptr: Pointer;
begin
  hbuf := Clipboard.GetAsHandle(FGridFormat);
  if hbuf <> 0 then
  begin
    bufptr := GlobalLock(hbuf);
    if bufptr <> nil then
    try
      Stream := TMemoryStream.Create;
      try
        Stream.WriteBuffer(bufptr^, GlobalSize(hbuf));
        Stream.Position := 0;
        LoadFromStream(Stream);
      finally
        Stream.Free;
      end;
    finally
      GlobalUnlock(hbuf);
    end;
  end;
end;

procedure TCoolStringGrid.CopyToClipboardCell(ACol, ARow: LongInt);
begin
  Clipboard.SetTextBuf(PChar(Cells[ACol, ARow]));
end;

procedure TCoolStringGrid.CutToClipboardCell(ACol, ARow: LongInt);
begin
  CopyToClipboardCell(ACol, ARow);
  Cells[ACol, ARow] := '';
end;

procedure TCoolStringGrid.PasteFromClipboardCell(ACol, ARow: LongInt);
var
  Buff: array[0..65535] of Char;
begin
  Clipboard.GetTextBuf(Buff, Length(Buff));
  Cells[ACol, ARow] := Buff;
end;

procedure TCoolStringGrid.SetColumnParameters(ACol: Longint; AFixedInclude: Boolean; AColor: TColor; AReadOnly, AWallpaperAlloved: Boolean; AFont: TFont; ATextAlign: TAlignment);
var
  K, I: Integer;
begin
  if not AFixedInclude then
    K := FixedCols else
      K := 0;

  for I := K to RowCount-1 do
  begin
    Colors[ACol, I] := AColor;
    ReadOnlyCells[ACol, I] := AReadOnly;
    WallpaperForCells[ACol, I] := AWallpaperAlloved;
    if Assigned(AFont) then
      Fonts[ACol, I] := AFont;
    CellTextAligns[ACol, I] := ATextAlign;
  end;
end;

procedure TCoolStringGrid.SetRowParameters(ARow: Longint; AFixedInclude: Boolean; AColor: TColor; AReadOnly, AWallpaperAlloved: Boolean; AFont: TFont; ATextAlign: TAlignment);
var
  K, I: Integer;
begin
  if not AFixedInclude then
    K := FixedCols else
      K := 0;

  for I := K to ColCount-1 do
  begin
    Colors[I, ARow] := AColor;
    ReadOnlyCells[I, ARow] := AReadOnly;
    WallpaperForCells[I, ARow] := AWallpaperAlloved;
    if Assigned(AFont) then
      Fonts[I, ARow] := AFont;
    CellTextAligns[I, ARow] := ATextAlign;
  end;
end;

procedure TCoolStringGrid.WMPaint(var Message: TWMPaint);
begin
  inherited;

  if (ocFlatBorder in FExOptions) then
    DrawFlatBorder(0, Self, Focused);

  if Assigned(FOnPaint) then
    FOnPaint(Self);
end;

procedure TCoolStringGrid.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
  inherited;
end;

procedure TCoolStringGrid.CMMouseEnter(var Message: TMessage);
begin
  inherited;
  if (ocFlatBorder in FExOptions) and not IsCoolControl(Screen.ActiveControl) then
    DrawFlatBorder(0, Self, True);

  if Assigned(FOnMouseEnter) then
    FOnMouseEnter(Self);
end;

procedure TCoolStringGrid.CMMouseLeave(var Message: TMessage);
begin
  inherited;
  if (ocFlatBorder in FExOptions) and not IsCoolControl(Screen.ActiveControl) then
    DrawFlatBorder(0, Self, False);

  if Assigned(FOnMouseLeave) then
    FOnMouseLeave(Self);
end;

procedure TCoolStringGrid.WMSetFocus(var Message: TWMSetFocus);
begin
  inherited;
  if (ocFlatBorder in FExOptions) then
    DrawFlatBorder(0, Self, True);
end;

procedure TCoolStringGrid.WMKillFocus(var Message: TWMKillFocus);
begin
  inherited;
  if (ocFlatBorder in FExOptions) then
    DrawFlatBorder(0, Self, False);
end;

procedure TCoolStringGrid.WMNCPaint(var Message: TMessage);
var
  WR, R: TRect;
  MyDC: HDC;
  MyRgn: HRGN;
  MyFont: HFONT;
  MyBrush: HBRUSH;
  DeleteRgn: Boolean;
  NCM: TNonClientMetrics;
begin
  if not (ocNoCaption in FExOptions) and ( (FCaptionColor <> clInactiveCaption) or (FCaptionTextColor <> clInactiveCaptionText) or (ocPaintCaptionWallpaper in FExOptions) ) then
  begin
    DeleteRgn := FALSE;
    MyRgn := Message.wParam;

    MyDC := GetWindowDC(Handle);
    try
      GetWindowRect(Handle, WR);

      if SelectClipRgn(MyDC, MyRgn) = ERROR then
        with WR do
        begin
          MyRgn := CreateRectRgn(Left, Top, Right, Bottom);
          SelectClipRgn(MyDC, MyRgn);
          DeleteRgn := TRUE;
        end;

      OffsetClipRgn(MyDC, -WR.Left, -WR.Top);
      GetWindowRect(Handle, R);
      OffsetRect(R, -R.Left, -R.Top);
      InflateRect(R, -GetSystemMetrics(SM_CXFIXEDFRAME),  -GetSystemMetrics(SM_CYFIXEDFRAME));
      if (ocSmallCaption in FExOptions) then
        R.Bottom := R.Top + GetSystemMetrics(SM_CYSMCAPTION)-1 else
          R.Bottom := R.Top + GetSystemMetrics(SM_CYCAPTION)-1;

      MyBrush := CreateSolidBrush(ColorToRGB(FCaptionColor));
      try
        if not (ocPaintCaptionWallpaper in FExOptions) then
          FillRect(MyDC, R, MyBrush) else
            CTLDrawCaptionWallpaper(MyDC, R, True, SRCCOPY);

        NCM.cbSize := SizeOf(NCM);
        SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @NCM, 0);
        if (ocSmallCaption in FExOptions) then
          MyFont := CreateFontIndirect(NCM.lfSmCaptionFont) else
            MyFont := CreateFontIndirect(NCM.lfCaptionFont);
        try
          SelectObject(MyDC, MyFont);
          OffsetRect(R, 2, 0);
          try
            SetTextColor(MyDC, ColorToRGB(FCaptionTextColor));
            SetBkMode(MyDC, Transparent);
            DrawText(MyDC, PChar(Caption), -1, R, DT_LEFT or DT_VCENTER or DT_SINGLELINE);
          finally
            OffsetRect(R, -2, 0);
          end;
        finally
          DeleteObject(MyFont);
        end;
      finally
        DeleteObject(MyBrush);
      end;

      ExcludeClipRect(MyDC, R.Left, R.Top, R.Right, R.Bottom);
      OffsetClipRgn(MyDC, WR.Left, WR.Top);
      GetClipRgn(MyDC, MyRgn);
      Message.Result := DefWindowProc(Handle, Message.Msg, MyRgn, Message.lParam);

    finally
      if DeleteRgn then DeleteObject(MyRgn);
      ReleaseDC(Handle, MyDC);
    end;
  end else inherited;
end;

procedure TCoolStringGrid.WMNCLButtonDblClk(var Message: TWMNCLButtonDblClk);
begin
  if Message.HitTest = Windows.htCaption then
    Message.HitTest := Windows.htNoWhere else
      inherited;
end;

procedure TCoolStringGrid.WMNCHitTest(var Message: TWMNCHitTest);
begin
  inherited;
  if (Message.Result = Windows.htCaption) and (ocNoDragUsingCaption in FExOptions) then
    Message.Result := Windows.htNowhere;
end;

procedure TCoolStringGrid.CMParentColorChanged(var Message: TMessage);
begin
  inherited;
  if ocPaintTransparently in FExOptions then
    Invalidate;
end;

procedure TCoolStringGrid.CMEnabledChanged(var Message: TMessage);
begin
  inherited;
  Invalidate;
end;

procedure TCoolStringGrid.WMMove(var Message: TWMMove);
begin
  inherited;
  Invalidate;
end;

procedure TCoolStringGrid.WMSetText(var Message: TMessage);
begin
  inherited;
  NCCtlChanged;
end;

procedure TCoolStringGrid.CMEndEditing(var Message: TMessage);
var
  W, H: Integer;
begin
  if not EditorMode then
  begin
    W := DefaultColWidth;
    H := DefaultRowHeight;

    if Assigned(FOnEndCellEditing) then
      FOnEndCellEditing(Self, Message.wParam, Message.lParam, W, H);

    ColWidths[Message.wParam] := W;
    RowHeights[Message.lParam] := H;
  end;
end;

{TCoolEdit}
constructor TCoolEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FTextAlign := taLeftJustify;
  FBeingPainted := False;

  FBorderPen := TPen.Create;
  FBorderPen.OnChange := BorderPenChange;

  FOptions := [];
  FEdgeBorders := [];
  FBordersTrColor := clNone;

  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;
  FidWallpaper := -1;
end;

destructor TCoolEdit.Destroy;
begin
  FBorderPen.Free;
  FCoolImagesChangeLink.Free;
  if Assigned(FWallpaper) then FWallpaper.Free;
  inherited Destroy;
end;

procedure TCoolEdit.CreateWnd;
begin
  inherited CreateWnd;
end;

procedure TCoolEdit.CreateParams(var Params: TCreateParams);
const
   Alignments: array [TAlignment] of DWord = (ES_LEFT, ES_RIGHT, ES_CENTER);
begin
  inherited CreateParams(Params);
  with Params do
    Style := Params.Style or ES_MULTILINE or Alignments[FTextAlign];
end;

procedure TCoolEdit.SetParent(AParent: TWinControl);
begin
  inherited SetParent(AParent);
end;

procedure TCoolEdit.SetOptions(Value: TCoolOptions);
begin
  if FOptions <> Value then
  begin
    if (ocPaintTransparently in Value) and (ocPaintWallpaper in FOptions) then
      Exclude(Value, ocPaintWallpaper) else
        if (ocPaintWallpaper in Value) and (ocPaintTransparently in FOptions) then
          Exclude(Value, ocPaintTransparently);

    FOptions := Value;
    RecreateWnd;
    Perform(CM_COLORCHANGED, 0, 0);
  end;
end;

procedure TCoolEdit.SetTextAlign(Value: TAlignment);
begin
  if FTextAlign <> Value then
  begin
    FTextAlign := Value;
    RecreateWnd;
  end;
end;

procedure TCoolEdit.SetTransparencyLevel(Value: Byte);
begin
  if FTransparencyLevel <> Value then
  begin
    FTransparencyLevel := Value;
    Invalidate;
  end;
end;

procedure TCoolEdit.SetBorderPen(Value: TPen);
begin
  FBorderPen.Assign(Value);
end;

procedure TCoolEdit.SetBordersTrColor(Value: TColor);
begin
  if FBordersTrColor <> Value then
  begin
    FBordersTrColor := Value;
    Invalidate;
  end;
end;

procedure TCoolEdit.SetEdgeBorders(Value: TEdgeBorders);
begin
  if FEdgeBorders <> Value then
  begin
    FEdgeBorders := Value;
    Invalidate;
  end;
end;

procedure TCoolEdit.BorderPenChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolEdit.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  FWallpaper.Assign(Value);
  Invalidate;
end;

function TCoolEdit.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolEdit.WallpaperChanged(Sender: TObject);
begin
  Invalidate;
  Perform(CM_COLORCHANGED, 0, 0);
end;

procedure TCoolEdit.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolEdit.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  Invalidate;
end;

function TCoolEdit.CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaper(DC, FWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

function TCoolEdit.IsWallpaperAssigned: Boolean;
begin
  Result := (Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty) or
            (Assigned(FWallpaper) and not FWallpaper.Empty);
end;

procedure TCoolEdit.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FCoolImages) and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

procedure TCoolEdit.CoolImagesChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolEdit.WndProc(var Message: TMessage);
begin
  inherited WndProc(Message);
end;

procedure TCoolEdit.DoPaint;
const
  BorderOffsets: array[TBorderStyle] of Integer = (1, -1);
var
  MyDC: HDC;
  TempDC: HDC;
  OldBmp, TempBmp: HBITMAP;
begin
  FBeingPainted := True;

  if ((ocPaintWallpaper in FOptions) and IsWallpaperAssigned) or (ocPaintTransparently in FOptions) then
  begin
    HideCaret(Handle);
    try
      MyDC := GetDC(Handle);
      try
        TempDC := CreateCompatibleDC(MyDC);
        try
          TempBmp := CreateCompatibleBitmap(MyDC, Succ(ClientWidth), Succ(ClientHeight));
          try
            OldBmp := SelectObject(TempDC, TempBmp);

            PaintTo(TempDC, 0, 0);

            if (ocFlatBorder in FOptions) then
              DrawFlatBorder(TempDC, Self, True);

            BitBlt(MyDC, BorderOffsets[BorderStyle], BorderOffsets[BorderStyle], ClientWidth, ClientHeight, TempDC, 1, 1, SRCCOPY);

            SelectObject(TempDC, OldBmp);
          finally
            DeleteObject(TempBmp);
          end;
        finally
          DeleteDC(TempDC);
        end;
      finally
        ReleaseDC(Handle, MyDC);
      end;
    finally
      ShowCaret(Handle);
    end;
  end;

  FBeingPainted := False;
end;

procedure TCoolEdit.Change;
begin
  DoPaint;
  inherited Change;
end;

procedure TCoolEdit.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited KeyDown(Key, Shift);
  FReturnWanted := (Key = VK_RETURN) and (Shift = [ssCtrl]);
end;

procedure TCoolEdit.KeyUp(var Key: Word; Shift: TShiftState);
begin
  inherited KeyUp(Key, Shift);
end;

procedure TCoolEdit.KeyPress(var Key: Char);
begin
  inherited KeyPress(Key);
  if (Key = Char(VK_RETURN)) or FReturnWanted then
  begin
    Key := #0;
    MessageBeep(0);
  end;
end;

procedure TCoolEdit.CMMouseEnter (var Message: TMessage);
begin
  inherited;
  if (ocFlatBorder in FOptions) and not IsCoolControl(Screen.ActiveControl) then
    DrawFlatBorder(0, Self, True);

  if Assigned(FOnMouseEnter) then
    FOnMouseEnter(Self);
end;

procedure TCoolEdit.CMMouseLeave (var Message: TMessage);
begin
  inherited;
  if (ocFlatBorder in FOptions) and not IsCoolControl(Screen.ActiveControl) then
    DrawFlatBorder(0, Self, False);

  if Assigned(FOnMouseLeave) then
    FOnMouseLeave(Self);
end;

procedure TCoolEdit.WMSetFocus(var Message: TWMSetFocus);
begin
  inherited;
  if AutoSelect and not (csLButtonDown in ControlState) then
    SelectAll;

  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, True);
end;

procedure TCoolEdit.WMKillFocus(var Message: TWMKillFocus);
begin
  inherited;
  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, False);
end;

procedure TCoolEdit.WMEraseBkGnd(var Message: TWMEraseBkGnd);
begin
  if (ocPaintTransparently in FOptions) then
    PaintBackground(TrControl(Self, FTransparencyLevel), Message.DC, True) else
      if (ocPaintWallpaper in FOptions) and IsWallpaperAssigned then
        CTLDrawWallpaper(Message.DC, ClientRect, (ocStretchWallpaper in FOptions), SRCCOPY) else
          inherited;
end;

procedure TCoolEdit.WMPaint(var Message: TWMPaint);
begin
  inherited;

  if (ocPaintTransparently in FOptions) or ((ocPaintWallpaper in FOptions) and IsWallpaperAssigned) then
    if not FBeingPainted then
      DoPaint;

  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, Focused);

  DrawBorders(Message.DC, Self, FEdgeBorders, FBorderPen, FBordersTrColor);
end;

procedure TCoolEdit.WMNCPaint(var Message: TMessage);
begin
  inherited;
end;

procedure TCoolEdit.CNCtlColorEdit(var Message: TWMCtlColorEdit);
begin
  inherited;
  if ((ocPaintWallpaper in FOptions) and IsWallpaperAssigned) or (ocPaintTransparently in FOptions) then
    SetBkMode(Message.ChildDC, TRANSPARENT);
end;

procedure TCoolEdit.CNCtlColorStatic(var Message: TWMCtlColorStatic);
begin
  inherited;
  if ((ocPaintWallpaper in FOptions) and IsWallpaperAssigned) or (ocPaintTransparently in FOptions) then
    SetBkMode(Message.ChildDC, TRANSPARENT);
end;

procedure TCoolEdit.CMParentColorChanged(var Message: TMessage);
begin
  inherited;
  if ocPaintTransparently in FOptions then
    Invalidate;
end;

procedure TCoolEdit.WMSize(var Message: TWMSize);
begin
  inherited;
end;

procedure TCoolEdit.WMMove(var Message: TWMMove);
begin
  inherited;
  Invalidate;
end;

{TCoolEditBtn}
constructor TCoolEditBtn.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FButton := TSpeedButton.Create(Self);
  FButton.Height := Height;
  FButton.Width := Height;
  FButton.Visible := True;
  FButton.Cursor := crArrow;
  FButton.OnClick := BtnClick;
  FButton.Parent := Self;
end;

destructor TCoolEditBtn.Destroy;
begin
  FButton.Free;
  inherited Destroy;
end;

procedure TCoolEditBtn.CreateWnd;
begin
  inherited CreateWnd;
  SetEditRect;
end;

procedure TCoolEditBtn.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.Style := Params.Style or WS_CLIPCHILDREN;
end;

procedure TCoolEditBtn.SetEditRect;
var
  Loc: TRect;
begin
  Loc := ClientRect;
  InflateRectEx(Loc, 2, 0, -FButton.Height-2, 0);
  SendMessage(Handle, EM_SETRECTNP, 0, LongInt(@Loc));
end;

function TCoolEditBtn.GetGlyph: TBitmap;
begin
  Result := FButton.Glyph;
end;

procedure TCoolEditBtn.SetGlyph(Value: TBitmap);
begin
  FButton.Glyph.Assign(Value);
end;

function TCoolEditBtn.GetBtnCaption: TCaption;
begin
  Result := FButton.Caption;
end;

procedure TCoolEditBtn.SetBtnCaption(Value: TCaption);
begin
  if FButton.Caption <> Value then
    FButton.Caption := Value;
end;

function TCoolEditBtn.GetNumGlyphs: TNumGlyphs;
begin
  Result := FButton.NumGlyphs;
end;

procedure TCoolEditBtn.SetNumGlyphs(Value: TNumGlyphs);
begin
  if FButton.NumGlyphs <> Value then
    FButton.NumGlyphs := Value;
end;

procedure TCoolEditBtn.BtnClick(Sender: TObject);
begin
  if Assigned(FOnBtnClick) then FOnBtnClick(Self);
end;

{$IFDEF DELPHI4_OR_ABOVE}
procedure TCoolEditBtn.ActionChange(Sender: TObject; CheckDefaults: Boolean);

  procedure CopyImage(ImageList: TCustomImageList; Index: Integer);
  begin
    with Glyph do
    begin
      Width := ImageList.Width;
      Height := ImageList.Height;
      Canvas.Brush.Color := clFuchsia;//! for lack of a better color
      Canvas.FillRect(Rect(0,0, Width, Height));
      ImageList.Draw(Canvas, 0, 0, Index);
    end;
  end;

begin
  inherited ActionChange(Sender, CheckDefaults);
  if Sender is TCustomAction then
    with TCustomAction(Sender) do
    begin
      { Copy image from action's imagelist }
      if (Glyph.Empty) and (ActionList <> nil) and (ActionList.Images <> nil) and
        (ImageIndex >= 0) and (ImageIndex < ActionList.Images.Count) then
        CopyImage(ActionList.Images, ImageIndex);
    end;
end;
{$ENDIF}

procedure TCoolEditBtn.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited KeyDown(Key, Shift);
  if FReturnWanted then BtnClick(Self);
end;

procedure TCoolEditBtn.WMSize(var Message: TWMSize);
var
  MinHeight: Integer;
begin
  inherited;
  MinHeight := GetMinHeight;

  if Height < MinHeight then
    Height := MinHeight else
      if FButton <> nil then
      begin
        if NewStyleControls then
          FButton.SetBounds(Width - FButton.Width - 4, 0, FButton.Width, Height - 4) else
            FButton.SetBounds (Width - FButton.Width, 1, FButton.Width, Height - 3);

        SetEditRect;
      end;
end;

function TCoolEditBtn.GetMinHeight: Integer;
var
  DC: HDC;
  I: Integer;
  SaveFont: HFont;
  SysMetrics, Metrics: TTextMetric;
begin
  DC := GetDC(0);
  try
    GetTextMetrics(DC, SysMetrics);
    SaveFont := SelectObject(DC, Font.Handle);
    GetTextMetrics(DC, Metrics);
    SelectObject(DC, SaveFont);
  finally
    ReleaseDC(0, DC);
  end;

  I := SysMetrics.tmHeight;
  if I > Metrics.tmHeight then I := Metrics.tmHeight;
  Result := Metrics.tmHeight + I div 4 + GetSystemMetrics(SM_CYBORDER) * 4 + 2;
end;

{TCoolMemo}
constructor TCoolMemo.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := ControlStyle + [csSetCaption];
  FTextAlign := taLeftJustify;
  FCaptionColor := clInactiveCaption;
  FCaptionTextColor := clInactiveCaptionText;
  FOptions := [ocNoCaption];
  FBeingPainted := False;
  FOldSelStart := -1;

  FBorderPen := TPen.Create;
  FBorderPen.OnChange := BorderPenChange;

  FEdgeBorders := [];
  FBordersTrColor := clNone;

  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;

  FidWallpaper := -1;
  FidCaptionWallpaper := -1;
  Caption := Name;
end;

destructor TCoolMemo.Destroy;
begin
  FCoolImagesChangeLink.Free;
  FBorderPen.Free;
  if Assigned(FWallpaper) then FWallpaper.Free;
  if Assigned(FCaptionWallPaper) then FCaptionWallPaper.Free;
  inherited Destroy;
end;

procedure TCoolMemo.SetFocus;
var
  {$IFNDEF VER90}
  ParentForm: TCustomForm;
  {$ELSE}
  ParentForm: TForm;
  {$ENDIF}
begin
  {$IFNDEF VER90}
  if Parent is TCustomForm then
  {$ELSE}
  if Parent is TForm then
  {$ENDIF}
    ParentForm := GetParentForm(Self)
  else
    ParentForm := nil;

  if ParentForm <> nil then
    ParentForm.FocusControl(Self)
  else
    Windows.SetFocus(Handle);
end;

procedure TCoolMemo.CreateWnd;
begin
  inherited CreateWnd;
end;

procedure TCoolMemo.CreateParams(var Params: TCreateParams);
const
   Alignments: array [TAlignment] of DWord = (ES_LEFT, ES_RIGHT, ES_CENTER);
begin
  inherited CreateParams(Params);
                      
  with Params do
  begin
    Style := Style or Alignments[FTextAlign];

    if not (ocNoCaption in FOptions) then
      Style := Style or WS_CAPTION else
        Style := Style and not WS_CAPTION;

    if ocSmallCaption in FOptions then
      ExStyle := ExStyle or WS_EX_TOOLWINDOW else
        ExStyle := ExStyle and not WS_EX_TOOLWINDOW;
  end;
end;

procedure TCoolMemo.BorderPenChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolMemo.SetParent(AParent: TWinControl);
begin
  inherited SetParent(AParent);
end;

procedure TCoolMemo.SetOptions(Value: TCoolOptions);
begin
  if FOptions <> Value then
  begin
    if (ocPaintTransparently in Value) and (ocPaintWallpaper in FOptions) then
      Exclude(Value, ocPaintWallpaper) else
        if (ocPaintWallpaper in Value) and (ocPaintTransparently in FOptions) then
          Exclude(Value, ocPaintTransparently);

    FOptions := Value;
    RecreateWnd;
    Perform(CM_COLORCHANGED, 0, 0);
  end;
end;

procedure TCoolMemo.SetTextAlign(Value: TAlignment);
begin
  if FTextAlign <> Value then
  begin
    FTextAlign := Value;
    RecreateWnd;
  end;
end;

procedure TCoolMemo.SetTransparencyLevel(Value: Byte);
begin
  if FTransparencyLevel <> Value then
  begin
    FTransparencyLevel := Value;
    Invalidate;
  end;
end;

procedure TCoolMemo.SetBorderPen(Value: TPen);
begin
  FBorderPen.Assign(Value);
end;

procedure TCoolMemo.SetBordersTrColor(Value: TColor);
begin
  if FBordersTrColor <> Value then
  begin
    FBordersTrColor := Value;
    Invalidate;
  end;
end;

procedure TCoolMemo.SetEdgeBorders(Value: TEdgeBorders);
begin
  if FEdgeBorders <> Value then
  begin
    FEdgeBorders := Value;
    Invalidate;
  end;
end;

procedure TCoolMemo.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  FWallpaper.Assign(Value);
  Invalidate;
end;

function TCoolMemo.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolMemo.SetCaptionWallpaper(Value: TBitmap);
begin
  if FCaptionWallpaper = nil then FCaptionWallpaper := TBitmap.Create;
  FCaptionWallPaper.Assign(Value);
  NCCtlChanged;
end;

function TCoolMemo.GetCaptionWallpaper: TBitmap;
begin
  if FCaptionWallpaper = nil then FCaptionWallpaper := TBitmap.Create;
  Result := FCaptionWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolMemo.WallpaperChanged(Sender: TObject);
begin
  Invalidate;
  Perform(CM_COLORCHANGED, 0, 0);
end;

procedure TCoolMemo.SetCaptionColor(Value: TColor);
begin
  if FCaptionColor <> Value then
  begin
    FCaptionColor := Value;
    NCCtlChanged;
  end;
end;

procedure TCoolMemo.SetCaptionTextColor(Value: TColor);
begin
  if FCaptionTextColor <> Value then
  begin
    FCaptionTextColor := Value;
    NCCtlChanged;
  end;
end;

procedure TCoolMemo.SetCaption(Value: TCaption);
begin
  if FCaption <> Value then
  begin
    FCaption := Value;
    NCCtlChanged;
  end;
end;

function TCoolMemo.GetCaption: TCaption;
begin
  Result := FCaption;
end;

procedure TCoolMemo.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolMemo.SetidCaptionWallpaper(Value: Integer);
begin
  if FidCaptionWallpaper <> Value then
  begin
    FidCaptionWallpaper := Value;
    NCCtlChanged;
  end;
end;

procedure TCoolMemo.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  Invalidate;
  NCCtlChanged;
end;

function TCoolMemo.CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and 
    not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaper(DC, FWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

function TCoolMemo.IsWallpaperAssigned: Boolean;
begin
  Result := (Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty) or
            (Assigned(FWallpaper) and not FWallpaper.Empty);
end;

function TCoolMemo.CTLDrawCaptionWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidCaptionWallpaper >= 0) and (FidCaptionWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidCaptionWallpaper].Bitmap) and
    not FCoolImages.Images.Items[FidCaptionWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidCaptionWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FCaptionWallpaper) and not FCaptionWallpaper.Empty then
  begin
    DrawWallpaper(DC, FCaptionWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

procedure TCoolMemo.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FCoolImages) and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

procedure TCoolMemo.CoolImagesChange(Sender: TObject);
begin
  NCCtlChanged;
  Invalidate;
end;

procedure TCoolMemo.CMMouseEnter (var Message: TMessage);
begin
  inherited;
  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, True);

  if Assigned(FOnMouseEnter) then
    FOnMouseEnter(Self);
end;

procedure TCoolMemo.CMMouseLeave (var Message: TMessage);
begin
  inherited;
  if (ocFlatBorder in FOptions) and not IsCoolControl(Screen.ActiveControl) then
    DrawFlatBorder(0, Self, False);

  if Assigned(FOnMouseLeave) then
    FOnMouseLeave(Self);
end;

procedure TCoolMemo.WMSetFocus(var Message: TWMSetFocus);
begin
  inherited;
  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, True);
end;

procedure TCoolMemo.WMKillFocus(var Message: TWMKillFocus);
begin
  inherited;
  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, False);
end;

procedure TCoolMemo.WMEraseBkGnd(var Message: TWMEraseBkGnd);
begin
  if (ocPaintTransparently in FOptions) then
    PaintBackground(TrControl(Self, FTransparencyLevel), Message.DC, True) else
      if (ocPaintWallpaper in FOptions) and IsWallpaperAssigned then
        CTLDrawWallpaper(Message.DC, ClientRect, (ocStretchWallpaper in FOptions), SRCCOPY) else
          inherited;
end;

procedure TCoolMemo.WMPaint(var Message: TWMPaint);
begin
  inherited;

  if (ocPaintTransparently in FOptions) or ((ocPaintWallpaper in FOptions) and IsWallpaperAssigned) then
    if not FBeingPainted then
      DoPaint;

  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, Focused);

  DrawBorders(Message.DC, Self, FEdgeBorders, FBorderPen, FBordersTrColor);
end;

procedure TCoolMemo.CNCtlColorEdit(var Message: TWMCtlColorEdit);
begin
  inherited;
  if ((ocPaintWallpaper in FOptions) and IsWallpaperAssigned) or (ocPaintTransparently in FOptions) then
    SetBkMode(Message.ChildDC, TRANSPARENT);
end;

procedure TCoolMemo.CNCtlColorStatic(var Message: TWMCtlColorStatic);
begin
  inherited;
  if ((ocPaintWallpaper in FOptions) and IsWallpaperAssigned) or (ocPaintTransparently in FOptions) then
    SetBkMode(Message.ChildDC, TRANSPARENT);
end;

procedure TCoolMemo.CMParentColorChanged(var Message: TMessage);
begin
  inherited;
  if ocPaintTransparently in FOptions then
    Invalidate;
end;

procedure TCoolMemo.WMSize(var Message: TWMSize);
begin
  inherited;
end;

procedure TCoolMemo.WMMove(var Message: TWMMove);
begin
  inherited;
  Invalidate;
end;

procedure TCoolMemo.CNCommand(var Msg: TWMCommand);
begin
  inherited;
end;

procedure TCoolMemo.WMNCLButtonDblClk(var Message: TWMNCLButtonDblClk);
begin
  if Message.HitTest = Windows.htCaption then
    Message.HitTest := Windows.htNoWhere else
      inherited;
end;

procedure TCoolMemo.WMNCHitTest(var Message: TWMNCHitTest);
begin
  inherited;
  if (Message.Result = Windows.htCaption) and (ocNoDragUsingCaption in FOptions) then
    Message.Result := Windows.htNowhere;
end;

procedure TCoolMemo.WMSetText(var Message: TMessage);
begin
  inherited;
end;

procedure TCoolMemo.WMNCPaint(var Message: TMessage);
var
  WR, R: TRect;
  MyDC: HDC;
  MyRgn: HRGN;
  OldFont, MyFont: HFONT;
  MyBrush: HBRUSH;
  DeleteRgn: Boolean;
  NCM: TNonClientMetrics;
begin
  inherited;
  if not (ocNoCaption in FOptions) then
  begin
    DeleteRgn := FALSE;
    MyRgn := Message.wParam;

    MyDC := GetWindowDC(Handle);
    try
      GetWindowRect(Handle, WR);

      if SelectClipRgn(MyDC, MyRgn) = ERROR then
        with WR do
        begin
          MyRgn := CreateRectRgn(Left, Top, Right, Bottom);
          SelectClipRgn(MyDC, MyRgn);
          DeleteRgn := TRUE;
        end;

      OffsetClipRgn(MyDC, -WR.Left, -WR.Top);
      GetWindowRect(Handle, R);
      OffsetRect(R, -R.Left, -R.Top);
      InflateRect(R, -GetSystemMetrics(SM_CXFIXEDFRAME),  -GetSystemMetrics(SM_CYFIXEDFRAME));
      if (ocSmallCaption in FOptions) then
        R.Bottom := R.Top + GetSystemMetrics(SM_CYSMCAPTION)-1 else
          R.Bottom := R.Top + GetSystemMetrics(SM_CYCAPTION)-1;

      MyBrush := CreateSolidBrush(ColorToRGB(FCaptionColor));
      try
        if not (ocPaintCaptionWallpaper in FOptions) then
          FillRect(MyDC, R, MyBrush) else
            CTLDrawCaptionWallpaper(MyDC, R, True, SRCCOPY);

        NCM.cbSize := SizeOf(NCM);
        SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @NCM, 0);
        if (ocSmallCaption in FOptions) then
          MyFont := CreateFontIndirect(NCM.lfSmCaptionFont) else
            MyFont := CreateFontIndirect(NCM.lfCaptionFont);
        try
          OldFont := SelectObject(MyDC, MyFont);
          try
            OffsetRect(R, 2, 0);
            try
              SetTextColor(MyDC, ColorToRGB(FCaptionTextColor));
              SetBkMode(MyDC, Transparent);
              DrawText(MyDC, PChar(Caption), -1, R, DT_LEFT or DT_VCENTER or DT_SINGLELINE);
            finally
              OffsetRect(R, -2, 0);
            end;
          finally
            SelectObject(MyDC, OldFont);
          end;
        finally
          DeleteObject(MyFont);
        end;
      finally
        DeleteObject(MyBrush);
      end;

      ExcludeClipRect(MyDC, R.Left, R.Top, R.Right, R.Bottom);
      OffsetClipRgn(MyDC, WR.Left, WR.Top);
      GetClipRgn(MyDC, MyRgn);
      Message.Result := DefWindowProc(Handle, Message.Msg, MyRgn, Message.lParam);

    finally
      if DeleteRgn then DeleteObject(MyRgn);
      ReleaseDC(Handle, MyDC);
    end;
  end;
end;

procedure TCoolMemo.NCCtlChanged;
begin
  if HandleAllocated then
    SetWindowPos(Handle, 0, 0, 0, 0, 0, SWP_DRAWFRAME or SWP_NOACTIVATE or SWP_NOMOVE or
                                        SWP_NOSIZE or SWP_NOZORDER);
end;

procedure TCoolMemo.WndProc(var Message: TMessage);
var
  PosMemo: Integer;
begin
  if not (ocNoCaption in FOptions) then
    case Message.Msg of
      WM_MOUSEMOVE:
        if (MK_LBUTTON and  Message.wParam <> 0) then
        begin
          PosMemo := Perform(EM_CHARFROMPOS, 0, MakelParam(LoWord(Message.lParam), HiWord(Message.lParam)));
          if LoWord(PosMemo) > FOldSelStart then
            SelLength := LoWord(PosMemo) - FOldSelStart else
            begin
              SelStart := LoWord(PosMemo);
              SelLength := FOldSelStart - SelStart;
            end;
        end;

      WM_LBUTTONDOWN:
        begin
          SetFocus;
          PosMemo := Perform(EM_CHARFROMPOS, 0, MakelParam(LoWord(Message.lParam), HiWord(Message.lParam)));
          SelStart := LoWord(PosMemo);
          FOldSelStart := SelStart;
        end;
    end;

  inherited WndProc(Message);
end;

procedure TCoolMemo.DoPaint;
const
  BorderOffsets: array[TBorderStyle] of Integer = (1, -1);
var
  MyDC: HDC;
  TempDC: HDC;
  OldBmp, TempBmp: HBITMAP;
begin
  FBeingPainted := True;

  if ((ocPaintWallpaper in FOptions) and IsWallpaperAssigned) or (ocPaintTransparently in FOptions) then
  begin
    HideCaret(Handle);
    try
      MyDC := GetDC(Handle);
      try
        TempDC := CreateCompatibleDC(MyDC);
        try
          TempBmp := CreateCompatibleBitmap(MyDC, Succ(ClientWidth), Succ(ClientHeight));
          try
            OldBmp := SelectObject(TempDC, TempBmp);

            PaintTo(TempDC, 0, 0);

            if (ocFlatBorder in FOptions) then
              DrawFlatBorder(TempDC, Self, True);

            BitBlt(MyDC, BorderOffsets[BorderStyle], BorderOffsets[BorderStyle], ClientWidth, ClientHeight, TempDC, 1, 1, SRCCOPY);

            SelectObject(TempDC, OldBmp);
          finally
            DeleteObject(TempBmp);
          end;
        finally
          DeleteDC(TempDC);
        end;
      finally
        ReleaseDC(Handle, MyDC);
      end;
    finally
      ShowCaret(Handle);
    end;
  end;

  FBeingPainted := False;
end;

procedure TCoolMemo.Change;
begin
  DoPaint;

  if (ocFlatBorder in FOptions) then
    DrawFlatBorder(0, Self, Focused);

  inherited Change;
end;

procedure TCoolMemo.KeyDown(var Key: Word; Shift: TShiftState);

  function lastVisibleLine: Integer;
  var
    R: TRect;
    lIndex: Integer;
  begin
    Perform(EM_GETRECT, 0, Longint(@R));
    lIndex := Perform(EM_CHARFROMPOS, 0, MakelParam(R.left, R.Bottom));
    Result := Perform(EM_LINEFROMCHAR, lIndex, 0);
  end;

begin
  inherited KeyDown(Key, Shift);
  if (ocFlatBorder in FOptions) then
  begin
    if (Key = VK_PRIOR) and (Perform(EM_GETFIRSTVISIBLELINE, 0, 0) = 0) then
      Key := 0;

    if (Key = VK_NEXT) and (lastVisibleLine = Lines.Count) then
      Key := 0;
  end;
end;

procedure TCoolMemo.KeyUp(var Key: Word; Shift: TShiftState);
begin
  inherited KeyUp(Key, Shift);
end;

procedure TCoolMemo.KeyPress(var Key: Char);
begin
  inherited KeyPress(Key);
end;

procedure TCoolMemo.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  inherited MouseDown(Button, Shift, X, Y);
end;

procedure TCoolMemo.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  inherited MouseUp(Button, Shift, X, Y);
end;

{TCoolLabel}
constructor TCoolLabel.Create(AOwner: TComponent);
begin
  FGlyph := TGlyph.Create;
  TGlyph(FGlyph).OnChange := GlyphChanged;
  inherited Create(AOwner);
  FShadowColor := clBtnHighlight;
  FShadowSize := 1;
  FShadowPos := spLeftTop;
  FSimpleView := False;
  FBevelInner := bvNone;
  FBevelOuter := bvNone;
  FBevelsOffset := 0;

  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;
  FidWallpaper := -1;

  FBorderPen := TPen.Create;
  FBorderPen.OnChange := BorderPenChange;
  FEdgeBorders := [];

  FStretched := False;
end;

destructor TCoolLabel.Destroy;
begin
  FBorderPen.Free;
  FCoolImagesChangeLink.Free;
  if Assigned(FWallpaper) then FWallpaper.Free;
  inherited Destroy;
  TGlyph(FGlyph).Free;
end;

procedure TCoolLabel.GlyphChanged(Sender: TObject);
begin
  Invalidate;
end;

function TCoolLabel.GetGlyph: TBitmap;
begin
  Result := TGlyph(FGlyph).Glyph;
end;

procedure TCoolLabel.SetGlyph(Value: TBitmap);
begin
  TGlyph(FGlyph).Glyph := Value;
  AdjustBounds;
end;

function TCoolLabel.GetNumGlyphs: TNumGlyphs;
begin
  Result := TGlyph(FGlyph).NumGlyphs;
end;

procedure TCoolLabel.SetNumGlyphs(Value: TNumGlyphs);
begin
  if Value < 0 then Value := 1 else
      if Value > 2 then Value := 2;

  if Value <> TGlyph(FGlyph).NumGlyphs then
  begin
    TGlyph(FGlyph).NumGlyphs := Value;
    Invalidate;
  end;
end;

function TCoolLabel.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolLabel.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  FWallpaper.Assign(Value);
  Repaint;
end;

procedure TCoolLabel.SetShadowColor(Value: TColor);
begin
  if FShadowColor <> Value then
  begin
    FShadowColor := Value;
    FSimpleView := False;
    Repaint;
  end;
end;

procedure TCoolLabel.SetShadowSize(Value: Byte);
begin
  if FShadowSize <> Value then
  begin
    FShadowSize := Value;
    FSimpleView := False;
    Repaint;
  end;
end;

procedure TCoolLabel.SetShadowPos(Value: TShadowPosition);
begin
  if FShadowPos <> Value then
  begin
    FShadowPos := Value;
    FSimpleView := False;
    Repaint;
  end;
end;

procedure TCoolLabel.SetSimpleView(Value: Boolean);
begin
  if FSimpleView <> Value then
  begin
    FSimpleView := Value;
    Repaint;
  end;
end;

procedure TCoolLabel.SetBevelInner(Value: TPanelBevel);
begin
  if FBevelInner <> Value then
  begin
    FBevelInner := Value;
    Repaint;
  end;
end;

procedure TCoolLabel.SetBevelOuter(Value: TPanelBevel);
begin
  if FBevelOuter <> Value then
  begin
    FBevelOuter := Value;
    Repaint;
  end;
end;

procedure TCoolLabel.SetBevelsOffset(Value: Integer);
begin
  if FBevelsOffset <> Value then
  begin
    FBevelsOffset := Value;

    if FBevelsOffset <> 0 then
      AutoSize := False;

    Repaint;
  end;
end;

procedure TCoolLabel.SetStretched(Value: Boolean);
begin
  if FStretched <> Value then
  begin
    FStretched := Value;
    Invalidate;
  end;
end;

procedure TCoolLabel.WallpaperChanged(Sender: TObject);
begin
  Invalidate;
  Perform(CM_COLORCHANGED, 0, 0);
end;

procedure TCoolLabel.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolLabel.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  Invalidate;
end;

procedure TCoolLabel.SetBorderPen(Value: TPen);
begin
  FBorderPen.Assign(Value);
end;

procedure TCoolLabel.SetEdgeBorders(Value: TEdgeBorders);
begin
  if FEdgeBorders <> Value then
  begin
    FEdgeBorders := Value;
    Invalidate;
  end;
end;

procedure TCoolLabel.BorderPenChange(Sender: TObject);
begin
  Invalidate;
end;

function TCoolLabel.CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaper(DC, FWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

procedure TCoolLabel.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FCoolImages) and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

procedure TCoolLabel.Loaded;
begin
  inherited Loaded;
  {$IFDEF BCB}
  {$IFNDEF DELPHI4_OR_ABOVE}
  AdjustBounds;
  {$ENDIF}
  {$ELSE}
  {$IFNDEF VER90}
  AdjustBounds;
  {$ENDIF}
  {$ENDIF}
end;

procedure TCoolLabel.SetAutoSize(Value: Boolean);
begin
  inherited SetAutoSize(Value);
  {$IFDEF BCB}
  {$IFNDEF DELPHI4_OR_ABOVE}
  AdjustBounds;
  {$ENDIF}
  {$ELSE}
  {$IFNDEF VER90}
  AdjustBounds;
  {$ENDIF}
  {$ENDIF}
end;

procedure TCoolLabel.CoolImagesChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolLabel.AdjustBounds;
const
  WordWraps: array[Boolean] of Word = (0, DT_WORDBREAK);
var
  X: Integer;
  R: TRect;
  {$IFDEF DELPHI4_OR_ABOVE}
  AAlignment: TAlignment;
  {$ENDIF}
begin
  if not (csReading in ComponentState) and AutoSize and Assigned(Parent) then
  begin
    R := ClientRect;
    DoDrawText(R, (DT_EXPANDTABS or DT_CALCRECT) or WordWraps[WordWrap]);
    X := Left;

    if Assigned(Glyph) and not (Glyph.Empty) then
    begin
      R.Right := R.Right + Glyph.Width div NumGlyphs + LIGHT_OFFSET;
      if R.Bottom < Glyph.Height then R.Bottom := Glyph.Height;
    end;

    {$IFDEF DELPHI4_OR_ABOVE}
    AAlignment := Alignment;
    if UseRightToLeftAlignment then ChangeBiDiModeAlignment(AAlignment);
    {$ENDIF}
    if Alignment = taRightJustify then Inc(X, Width - R.Right);

    SetBounds(X, Top, R.Right, R.Bottom);
  end;
end;

{$IFDEF BCB}
procedure TCoolLabel.DoDrawText(var Recty: TRect; Flags: {$IFNDEF VER125}{$IFDEF DELPHI5_OR_ABOVE}LongInt{$ELSE}Word{$ENDIF}{$ELSE}Longint{$ENDIF});
{$ELSE}
procedure TCoolLabel.DoDrawText(var Recty: TRect; Flags: Longint);
{$ENDIF}
var
  Text: string;
begin
  Text := GetLabelText;
  if (Flags and DT_CALCRECT <> 0) and
     ((Text = '') or ShowAccelChar and (Text[1] = '&') and (Text[2] = #0)) then
       Text := Text + ' ';

  if not ShowAccelChar then
    Flags := Flags or DT_NOPREFIX;

  {$IFDEF DELPHI4_OR_ABOVE}
  Flags := DrawTextBiDiModeFlags(Flags);
  {$ENDIF}
  Canvas.Font := Font;

  if not Enabled then
    Draw3DText(Canvas.Handle, Recty, {$IFDEF BCB}{$IFDEF VER100}SPToInt({$ENDIF}{$ENDIF} spRightBottom {$IFDEF BCB}{$IFDEF VER100}){$ENDIF}{$ENDIF}, PChar(Text), Flags, clBtnShadow, clBtnHighlight, 1) else
      if FSimpleView then
        DrawText(Canvas.Handle, PChar(Text),  Length(Caption), Recty, Flags) else
          Draw3DText(Canvas.Handle, Recty, {$IFDEF BCB}{$IFDEF VER100}SPToInt({$ENDIF}{$ENDIF} FShadowPos {$IFDEF BCB}{$IFDEF VER100}){$ENDIF}{$ENDIF}, PChar(Text), Flags, Font.Color, FShadowColor, FShadowSize);
end;

procedure TCoolLabel.Paint;
const
  Alignments: array[TAlignment] of Word = (DT_LEFT, DT_RIGHT, DT_CENTER);
  WordWraps: array[Boolean] of Word = (0, DT_WORDBREAK);
  {$IFDEF DELPHI4_OR_ABOVE}
  FInnerEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER, 0);
  FOuterEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER, 0);
  {$ELSE}
  FInnerEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER);
  FOuterEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER);
  {$ENDIF}
var
  P: TPoint;
  Rect: TRect;
  {$IFNDEF VER90}
  CalcRect: TRect;
  {$ENDIF}
  DrawStyle: Longint;
begin
  with Canvas do
  begin
    if not Transparent then
      if not CTLDrawWallpaper(Canvas.Handle, ClientRect, FStretched, SRCCOPY) then
      begin
        Brush.Color := Self.Color;
        Brush.Style := bsSolid;
        FillRect(ClientRect);
      end;

    Rect := ClientRect;
    {$IFDEF DELPHI4_OR_ABOVE}
    if not ((FBevelInner in [bvNone, bvSpace]) and (FBevelOuter in [bvNone, bvSpace])) then
    {$ELSE}
    if not ((FBevelInner = bvNone) and (FBevelOuter = bvNone)) then
    {$ENDIF}
    begin
      DrawEdge(Handle, Rect, FInnerEdges[FBevelInner] OR FOuterEdges[FBevelOuter], BF_RECT);
      InflateRect(Rect, -FBevelsOffset, -FBevelsOffset);
    end;

    Brush.Style := bsClear;
    DrawStyle := DT_EXPANDTABS or WordWraps[WordWrap] or Alignments[Alignment];

    {$IFNDEF VER90}
    if Layout <> tlTop then
    begin
      CalcRect := Rect;

      DoDrawText(CalcRect, DrawStyle or DT_CALCRECT);
      if Layout = tlBottom then
        OffsetRect(Rect, 0, Height - CalcRect.Bottom) else
          OffsetRect(Rect, 0, (Height - CalcRect.Bottom) div 2);
    end;
    {$ENDIF}

    if Assigned(Glyph) and not (Glyph.Empty) then
    begin
      P.Y := Rect.Top;

      case Alignment of
        taCenter:
          begin
            P.X := ((Rect.Right - Rect.Left) div 2) - ((Canvas.TextWidth(Text) + Glyph.Width div NumGlyphs + LIGHT_OFFSET) div 2);
            OffsetRect(Rect, (Glyph.Width div NumGlyphs + LIGHT_OFFSET) div 2, 0);
          end;
        taLeftJustify:
          begin
            P.X := Rect.Left;
            OffsetRect(Rect, Glyph.Width div NumGlyphs + LIGHT_OFFSET, 0);
          end;
        taRightJustify:
          P.X := Rect.Right - Canvas.TextWidth(Text) - Glyph.Width div NumGlyphs - LIGHT_OFFSET;
      end;

      TGlyph(FGlyph).DrawImage(Canvas, P, Enabled, True, clNone);
    end;

    DoDrawText(Rect, DrawStyle);
    DrawBorders2(Self, FEdgeBorders, FBorderPen);
  end;
end;

procedure TCoolLabel.CMTextChanged(var Message: TMessage);
begin
  inherited;
  {$IFDEF BCB}
  {$IFNDEF DELPHI4_OR_ABOVE}
  AdjustBounds;
  {$ENDIF}
  {$ELSE}
  {$IFNDEF VER90}
  AdjustBounds;
  {$ENDIF}
  {$ENDIF}
end;

procedure TCoolLabel.CMFontChanged(var Message: TMessage);
begin
  inherited;
  {$IFDEF BCB}
  {$IFNDEF DELPHI4_OR_ABOVE}
  AdjustBounds;
  {$ENDIF}
  {$ELSE}
  {$IFNDEF VER90}
  AdjustBounds;
  {$ENDIF}
  {$ENDIF}
end;

{$IFDEF DELPHI4_OR_ABOVE}

{TCoolCheckRadioBoxActionLink}
procedure TCoolCheckRadioBoxActionLink.AssignClient(AClient: TObject);
begin
  inherited AssignClient(AClient);
  FClient := AClient as TCoolCheckRadioBox;
end;

function TCoolCheckRadioBoxActionLink.IsCheckedLinked: Boolean;
begin
  Result := inherited IsCheckedLinked and
    (FClient.Checked = (Action as TCustomAction).Checked);
end;

procedure TCoolCheckRadioBoxActionLink.SetChecked(Value: Boolean);
begin
  if IsCheckedLinked then FClient.Checked := Value;
end;

{$ENDIF}

{TCoolCheckRadioBox}
constructor TCoolCheckRadioBox.Create(AOwner: TComponent);
begin
  FGlyphMarked := TGlyph.Create;
  TGlyph(FGlyphMarked).OnChange := GlyphMarkedChanged;
  FGlyphNormal := TGlyph.Create;
  TGlyph(FGlyphNormal).OnChange := GlyphNormalChanged;
  inherited Create(AOwner);
  ControlStyle := [csSetCaption, csClickEvents, csReplicatable];
  SetBounds(0, 0, 147, 17);
  {$IFDEF DELPHI4_OR_ABOVE}
  AutoSize := False;
  {$ENDIF}
  FAlignment := taRightJustify;
  FTransparent := False;
  FState := cbUnchecked;
  FAllowGrayed := False;
  FChecked := False;
  FDown := False;
  FFlat := False;
  FCheckRadioType := crCheckBox;
  FGroupIndex := 0;
  // by Starenko begin
  FImageChangeLink := TChangeLink.Create;
  FImageChangeLink.OnChange := ImageListChange;
  // by Starenko end

  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;
  FidWallpaper := -1;

  FShadowColor := clBtnHighlight;
  FShadowSize := 1;
  FShadowPos := spLeftTop;
  FSimpleView := False;
  FBevelInner := bvNone;
  FBevelOuter := bvNone;
  FBevelsOffset := 0;
  FOwnerDraw := False;
  FTransparencyLevel := 0;
  FStretched := False;
end;

destructor TCoolCheckRadioBox.Destroy;
begin
  FCoolImagesChangeLink.Free;
  if Assigned(FWallpaper) then FWallpaper.Free;
{$IFDEF DELPHI5_OR_ABOVE}
  FreeAndNil(FImageChangeLink);
{$ELSE}
  FImageChangeLink.Free;
{$ENDIF}
  TGlyph(FGlyphMarked).Free;
  TGlyph(FGlyphNormal).Free;
  inherited Destroy;
end;

function TCoolCheckRadioBox.GetImageHeight: Integer;
begin
  // by Starenko begin
  Result := 13;

  if FOwnerDraw then
    case FImageSrc of
      isGlyph: //paint img from glyphs
          if Checked or (FState = cbChecked)
          then Result := GlyphMarked.Height
          else Result := GlyphNormal.Height;
      isImageList: //paint img from imglst
          if Assigned(FImages) then
            Result := FImages.Height;
    end;//case//
  // by Starenko end
end;

function TCoolCheckRadioBox.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolCheckRadioBox.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper <> Value then
  begin
    if FWallpaper = nil then FWallpaper := TBitmap.Create;
    FTransparent := False;
    FWallpaper.Assign(Value);
    Invalidate;
  end;
end;

procedure TCoolCheckRadioBox.SetTransparent(Value: Boolean);
begin
  if Transparent <> Value then
  begin
    FTransparent := Value;
    Invalidate;
  end;
end;

procedure TCoolCheckRadioBox.SetTransparencyLevel(Value: Byte);
begin
  if FTransparencyLevel <> Value then
  begin
    FTransparencyLevel := Value;
    Invalidate;
  end;
end;

procedure TCoolCheckRadioBox.SetFlat(Value: Boolean);
begin
  if FFlat <> Value then
  begin
    FFlat := Value;
    InvalidateEx;
  end;
end;

procedure TCoolCheckRadioBox.SetAlignment(Value: TLeftRight);
begin
  if FAlignment <> Value then
  begin
    FAlignment := Value;
    Invalidate;
  end;
end;

procedure TCoolCheckRadioBox.SetCheckRadioType(Value: TCheckRadioType);
begin
  if FCheckRadioType <> Value then
  begin
    FCheckRadioType := Value;
    TabStop := Value = crCheckBox;
    Invalidate;
  end;
end;

procedure TCoolCheckRadioBox.SetShadowColor(Value: TColor);
begin
  if FShadowColor <> Value then
  begin
    FShadowColor := Value;
    FSimpleView := False;
    Invalidate;
  end;
end;

procedure TCoolCheckRadioBox.SetShadowSize(Value: Byte);
begin
  if FShadowSize <> Value then
  begin
    FShadowSize := Value;
    FSimpleView := False;
    Invalidate;
  end;
end;

procedure TCoolCheckRadioBox.SetShadowPos(Value: TShadowPosition);
begin
  if FShadowPos <> Value then
  begin
    FShadowPos := Value;
    FSimpleView := False;
    Invalidate;
  end;
end;

procedure TCoolCheckRadioBox.SetSimpleView(Value: Boolean);
begin
  if FSimpleView <> Value then
  begin
    FSimpleView := Value;
    Invalidate;
  end;
end;

procedure TCoolCheckRadioBox.SetBevelInner(Value: TPanelBevel);
begin
  if FBevelInner <> Value then
  begin
    FBevelInner := Value;
    Invalidate;
  end;
end;

procedure TCoolCheckRadioBox.SetBevelOuter(Value: TPanelBevel);
begin
  if FBevelOuter <> Value then
  begin
    FBevelOuter := Value;
    Invalidate;
  end;
end;

procedure TCoolCheckRadioBox.SetBevelsOffset(Value: Integer);
begin
  if FBevelsOffset <> Value then
  begin
    FBevelsOffset := Value;

  {$IFDEF DELPHI4_OR_ABOVE}
    if FBevelsOffset <> 0 then
      AutoSize := False;
  {$ENDIF}

    Invalidate;
  end;
end;

procedure TCoolCheckRadioBox.SetOwnerDraw(Value: Boolean);
begin
  if FOwnerDraw <> Value then
  begin
    FOwnerDraw := Value;
    Invalidate;
  end;
end;

procedure TCoolCheckRadioBox.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;
    Invalidate;
  end;
end;

// by Starenko begin
procedure TCoolCheckRadioBox.SetImages(Value: TImageList);
begin
  if Assigned(Images) then
    Images.UnRegisterChanges(FImageChangeLink);

  FImages := Value;

  if Assigned(Images) then
    Images.RegisterChanges(FImageChangeLink);

  Invalidate;
end;

procedure TCoolCheckRadioBox.SetImageSrc(Value: TImageSource);
begin
  if FImageSrc <> Value then
  begin
    FImageSrc := Value;
    Invalidate;
  end;
end;

// by Starenko end

procedure TCoolCheckRadioBox.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  Invalidate;
end;

procedure TCoolCheckRadioBox.SetState(Value: TCheckBoxState);
begin
  if FState <> Value then
  begin
    FState := Value;
    InvalidateEx;
  end;
end;

procedure TCoolCheckRadioBox.SetChecked(Value: Boolean);
const
  States: array[Boolean] of TCheckBoxState = (cbUnchecked, cbChecked);
begin
  if FChecked <> Value then
  begin
    FChecked := Value;
    FState := States[Value];
    InvalidateEx;
  end;
end;

function TCoolCheckRadioBox.Toggle: Boolean;
var
  I: Integer;
  FCRBox: TCoolCheckRadioBox;
  FOldState: TCheckBoxState;
begin
  FOldState := FState;
  if FCheckRadioType = crRadioBox then
  begin
    for I := 0 to Parent.ControlCount-1 do
      if Parent.Controls[I] is TCoolCheckRadioBox then
      begin
        FCRBox := Parent.Controls[I] as TCoolCheckRadioBox;
        if (FCRBox.FCheckRadioType = crRadioBox) and (FCRBox.GroupIndex = GroupIndex) then
          if FCRBox <> Self then
            FCRBox.Checked := False
          else
            FCRBox.Checked := True;
      end;
  end else
    if not FAllowGrayed then
      Checked := not Checked else
        case State of
          cbChecked:   State := cbGrayed;
          cbGrayed:    State := cbUnchecked;
          cbUnchecked: State := cbChecked
        end;

  Result := FOldState <> FState;
end;

procedure TCoolCheckRadioBox.SetFocus;
var
  {$IFNDEF VER90}
  Parent: TCustomForm;
  {$ELSE}
  Parent: TForm;
  {$ENDIF}
begin
  Parent := nil;
  {$IFNDEF VER90}
  if Parent is TCustomForm then
  {$ELSE}
  if Parent is TForm then
  {$ENDIF}
    Parent := GetParentForm(Self);

  if Parent <> nil then
    Parent.FocusControl(Self)
  else
    Windows.SetFocus(Handle);
end;

procedure TCoolCheckRadioBox.Click;
begin
  if Toggle then
    inherited Click;
end;

function TCoolCheckRadioBox.CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaper(DC, FWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

function TCoolCheckRadioBox.IsCheckedStored: Boolean;
begin
  {$IFDEF DELPHI4_OR_ABOVE}
  Result := (ActionLink = nil) or not TCoolCheckRadioBoxActionLink(ActionLink).IsCheckedLinked;
  {$ELSE}
  Result := True; 
  {$ENDIF}
end;

procedure TCoolCheckRadioBox.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FCoolImages) and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

{$IFDEF DELPHI4_OR_ABOVE}
function TCoolCheckRadioBox.GetActionLinkClass: TControlActionLinkClass;
begin
  Result := TCoolCheckRadioBoxActionLink;
end;

procedure TCoolCheckRadioBox.ActionChange(Sender: TObject; CheckDefaults: Boolean);
begin
  inherited ActionChange(Sender, CheckDefaults);
  if Sender is TCustomAction then
    with TCustomAction(Sender) do
      if not CheckDefaults or (Self.Checked = False) then
        Self.Checked := Checked;
end;
{$ENDIF}

procedure TCoolCheckRadioBox.AssignTo(Dest: TPersistent);
begin
  inherited AssignTo(Dest);
  {$IFDEF DELPHI4_OR_ABOVE}
  if Dest is TCustomAction then
    with TCustomAction(Dest) do
      Checked := Self.Checked;
  {$ENDIF}    
end;

procedure TCoolCheckRadioBox.Loaded;
begin
  inherited Loaded;
end;

procedure TCoolCheckRadioBox.ReadState(Reader: TReader);
begin
  inherited ReadState(Reader);
end;

procedure TCoolCheckRadioBox.CoolImagesChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolCheckRadioBox.GlyphMarkedChanged(Sender: TObject);
begin
  InvalidateEx;
end;

procedure TCoolCheckRadioBox.GlyphNormalChanged(Sender: TObject);
begin
  InvalidateEx;
end;

// by Starenko begin
procedure TCoolCheckRadioBox.ImageListChange(Sender: TObject);
begin
  InvalidateEx;
end;
// by Starenko end

function TCoolCheckRadioBox.GetGlyphMarked: TBitmap;
begin
  Result := TGlyph(FGlyphMarked).Glyph;
end;

procedure TCoolCheckRadioBox.SetGlyphMarked(Value: TBitmap);
begin
  TGlyph(FGlyphMarked).Glyph := Value;
  Invalidate;
end;

function TCoolCheckRadioBox.GetGlyphNormal: TBitmap;
begin
  Result := TGlyph(FGlyphNormal).Glyph;
end;

procedure TCoolCheckRadioBox.SetGlyphNormal(Value: TBitmap);
begin
  TGlyph(FGlyphNormal).Glyph := Value;
  Invalidate;
end;

function TCoolCheckRadioBox.GetNumGlyphsMarked: TNumGlyphs;
begin
  Result := TGlyph(FGlyphMarked).NumGlyphs;
end;

procedure TCoolCheckRadioBox.SetNumGlyphsMarked(Value: TNumGlyphs);
begin
  if Value < 0 then Value := 1 else
      if Value > 2 then Value := 2;

  if Value <> TGlyph(FGlyphMarked).NumGlyphs then
  begin
    TGlyph(FGlyphMarked).NumGlyphs := Value;
    InvalidateEx;
  end;
end;

function TCoolCheckRadioBox.GetNumGlyphsNormal: TNumGlyphs;
begin
  Result := TGlyph(FGlyphNormal).NumGlyphs;
end;

procedure TCoolCheckRadioBox.SetNumGlyphsNormal(Value: TNumGlyphs);
begin
  if Value < 0 then  Value := 1 else
      if Value > 2 then Value := 2;

  if Value <> TGlyph(FGlyphNormal).NumGlyphs then
  begin
    TGlyph(FGlyphNormal).NumGlyphs := Value;
    InvalidateEx;
  end;
end;

procedure TCoolCheckRadioBox.WallpaperChanged(Sender: TObject);
begin
  Invalidate;
  Perform(CM_COLORCHANGED, 0, 0);
end;

procedure TCoolCheckRadioBox.SetStretched(Value: Boolean);
begin
  if FStretched <> Value then
  begin
    FStretched := Value;
    Invalidate;
  end;
end;

procedure TCoolCheckRadioBox.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbLeft then
  begin
    SetFocus;
    FDown := True;
    InvalidateEx;
  end;
  inherited MouseDown(Button, Shift, X, Y);
end;

procedure TCoolCheckRadioBox.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if (Button = mbLeft) and FDown then
  begin
    FDown := False;
    InvalidateEx;
  end;
  inherited MouseUp(Button, Shift, X, Y);
end;

procedure TCoolCheckRadioBox.KeyDown(var Key: Word; Shift: TShiftSTate);
begin
  if (Key = VK_SPACE) and (Shift = []) then
  begin
    FDown := True;
    InvalidateEx;
  end;
  inherited KeyDown(Key, Shift);
end;

procedure TCoolCheckRadioBox.KeyUp(var Key: Word; Shift: TShiftSTate);
begin
  if (Key = VK_SPACE) and (Shift = []) and FDown then
  begin
    FDown := False;
    InvalidateEx;
    Click;
  end;
  inherited KeyUp(Key, Shift);
end;

procedure TCoolCheckRadioBox.DoEnter;
begin
  inherited DoEnter;
  Repaint;
end;

procedure TCoolCheckRadioBox.DoExit;
begin
  inherited DoExit;

  FDown := False;
  InvalidateEx;
  Repaint;
end;

procedure TCoolCheckRadioBox.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
end;

{$IFDEF DELPHI4_OR_ABOVE}
procedure TCoolCheckRadioBox.AdjustSize;
begin
  SetBounds(Left, Top, Width, Height);
end;
{$ENDIF}

procedure TCoolCheckRadioBox.InvalidateEx;
var
  R: TRect;
  ImgTop: Integer;
begin
  ImgTop := (ClientHeight div 2) - (ImageHeight div 2);
  case Alignment of
    taLeftJustify: R := Rect(ClientWidth - ImageHeight - OFFSET, ImgTop, ClientWidth - OFFSET, ImgTop + ImageHeight);
    taRightJustify: R := Rect(OFFSET, ImgTop, OFFSET + ImageHeight, ImgTop + ImageHeight);
  end;
  InvalidateRectEx(Handle, R, True);
end;

procedure TCoolCheckRadioBox.Paint;
const
  States: array[TCheckBoxState] of Longint = (0, DFCS_CHECKED, DFCS_INACTIVE or DFCS_CHECKED);
  Types: array[TCheckRadioType] of Longint = (DFCS_BUTTONCHECK, DFCS_BUTTONRADIO);
  Downs: array[Boolean] of Longint = (0, DFCS_INACTIVE);
  Flats: array[Boolean] of Longint = (0, DFCS_FLAT);
  Enableds: array[Boolean] of Longint = (DFCS_INACTIVE, 0);
  Alignments: array[TLeftRight] of Longint = (DT_RIGHT, DT_LEFT);
  {$IFDEF DELPHI4_OR_ABOVE}
  FInnerEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER, 0);
  FOuterEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER, 0);
  {$ELSE}
  FInnerEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER);
  FOuterEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER);
  {$ENDIF}
var
  R: TRect;
  ImgTop,
  TxtTop: Integer;
begin
  inherited Paint;

  with Canvas do
  begin
    Font.Assign(Self.Font);

    //Image
    ImgTop := (ClientHeight div 2) - (ImageHeight div 2);
    case Alignment of
      taLeftJustify: R := Rect(ClientWidth - ImageHeight - OFFSET, ImgTop, ClientWidth - OFFSET, ImgTop + ImageHeight);
      taRightJustify: R := Rect(OFFSET, ImgTop, OFFSET + ImageHeight, ImgTop + ImageHeight);
    end;
    if not FOwnerDraw then  //---- default image
      DrawFrameControl(Handle, R, DFC_BUTTON, Types[FCheckRadioType] or States[FState] or Downs[FDown] or Enableds[Enabled] or Flats[FFlat])
    else                    //---- custom image
      // by Starenko begin
      case FImageSrc of
      isGlyph: //paint img from glyphs
          if Checked or (FState = cbChecked)
          then TGlyph(FGlyphMarked).DrawImage(Canvas, R.TopLeft, Enabled, True, clNone)
          else TGlyph(FGlyphNormal).DrawImage(Canvas, R.TopLeft, Enabled, True, clNone);
      isImageList: //paint img from imglst
          if Assigned(FImages) then
            if Checked or (FState = cbChecked) then
{$IFDEF DELPHI5_OR_ABOVE}
              Images.Draw(Canvas, R.Left, R.Top, 1, true)  //checked - imglst#1
            else
              Images.Draw(Canvas, R.Left, R.Top, 0, true); //unchecked - imglst#0 (default)
{$ELSE}
              Images.Draw(Canvas, R.Left, R.Top, 1)  //checked - imglst#1
            else
              Images.Draw(Canvas, R.Left, R.Top, 0); //unchecked - imglst#0 (default)
{$ENDIF}
      end;//case//
      // by Starenko end

    //Text
    SetBkMode(Handle, Windows.TRANSPARENT);

    TxtTop := (ClientHeight div 2) - (TextHeight(Caption) div 2);
    case Alignment of
      taLeftJustify:
        begin
          R := Rect(R.Left - TextWidth(Caption) - OFFSET, TxtTop, R.Left - OFFSET, TxtTop + TextHeight(Caption));
          if Pos('&', Caption) <> 0 then
            R.Left := R.Left + TextWidth('&');
        end;
      taRightJustify:
        begin
          R := Rect(R.Right + OFFSET, TxtTop, R.Right + OFFSET + TextWidth(Caption), TxtTop + TextHeight(Caption));
          if Pos('&', Caption) <> 0 then
            R.Right := R.Right - TextWidth('&');
        end;
    end;

    if Enabled then
    begin
      if FSimpleView then
        DrawText(Handle, PChar(Caption), Length(Caption), R, Alignments[FAlignment] or DT_NOCLIP or DT_SINGLELINE)
      else
        Draw3DText(Canvas.Handle, R, {$IFDEF BCB}{$IFDEF VER100}SPToInt({$ENDIF}{$ENDIF} FShadowPos {$IFDEF BCB}{$IFDEF VER100}){$ENDIF}{$ENDIF}, PChar(Caption),
                             Alignments[FAlignment] or DT_NOCLIP or DT_SINGLELINE, Font.Color, FShadowColor, FShadowSize);
    end else
    begin
      SetTextColor(Canvas.Handle, ColorToRGB(Font.Color));
      DrawState(Handle, 0, nil, LPARAM(Caption), 0, R.Left, R.Top, R.Right, R.Bottom, DST_PREFIXTEXT or DSS_DISABLED);
    end;

    //Focus frame
    if (Caption <> '') and not (csDesigning in ComponentState) and Focused then
    begin
      InflateRect(R, Succ(FShadowSize), FShadowSize);
      DrawFocusRect(R);
    end;

    //Bevels
    R := ClientRect;
    {$IFDEF DELPHI4_OR_ABOVE}
    if not ((FBevelInner in [bvNone, bvSpace]) and (FBevelOuter in [bvNone, bvSpace])) then
    {$ELSE}
    if not ((FBevelInner = bvNone) and (FBevelOuter = bvNone)) then
    {$ENDIF}
    begin
      DrawEdge(Handle, R, FInnerEdges[FBevelInner] OR FOuterEdges[FBevelOuter], BF_RECT);
      InflateRect(R, -FBevelsOffset, -FBevelsOffset);
    end;
  end;
end;

procedure TCoolCheckRadioBox.CMTextChanged(var Message: TMessage);
begin
  inherited;
  Invalidate;
end;

procedure TCoolCheckRadioBox.CMMouseEnter(var Message: TMessage);
begin
  inherited;
  if Focused and (Hi(GetKeyState(VK_LBUTTON)) = $0000FF) then
  begin
    FDown := True;
    InvalidateEx;
  end;
  if Assigned(FOnMouseEnter) then
    FOnMouseEnter(Self);
end;

procedure TCoolCheckRadioBox.CMMouseLeave(var Message: TMessage);
begin
  inherited;
  if Focused and (Hi(GetKeyState(VK_LBUTTON)) = $0000FF) then
  begin
    FDown := False;
    InvalidateEx;
  end;
  if Assigned(FOnMouseLeave) then
    FOnMouseLeave(Self);
end;

procedure TCoolCheckRadioBox.CMDialogChar(var Message: TCMDialogChar);
begin
   with Message do
     if IsAccel(CharCode, Caption) and Enabled and CanFocus then
     begin
       SetFocus;
       Click;
       Result := 1;
     end else inherited;
end;

procedure TCoolCheckRadioBox.CMFocusChanged(var Message: TCMFocusChanged);
begin
  inherited;
  with Message do
    if (Sender is TCoolCheckRadioBox) and (TCoolCheckRadioBox(Sender).CheckRadioType = crRadioBox) and (FCheckRadioType = crRadioBox) and (TCoolCheckRadioBox(Sender).Parent = Parent) and (TCoolCheckRadioBox(Sender).GroupIndex = FGroupIndex) and not (ssLeft in CurrentShiftState) then
      begin
        TabStop := Sender = Self;
        if Sender = Self then Click;
      end;
end;

procedure TCoolCheckRadioBox.CMEnabledChanged(var Message: TMessage);
begin
  inherited;
  Invalidate;
end;

procedure TCoolCheckRadioBox.CMParentColorChanged(var Message: TMessage);
begin
  inherited;
  Invalidate;
end;

procedure TCoolCheckRadioBox.CNCommand(var Message: TWMCommand);
begin
  if Message.NotifyCode = BN_CLICKED then
    Click;
end;

procedure TCoolCheckRadioBox.CMFontChange(var Message: TMessage);
begin
  inherited;
end;

procedure TCoolCheckRadioBox.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
  if FTransparent then
    PaintBackground(TrControl(Self, FTransparencyLevel), Message.DC, True) else
      if not CTLDrawWallpaper(Message.DC, ClientRect, FStretched, SRCCOPY) then
        inherited
end;

procedure TCoolCheckRadioBox.WMMove(var Message: TWMMove);
begin
  inherited;
  Invalidate;
end;

procedure TCoolCheckRadioBox.WMLButtonDown(var Message: TWMLButtonDown);
begin
  inherited;
end;

procedure TCoolCheckRadioBox.WMLButtonUp(var Message: TWMLButtonUp);
begin
  inherited;
end;

{TCoolGroupBox}
constructor TCoolGroupBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FShadowColor := clBtnHighlight;
  FShadowSize := 1;
  FShadowPos := spLeftTop;
  FSimpleView := False;

  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;
  FidWallpaper := -1;
  FTransparencyLevel := 0;
  FStretched := False;
end;

destructor TCoolGroupBox.Destroy;
begin
  FCoolImagesChangeLink.Free;
  if Assigned(FWallpaper) then FWallpaper.Free;
  inherited Destroy;
end;

procedure TCoolGroupBox.SetTransparent(Value: Boolean);
begin
  if Value <> FTransparent then
  begin
    Perform(CM_COLORCHANGED, 0, 0);
    FTransparent := Value;
    Invalidate;
  end;
end;

procedure TCoolGroupBox.SetTransparencyLevel(Value: Byte);
begin
  if FTransparencyLevel <> Value then
  begin
    FTransparencyLevel := Value;
    Invalidate;
  end;
end;

function TCoolGroupBox.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolGroupBox.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper <> Value then
  begin
    if FWallpaper = nil then FWallpaper := TBitmap.Create;

    Perform(CM_COLORCHANGED, 0, 0);
    FWallpaper.Assign(Value);
    Invalidate;
  end;
end;

procedure TCoolGroupBox.SetShadowColor(Value: TColor);
begin
  if FShadowColor <> Value then
  begin
    FShadowColor := Value;
    FSimpleView := False;
    Invalidate;
    {$IFNDEF VER90}
    Changed;
    {$ELSE}
    Perform(CM_CHANGED, 0, 0);
    {$ENDIF}
  end;
end;

procedure TCoolGroupBox.SetShadowSize(Value: Byte);
begin
  if FShadowSize <> Value then
  begin
    FShadowSize := Value;
    FSimpleView := False;
    Invalidate;
    {$IFNDEF VER90}
    Changed;
    {$ELSE}
    Perform(CM_CHANGED, 0, 0);
    {$ENDIF}
  end;
end;

procedure TCoolGroupBox.SetShadowPos(Value: TShadowPosition);
begin
  if FShadowPos <> Value then
  begin
    FShadowPos := Value;
    FSimpleView := False;
    Invalidate;
    {$IFNDEF VER90}
    Changed;
    {$ELSE}
    Perform(CM_CHANGED, 0, 0);
    {$ENDIF}
  end;
end;

procedure TCoolGroupBox.SetSimpleView(Value: Boolean);
begin
  if FSimpleView <> Value then
  begin
    FSimpleView := Value;
    Invalidate;
    {$IFNDEF VER90}
    Changed;
    {$ELSE}
    Perform(CM_CHANGED, 0, 0);
    {$ENDIF}
  end;
end;

procedure TCoolGroupBox.WallpaperChanged(Sender: TObject);
begin
  Invalidate;
  Perform(CM_COLORCHANGED, 0, 0);
end;

procedure TCoolGroupBox.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolGroupBox.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  Invalidate;
end;

procedure TCoolGroupBox.SetStretched(Value: Boolean);
begin
  if FStretched <> Value then
  begin
    FStretched := Value;
    Invalidate;
  end;
end;

function TCoolGroupBox.CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaper(DC, FWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

procedure TCoolGroupBox.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FCoolImages) and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

procedure TCoolGroupBox.CoolImagesChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolGroupBox.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
  if FTransparent then
    PaintBackground(TrControl(Self, FTransparencyLevel), Message.DC, True) else
      if not CTLDrawWallpaper(Message.DC, ClientRect, FStretched, SRCCOPY) then
        inherited;
end;

procedure TCoolGroupBox.CMParentColorChanged(var Message: TMessage);
begin
  inherited;
  Perform(CM_COLORCHANGED, 0, 0);
  Invalidate;
end;

procedure TCoolGroupBox.CMEnabledChanged(var Message: TMessage);
begin
  inherited;
  Invalidate;
end;

procedure TCoolGroupBox.WMMove(var Message: TWMMove);
begin
  inherited;
  Invalidate;
end;

procedure TCoolGroupBox.Paint;
const
  {$IFDEF DELPHI4_OR_ABOVE}
  FInnerEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER, 0);
  FOuterEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER, 0);
  {$ELSE}
  FInnerEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER);
  FOuterEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER);
  {$ENDIF}
var
  H: Integer;
  R: TRect;
  Flags: Longint;
begin
  with Canvas do
  begin
    Font := Self.Font;
    H := TextHeight('0');
    R := Rect(0, H div 2 - 1, Width, Height);
    if Ctl3D then
    begin
      Inc(R.Left);
      Inc(R.Top);
      Brush.Color := clBtnHighlight;
      FrameRect(R);
      OffsetRect(R, -1, -1);
      Brush.Color := clBtnShadow;
    end else
      Brush.Color := clWindowFrame;
    FrameRect(R);
    if Text <> '' then
    begin
      {$IFDEF DELPHI4_OR_ABOVE}
      if not UseRightToLeftAlignment then
        R := Rect(8, 0, 0, H)
      else
        R := Rect(R.Right - Canvas.TextWidth(Text) - 8, 0, 0, H);

      Flags := DrawTextBiDiModeFlags(DT_SINGLELINE);
      {$ELSE}
      R := Rect(8, 0, 0, H);
      Flags := DT_SINGLELINE;
      {$ENDIF}
      DrawText(Handle, PChar(Text), Length(Text), R, Flags or DT_CALCRECT);
      InflateRect(R, FShadowSize, 0);

      if FTransparent then
      begin
        SetBkMode(Handle, Windows.Transparent);
        PaintBackgroundEx(TrControl(Self, FTransparencyLevel), Handle, R, True);
      end else
      begin
        SetBkMode(Handle, Windows.Transparent);
        if not CTLDrawWallpaper(Handle, R, FStretched, SRCCOPY) then
        begin
          SetBkMode(Handle, Windows.Opaque);
          Brush.Color := Color;
        end;
      end;

      if Enabled then
      begin
        if FSimpleView then
          DrawText(Handle, PChar(Text), Length(Text), R, Flags) else
            Draw3DText(Canvas.Handle, R, {$IFDEF BCB}{$IFDEF VER100}SPToInt({$ENDIF}{$ENDIF} FShadowPos {$IFDEF BCB}{$IFDEF VER100}){$ENDIF}{$ENDIF}, PChar(Text), Flags, Font.Color, FShadowColor, FShadowSize);
      end else
      begin
        SetTextColor(Canvas.Handle, ColorToRGB(Font.Color));
        //DrawState wont draw opaque...
        DrawText(Handle, PChar(Text), Length(Text), R, Flags);
        DrawState(Handle, 0, nil, LPARAM(Text), 0, R.Left, R.Top, R.Right, R.Bottom, DST_PREFIXTEXT or DSS_DISABLED);
      end;
    end;
  end;
end;

{TThreadTimer}
constructor TThreadTimer.Create;
begin
  inherited Create(True);
  FreeOnTerminate := False;
  FEnabled := False;
  FInterval := 100;
  Priority := tpLowest;
end;

procedure TThreadTimer.SetEnabled(Value: Boolean);
begin
  if FEnabled <> Value then
  begin
    FEnabled := Value;
    Suspended := not Value;
  end;
end;

procedure TThreadTimer.DoTimer;
begin
  if Assigned(FOnTimer) then
    FOnTimer(Self);
end;

procedure TThreadTimer.Execute;
begin
  while not Terminated or not Application.Terminated do
  begin
    if FEnabled then
    begin
      Sleep(FInterval);
      Synchronize(DoTimer);
    end;
  end;
end;

{TCoolScrollingText}
constructor TCoolScrollingText.Create(AOwner: TComponent);
begin
  FGlyph := TGlyph.Create;
  TGlyph(FGlyph).OnChange := GlyphChanged;
  inherited Create(AOwner);

  ControlStyle := ControlStyle + [csReplicatable];

  FStrings := TStringList.Create;
  TStringList(FStrings).OnChange := StringsChange;

  FTimer := TThreadTimer.Create;
  FTimer.OnTimer := DoTimer;

  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;
  FidWallpaper := -1;
  SetBounds(Left, Top, 97, 15);

  {$IFNDEF DELPHI4_OR_ABOVE}
  FAutoSize := False;
  {$ENDIF}

  FActive := False;
  FInterval := 25;
  FAlignment := taLeftJustify;
  FScrollDirection := sdRightToLeft;

  FShadowColor := clBtnHighlight;
  FShadowSize := 1;
  FShadowPos := spLeftTop;
  FSimpleView := False;
  FShowAccelChar := True;
  FTransparent := False;
  FStretched := False;

  FBackBitmap := TBitmap.Create;
end;

destructor TCoolScrollingText.Destroy;
begin
  FBackBitmap.Free;

  TerminateThread(FTimer.Handle, 0);
  FTimer.Free;

  FStrings.Free;
  FCoolImagesChangeLink.Free;
  if Assigned(FWallpaper) then FWallpaper.Free;
  inherited Destroy;
  TGlyph(FGlyph).Free;
end;

procedure TCoolScrollingText.GlyphChanged(Sender: TObject);
begin
  Invalidate;
end;

function TCoolScrollingText.GetGlyph: TBitmap;
begin
  Result := TGlyph(FGlyph).Glyph;
end;

procedure TCoolScrollingText.SetGlyph(Value: TBitmap);
begin
  TGlyph(FGlyph).Glyph := Value;
  AdjustBounds;
  Invalidate;
end;

function TCoolScrollingText.GetNumGlyphs: TNumGlyphs;
begin
  Result := TGlyph(FGlyph).NumGlyphs;
end;

procedure TCoolScrollingText.SetNumGlyphs(Value: TNumGlyphs);
begin
  if Value < 0 then Value := 1 else
      if Value > 2 then Value := 2;

  if Value <> TGlyph(FGlyph).NumGlyphs then
  begin
    TGlyph(FGlyph).NumGlyphs := Value;
    Invalidate;
  end;
end;

procedure TCoolScrollingText.SetStrings(Value: TStrings);
begin
  FStrings.Assign(Value);
  Invalidate;
end;

function TCoolScrollingText.GetStrings: TStrings;
begin
  Result := FStrings;
end;

procedure TCoolScrollingText.SetInterval(Value: Cardinal);
begin
  if FInterval <> Value then
  begin
    FInterval := Value;
    UpdateTimer;
    Invalidate;
  end;
end;

procedure TCoolScrollingText.SetActive(Value: Boolean);
begin
  if FActive <> Value then
  begin
    FActive := Value;
    UpdateTimer;
    Invalidate;
  end;
end;

procedure TCoolScrollingText.SetAlignment(Value: TAlignment);
begin
  if FAlignment <> Value then
  begin
    FAlignment := Value;
    Invalidate;
  end;
end;

procedure TCoolScrollingText.SetTransparent(Value: Boolean);
begin
  if FTransparent <> Value then
  begin
    FTransparent := Value;
    Invalidate;
  end;
end;

procedure TCoolScrollingText.SetScrollDirection(Value: TScrollDirection);
begin
  if FScrollDirection <> Value then
  begin
    FScrollDirection := Value;

    if FScrollDirection in [sdLeftToRight, sdRightToLeft] then
      FAlignment := taLeftJustify;

    Invalidate;
  end;
end;

procedure TCoolScrollingText.SetShadowColor(Value: TColor);
begin
  if FShadowColor <> Value then
  begin
    FShadowColor := Value;
    FSimpleView := False;
    Invalidate;
  end;
end;

procedure TCoolScrollingText.SetShadowSize(Value: Byte);
begin
  if FShadowSize <> Value then
  begin
    FShadowSize := Value;
    FSimpleView := False;
    Invalidate;
  end;
end;

procedure TCoolScrollingText.SetShadowPos(Value: TShadowPosition);
begin
  if FShadowPos <> Value then
  begin
    FShadowPos := Value;
    FSimpleView := False;
    Invalidate;
  end;
end;

procedure TCoolScrollingText.SetSimpleView(Value: Boolean);
begin
  if FSimpleView <> Value then
  begin
    FSimpleView := Value;
    Invalidate;
  end;
end;

procedure TCoolScrollingText.SetFocusControl(Value: TWinControl);
begin
  FFocusControl := Value;
  if Value <> nil then
    Value.FreeNotification(Self);
end;

procedure TCoolScrollingText.SetShowAccelChar(Value: Boolean);
begin
  if FShowAccelChar <> Value then
  begin
    FShowAccelChar := Value;
    Invalidate;
  end;
end;

procedure TCoolScrollingText.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  FWallpaper.Assign(Value);
  Invalidate;
end;

function TCoolScrollingText.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolScrollingText.WallpaperChanged(Sender: TObject);
begin
  Invalidate;
  Perform(CM_COLORCHANGED, 0, 0);
end;

procedure TCoolScrollingText.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolScrollingText.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  Invalidate;
end;

procedure TCoolScrollingText.SetStretched(Value: Boolean);
begin
  if FStretched <> Value then
  begin
    FStretched := Value;
    Invalidate;
  end;
end;

function TCoolScrollingText.CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaper(DC, FWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

function TCoolScrollingText.IsWallpaperAssigned: Boolean;
begin
  Result := (Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty) or
            (Assigned(FWallpaper) and not FWallpaper.Empty);
end;

procedure TCoolScrollingText.CoolImagesChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolScrollingText.DoPaintBackground;
begin
  FBackBitmap.Width := Parent.Width;
  FBackBitmap.Height := Parent.Height;
  SendMessage(Parent.Handle, WM_ERASEBKGND, FBackBitmap.Canvas.Handle, 0);
  SendMessage(Parent.Handle, WM_PAINT, FBackBitmap.Canvas.Handle, 0);
end;

procedure TCoolScrollingText.DoPaint(Canv: TCanvas);
const
  Alignments: array[TAlignment] of Integer = (DT_LEFT, DT_RIGHT, DT_CENTER);
var
  P: TPoint;
  R: TRect;
  Flags: Integer;
begin
  with Canv do
  begin
    if IsWallpaperassigned then
      CTLDrawWallpaper(Handle, ClientRect, FStretched, CMSRCCOPY) else
        if not FTransparent then
        begin
          Brush.Color := Self.Color;
          Brush.Style := bsSolid;
          FillRect(ClientRect);
        end;

    SetBkMode(Handle, Windows.TRANSPARENT);
    R := ClientRect;
    R.Left := X;
    R.Top := Y;

    if Assigned(Glyph) and not (Glyph.Empty) then
    begin
      P.Y := R.Top;
      case Alignment of
        taCenter:
          begin
            P.X := ((R.Right - R.Left) div 2) - ((TextWidth(Text) + Glyph.Width div NumGlyphs + LIGHT_OFFSET) div 2);
            OffsetRect(R, (Glyph.Width div NumGlyphs + LIGHT_OFFSET) div 2, 0);
          end;
        taLeftJustify:
          begin
            P.X := R.Left;
            OffsetRect(R, Glyph.Width div NumGlyphs + LIGHT_OFFSET, 0);
          end;
        taRightJustify:
          P.X := R.Right - TextWidth(Text) - Glyph.Width div NumGlyphs - LIGHT_OFFSET;
      end;
      TGlyph(FGlyph).DrawImage(Canv, P, Enabled, True, clNone);
    end;

    Flags := DT_NOCLIP or Alignments[FAlignment];
    DoDrawText(Canv, R, Flags);
  end;
end;

procedure TCoolScrollingText.DoPaintEvent;
var
  R: TRect;
  B: TBitmap;
  Reposition: Boolean;
begin
  case FScrollDirection of
    sdBottomToTop:
      begin
        R := BusyRect;
        if Y > -(R.Bottom - R.Top) then
          Inc(Y, -SCROLL_COUNT) else
            begin
              Reposition := False;
              if Assigned(FOnTextScrolled) then FOnTextScrolled(Self, Reposition);
              SetTextCoordinates(Reposition);
            end;
      end;
    sdTopToBottom:
      begin
        if Y < Height then
          Inc(Y, SCROLL_COUNT) else
            begin
              Reposition := False;
              if Assigned(FOnTextScrolled) then FOnTextScrolled(Self, Reposition);
              SetTextCoordinates(Reposition);
            end;
      end;
    sdLeftToRight:
      begin
        if X < Width then
          Inc(X, SCROLL_COUNT) else
            begin
              Reposition := False;
              if Assigned(FOnTextScrolled) then FOnTextScrolled(Self, Reposition);
              SetTextCoordinates(Reposition);
            end;
      end;
    sdRightToLeft:
      begin
        R := BusyRect;
        if X > -(R.Right - R.Left)  then
          Inc(X, -SCROLL_COUNT) else
            begin
              Reposition := False;
              if Assigned(FOnTextScrolled) then FOnTextScrolled(Self, Reposition);
              SetTextCoordinates(Reposition);
            end;
      end;
  end;

  B := TBitmap.Create;
  try
    B.Width := Width;
    B.Height := Height;

    if FTransparent then
    begin
      R := ClientRect;
      OffsetRect(R, Left, Top);
      B.Canvas.CopyRect(Rect(0, 0, B.Width, B.Height), FBackBitmap.Canvas, R);
    end;

    DoPaint(B.Canvas);
    Canvas.Draw(0, 0, B);
  finally
    B.Free;
  end;
end;

procedure TCoolScrollingText.CMTextChanged(var Message: TMessage);
begin
  inherited;
  AdjustBounds;
  Invalidate;
end;

procedure TCoolScrollingText.CMFontChanged(var Message: TMessage);
begin
  inherited;
  AdjustBounds;
  Invalidate;
end;

procedure TCoolScrollingText.CMDialogChar(var Message: TCMDialogChar);
begin
  if (FFocusControl <> nil) and Enabled and ShowAccelChar and
    IsAccel(Message.CharCode, FStrings.Text) then
    with FFocusControl do
      if CanFocus then
      begin
        SetFocus;
        Message.Result := 1;
      end;
end;

{$IFNDEF DELPHI4_OR_ABOVE}
procedure TCoolScrollingText.SetAutoSize(Value: Boolean);
begin
  if FAutoSize <> Value then
  begin
    FAutoSize := Value;
    AdjustBounds;
    Invalidate;
  end;
end;
{$ENDIF}

procedure TCoolScrollingText.CMEnabledChanged(var Message: TMessage);
begin
  inherited;
  Invalidate;
end;

procedure TCoolScrollingText.SetTextCoordinates(Initial: Boolean);
begin
  if (csDesigning in ComponentState) or Initial then
  begin
    X := 0;
    Y := 0;
  end else
  case FScrollDirection of
    sdBottomToTop:
      begin
        X := 0;
        Y := Height;
      end;
    sdTopToBottom:
      begin
        X := 0;
        Y := -Height;
      end;
    sdLeftToRight:
      begin
        X := -Width;
        Y := 0;
      end;
    sdRightToLeft:
      begin
        X := Width;
        Y := 0;
      end;
  end;
  Invalidate;
end;

procedure TCoolScrollingText.StringsChange(Sender: TObject);
begin
  Invalidate;
  AdjustBounds;
end;

procedure TCoolScrollingText.DoTimer(Sender: TObject);
begin
  if not (csDestroying in ComponentState) then
    DoPaintEvent;
end;

procedure TCoolScrollingText.UpdateTimer;
begin
  if not DesignTime(Self) then
  begin
    FTimer.Enabled := FActive;
    FTimer.Interval := FInterval;

    if FTimer.Enabled then
    begin
      Hide;
      DoPaintBackground;
    end;
  end;
end;

{$IFDEF BCB}
procedure TCoolScrollingText.DoDrawText(Canv: TCanvas; var Recty: TRect; Flags: {$IFNDEF VER125}Word{$ELSE}Longint{$ENDIF});
{$ELSE}
procedure TCoolScrollingText.DoDrawText(Canv: TCanvas; var Recty: TRect; Flags: Longint);
{$ENDIF}
const
  Prefixes: array[Boolean] of Integer = (0, DT_NOPREFIX);
var
  Text: string;
begin
  Text := FStrings.Text + ' ';
  Flags := Flags or Prefixes[FShowAccelChar];
  {$IFDEF DELPHI4_OR_ABOVE}
  Flags := DrawTextBiDiModeFlags(Flags);
  {$ENDIF}
  Canv.Font := Self.Font;

  if not Enabled then
    Draw3DText(Canv.Handle, Recty, {$IFDEF BCB}{$IFDEF VER100}SPToInt({$ENDIF}{$ENDIF} spRightBottom {$IFDEF BCB}{$IFDEF VER100}){$ENDIF}{$ENDIF}, PChar(FStrings.Text), Flags, clBtnShadow, clBtnHighlight, 1) else
      if FSimpleView then
        DrawText(Canv.Handle, PChar(Text), Length(Text), Recty, Flags) else
          Draw3DText(Canv.Handle, Recty, {$IFDEF BCB}{$IFDEF VER100}SPToInt({$ENDIF}{$ENDIF} FShadowPos {$IFDEF BCB}{$IFDEF VER100}){$ENDIF}{$ENDIF}, PChar(Text), Flags, Font.Color, FShadowColor, FShadowSize);
end;

procedure TCoolScrollingText.Paint;
begin
  inherited Paint;
  DoPaint(Canvas);
end;

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

  if (Operation = opRemove) and Assigned(FCoolImages) and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

procedure TCoolScrollingText.Loaded;
begin
  inherited Loaded;
  AdjustBounds;
  SetTextCoordinates(False);
  UpdateTimer;
end;

procedure TCoolScrollingText.SetName(const Value: TComponentName);
var
  ChangeText: Boolean;
begin
  ChangeText := Name = TrimRight(FStrings.Text);
  inherited SetName(Value);
  if ChangeText then
    FStrings.Text := Name;
end;

function TCoolScrollingText.BusyRect: TRect;
const
  WordWraps: array[Boolean] of Word = (0, DT_WORDBREAK);
begin
  Result := ClientRect;

  DoDrawText(Canvas, Result, DT_EXPANDTABS or DT_CALCRECT or WordWraps[FStrings.Count > 1]);
  if Assigned(Glyph) and not (Glyph.Empty) then
  begin
    Result.Right := Result.Right + Glyph.Width div NumGlyphs + LIGHT_OFFSET;
    if Result.Bottom < Glyph.Height then Result.Bottom := Glyph.Height;
  end;
end;

procedure TCoolScrollingText.AdjustBounds;
var
  X: Integer;
  R: TRect;
  {$IFDEF DELPHI4_OR_ABOVE}
  AAlignment: TAlignment;
  {$ENDIF}
begin
  if not (csReading in ComponentState) and AutoSize and Assigned(Parent) then
  begin
    R := BusyRect;
    X := Left;

    {$IFDEF DELPHI4_OR_ABOVE}
    AAlignment := Alignment;
    if UseRightToLeftAlignment then ChangeBiDiModeAlignment(AAlignment);
    {$ENDIF}
    if Alignment = taRightJustify then Inc(X, Width - R.Right);

    SetBounds(X, Top, R.Right, R.Bottom);
  end;
end;

{$IFDEF DELPHI4_OR_ABOVE}
procedure TCoolScrollingText.AdjustSize;
begin
  inherited AdjustSize;
  AdjustBounds;
end;
{$ENDIF}

{TCoolFormHook}
constructor TCoolFormHook.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FWindowHook := TWndHook.Create(Self);
  FWindowHook.OnBeforeMessage := BeforeMessage;
  FWindowHook.OnAfterMessage := AfterMessage;
  FWindowHook.OnChangeWinControl := ChangeControl;

  Form := TCoolForm(Owner);

  FWindowHook.WinControl := TWinControl(Owner);
  FWindowHook.Active := True;

  FRoundXOffset := 0;
  FRoundYOffset := 0;
  FStartColor := clBlue;
  FEndColor := clBlack;
  FGradientDirection := gdVertical;

  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;
  FidWallpaper := -1;
  FTransparencyIntense := 128;

  FDragRect := Rect(0, 0, 0, 0);
end;

destructor TCoolFormHook.Destroy;
begin
  if FormAssigned then Options := [];
  if Assigned(FWallpaper) then FWallPaper.Free;
  FCoolImagesChangeLink.Free;
  FWindowHook.Free;
  inherited Destroy;
end;

procedure TCoolFormHook.Loaded;
begin
  inherited Loaded;
  // For a while... Gotta be fixed later.
  FWindowHook.Active := False;
  FWindowHook.WinControl := TWinControl(Owner);
  FWindowHook.Active := True;
end;

function TCoolFormHook.FormAssigned: Boolean;
begin
  Result := Assigned(Form);

  if Result then
    Result := Form.HandleAllocated;

  if Result then
    Result := not (csDestroying in Form.ComponentState);
end;

procedure TCoolFormHook.BeforeMessage(Sender: TObject; var Msg: TMessage; var Handled: Boolean);
begin
  Handled := False;
  if Assigned(Form) and not (csDesigning in ComponentState) then
    with Form, TWMEraseBkgnd(Msg) do
      if (Msg = WM_ERASEBKGND) and ((ocPaintGradiently in FOptions) or (ocPaintWallpaper in FOptions)) then
      begin
        if (ocPaintGradiently in FOptions) then
        begin
          FillGradientRect(DC, ClientRect, FStartColor, FEndColor, GRADIENT_BANDS, FGradientDirection = gdHorizontal);
          Handled := True;
        end else
        if (ocPaintWallpaper in FOptions) then
          Handled := CTLDrawWallpaper(DC, ClientRect, (ocStretchWallpaper in FOptions), SRCCOPY);
      end;
end;

procedure TCoolFormHook.AfterMessage(Sender: TObject; var Msg: TMessage; var Handled: Boolean);
var
  P: TPoint;
begin
  if Assigned(Form) and not (csDesigning in ComponentState) then
    with Form do
      case Msg.msg of
        WM_NCHITTEST:
          with TWMNCHitTest(Msg) do
          begin
            if (Result = htClient) and (ocDragUsingClientArea in FOptions) then
              if (FDragRect.Left = 0) and (FDragRect.Top = 0) and (FDragRect.Right = 0) and (FDragRect.Bottom = 0) then
                Result := htCaption
              else
                begin
                  P := ScreenToClient(Point(XPos, YPos));
                  if PtInRect(FDragRect, P) then
                    Result := htCaption;
                end;

            if (Result = Windows.htCaption) and (ocNoDragUsingCaption in FOptions) then
              Result := Windows.htNowhere;
          end;

        WM_SIZE:
          with TWMSize(Msg) do
            if (SizeType = SIZE_MAXIMIZED) or (SizeType = SIZE_RESTORED) then
              if (ocPaintGradiently in FOptions) or (ocPaintWallpaper in FOptions) then
              begin
                Perform(WM_ERASEBKGND, 0, 0);
                Perform(CM_COLORCHANGED, 0, 0);
              end;
      end;
end;

procedure TCoolFormHook.ChangeControl(Sender: TObject);
begin
  Form := TCoolForm(Sender);
end;

procedure TCoolFormHook.WallpaperChanged(Sender: TObject);
begin
  if Assigned(Form) then
  begin
    Form.Invalidate;
    Form.Perform(CM_COLORCHANGED, 0, 0);
  end;
end;

procedure TCoolFormHook.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  FWallpaper.Assign(Value);

  if not (csDesigning in ComponentState) and Assigned(Form) then
  begin
    Form.Perform(CM_COLORCHANGED, 0, 0);
    Form.Invalidate;
  end;
end;

function TCoolFormHook.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolFormHook.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;

    if not (csDesigning in ComponentState) and Assigned(Form) then
    begin
      Form.Perform(CM_COLORCHANGED, 0, 0);
      Form.Invalidate;
    end;
  end;                    
end;

procedure TCoolFormHook.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  if not (csDesigning in ComponentState) and Assigned(Form) then
  begin
    Form.Perform(CM_COLORCHANGED, 0, 0);
    Form.Invalidate;
  end;
end;

function TCoolFormHook.CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaper(DC, FWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

procedure TCoolFormHook.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FCoolImages) and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

procedure TCoolFormHook.CoolImagesChange(Sender: TObject);
begin
  if not (csDesigning in ComponentState) and Assigned(Form) then
  begin
    Form.Perform(CM_COLORCHANGED, 0, 0);
    Form.Invalidate;
  end;
end;

procedure TCoolFormHook.SetOptions(Value: TCoolOptions);
var
  R: TRect;
  P: TPoint;
  FullRgn, ClientRgn,
  CtlRgn, RoundRgn, RoundRgn_2: THandle;
  X, Y, CtlX, CtlY: Integer;

  procedure CreateRoundRgn;
  var
    K: Integer;
  begin
    GetWindowRgn(Form.Handle, FullRgn);
    DeleteObject(FullRgn);

    R := Form.ClientRect;

    if FRoundXOffset > 0 then
      FRoundXOffset := -FRoundXOffset;

    if FRoundYOffset > 0 then
      FRoundYOffset := -FRoundYOffset;

    InflateRect(R, FRoundXOffset, FRoundYOffset);
    RoundRgn := CreateEllipticRgnIndirect(R);

    if (ocPaintTransparently in Value) then
    begin
      P := Form.ClientOrigin;
      X := P.X - Form.Left;
      Y := P.Y - Form.Top;

      InflateRect(R, -X, -Y);
      RoundRgn_2 := CreateEllipticRgnIndirect(R);

      for K := 0 to Form.ControlCount-1 do
        with Form.Controls[K] do
          if Visible then
          begin
            CtlX := X + Left;
            CtlY := Y + Top;
            CtlRgn := CreateRectRgn(CtlX, CtlY, CtlX + Width, CtlY + Height);
            CombineRgn(RoundRgn_2, RoundRgn_2, CtlRgn, RGN_DIFF);
            DeleteObject(CtlRgn);
          end;

      CombineRgn(RoundRgn, RoundRgn, RoundRgn_2, RGN_DIFF);
      DeleteObject(RoundRgn_2);
    end;
    SetWindowRgn(Form.Handle, RoundRgn, TRUE);
  end;

  procedure CreateTransparentRgn;
  var
    K: Integer;
  begin
    GetWindowRgn(Form.Handle, FullRgn);
    DeleteObject(FullRgn);

    P := Form.ClientOrigin;
    X := P.X - Form.Left;
    Y := P.Y - Form.Top;

    FullRgn := CreateRectRgn(0, 0, Form.Width, Form.Height);
    ClientRgn := CreateRectRgn(X, Y, X + Form.ClientWidth, Y + Form.ClientHeight);
    CombineRgn(FullRgn, FullRgn, ClientRgn, RGN_DIFF);

    for K := 0 to Form.ControlCount-1 do
      with Form.Controls[K] do
        if Visible then
        begin
          CtlX := X + Left;
          CtlY := Y + Top;
          CtlRgn := CreateRectRgn(CtlX, CtlY, CtlX + Width, CtlY + Height);
          CombineRgn(FullRgn, FullRgn, CtlRgn, RGN_OR);
          DeleteObject(CtlRgn);
        end;

    SetWindowRgn(Form.Handle, FullRgn, TRUE);
    DeleteObject(ClientRgn);
  end;

  procedure CreateNormalRgn;
  begin
    GetWindowRgn(Form.Handle, FullRgn);
    DeleteObject(FullRgn);

    SetWindowRgn(Form.Handle, 0, TRUE);
  end;

  procedure SetSemiTransparentForm;
  var
    UHandle: HWND;
    SetLayeredWindowAttributes: function (Wnd: hwnd; crKey: ColorRef; bAlpha: Byte; dwFlags: DWord): boolean; stdcall;
  begin
    SetWindowLong(Form.Handle, GWL_EXSTYLE, GetWindowLong(Form.Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
    UHandle := LoadLibrary('user32.dll');
    if UHandle <> 0 then
    begin
      @SetLayeredWindowAttributes := GetProcAddress(UHandle, 'SetLayeredWindowAttributes');

      if @SetLayeredWindowAttributes <> nil then
        SetLayeredWindowAttributes(Form.Handle, 0, FTransparencyIntense, LWA_ALPHA);
  
      FreeLibrary(UHandle);
    end;
  end;

  procedure RemoveSemiTransparentForm;
  begin
    SetWindowLong(Form.Handle, GWL_EXSTYLE, GetWindowLong(Form.Handle, GWL_EXSTYLE) and not WS_EX_LAYERED);
  end;

begin
  if Assigned(Form) and (FOptions <> Value) then
  begin
    if (ocNoCaption in Value) and (GetWindowLong(Form.Handle, GWL_STYLE) and WS_CAPTION <> 0) then
    begin
      case Form.BorderStyle of
        bsSingle, bsSizeable:
          begin
            SetWindowLong(Form.Handle, GWL_STYLE, GetWindowLong(Form.Handle, GWL_STYLE) and not WS_CAPTION);
            SetWindowPos(Form.Handle, 0, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_FRAMECHANGED);
          end;
        bsDialog, bsToolWindow, bsSizeToolWin:
          begin
            SetWindowLong(Form.Handle, GWL_STYLE, GetWindowLong(Form.Handle, GWL_STYLE) and not WS_CAPTION);
            SetWindowPos(Form.Handle, 0, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_FRAMECHANGED);
          end;
      end;
    end else
    if not (ocNoCaption in Value) and (GetWindowLong(Form.Handle, GWL_STYLE) and WS_CAPTION = 0) then
    begin
      case Form.BorderStyle of
        bsSingle, bsSizeable:
          begin
            SetWindowLong(Form.Handle, GWL_STYLE, GetWindowLong(Form.Handle, GWL_STYLE) or WS_CAPTION);
            SetWindowPos(Form.Handle, 0, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_FRAMECHANGED);
          end;
        bsDialog, bsToolWindow, bsSizeToolWin:
          begin
            SetWindowLong(Form.Handle, GWL_STYLE, GetWindowLong(Form.Handle, GWL_STYLE) or WS_CAPTION);
            SetWindowPos(Form.Handle, 0, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_FRAMECHANGED);
          end;
      end;
    end;

    if (ocPaintTransparently in Value) and not (ocPaintTransparently in FOptions) then
      if (ocRoundedForm in Value) then
        CreateRoundRgn else
          CreateTransparentRgn else
            if (ocPaintTransparently in FOptions) and not (ocPaintTransparently in Value) then
              if ocRoundedForm in Value then
                CreateRoundRgn else
                  CreateNormalRgn;

    if (ocRoundedForm in Value) and not (ocRoundedForm in FOptions) then
      CreateRoundRgn else
        if (ocRoundedForm in FOptions) and not (ocRoundedForm in Value) then
          if ocPaintTransparently in Value then
            CreateTransparentRgn else
              CreateNormalRgn;

    if ((ocPaintWallpaper in Value) and not (ocPaintWallpaper in FOptions)) or ((ocPaintWallpaper in FOptions) and not (ocPaintWallpaper in Value)) then
      Form.Perform(CM_COLORCHANGED, 0, 0);

    if (ocPaintFormSemiTransparently in Value) and not (ocPaintFormSemiTransparently in FOptions) then
      SetSemiTransparentForm else
        if not (ocPaintFormSemiTransparently in Value) and (ocPaintFormSemiTransparently in FOptions) then
          RemoveSemiTransparentForm;

    Form.Invalidate;
  end;

  FOptions := Value;
  if FormAssigned then
    Form.Refresh;
end;

procedure TCoolFormHook.SetStartColor(Value: TColor);
begin
  if FStartColor <> Value then
  begin
    FStartColor := Value;

    if not (csDesigning in ComponentState) and Assigned(Form) and (ocPaintGradiently in FOptions) then
      Form.Invalidate;
  end;
end;

procedure TCoolFormHook.SetEndColor(Value: TColor);
begin
  if FEndColor <> Value then
  begin
    FEndColor := Value;
    if not (csDesigning in ComponentState) and Assigned(Form) and (ocPaintGradiently in FOptions) then
      Form.Invalidate;
  end;
end;

procedure TCoolFormHook.SetGradientDirection(Value: TGradientDirection);
begin
  if FGradientDirection <> Value then
  begin
    FGradientDirection := Value;

    if (ocPaintGradiently in FOptions) and Assigned(Form) then
      Form.Invalidate;
  end;
end;

procedure TCoolFormHook.SetTransparencyIntense(Value: TTransparencyIntense);
begin
  if FTransparencyIntense <> Value then
  begin
    FTransparencyIntense := Value;
    if (ocPaintFormSemiTransparently in Options) then
    begin
      Options := Options - [ocPaintFormSemiTransparently];
      Options := Options + [ocPaintFormSemiTransparently];
    end;
  end;
end;

{TMDICoolFormHook}
constructor TMDICoolFormHook.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
end;

destructor TMDICoolFormHook.Destroy;
begin
  if Assigned(Form) then
    UnHookWndProc(Form.ClientHandle);
  inherited Destroy;
end;

procedure TMDICoolFormHook.SetOptions(Value: TCoolOptions);
begin
  if Assigned(Form) and (FOptions <> Value) then
    if (oc3dMDIForm in Value) and not (oc3dMDIForm in FOptions) then
    begin
      SetWindowLong(Form.ClientHandle, GWL_EXSTYLE, GetWindowLong(Form.ClientHandle, GWL_EXSTYLE) or WS_EX_CLIENTEDGE);
      SetWindowPos(Form.ClientHandle, 0, 0, 0, 0, 0, SWP_DRAWFRAME or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER);
    end else
    if (oc3dMDIForm in FOptions) and not (oc3dMDIForm in Value) then
    begin
      SetWindowLong(Form.ClientHandle, GWL_EXSTYLE, GetWindowLong(Form.ClientHandle, GWL_EXSTYLE) and not WS_EX_CLIENTEDGE);
      SetWindowPos(Form.ClientHandle, 0, 0, 0, 0, 0, SWP_DRAWFRAME or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER);
    end;

  inherited SetOptions(Value);
end;

procedure TMDICoolFormHook.Loaded;
begin
  inherited Loaded;
  if Assigned(Form) then
    HookWndProc(Form.ClientHandle);
end;

procedure TMDICoolFormHook.HookWndProc(AHandle: HWND);
begin
  FNewProc := MakeObjectInstance(ClientWndProc);
  FDefProc := Pointer(SetWindowLong(AHandle, GWL_WNDPROC, LongInt(FNewProc)));
end;

procedure TMDICoolFormHook.UnHookWndProc(AHandle: HWND);
begin
  SetWindowLong(AHandle, GWL_WNDPROC, LongInt(FDefProc));
  FreeObjectInstance(FNewProc);
end;

procedure TMDICoolFormHook.HookedPaint(Sender: TObject);
begin
  with Sender as TForm do
  begin
    if ocGradientForMDIChildren in FOptions then
      FillGradientRect(Canvas.Handle, ClientRect, FStartColor, FEndColor, GRADIENT_BANDS, FGradientDirection = gdHorizontal);

    if (ocWallpaperForMDIChildren in FOptions) then
      CTLDrawWallpaper(Canvas.Handle, ClientRect, (ocStretchWallpaper in FOptions), SRCCOPY);

    if Assigned(FOldChildPaint) then
      FOldChildPaint(Self);
  end;
end;

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

procedure TMDICoolFormHook.ClientWndProc(var Message: TMessage);
var
  DC: HDC;
begin
  if Assigned(Form) then
  try
    case Message.Msg of
      WM_ERASEBKGND:
        begin
          if (ocPaintGradiently in FOptions) then
          begin
            DC := Message.wParam;
            FillGradientRect(DC, Form.ClientRect, FStartColor, FEndColor, GRADIENT_BANDS, FGradientDirection = gdHorizontal);
          end;

          if (ocPaintWallpaper in FOptions) then
          begin
            DC := Message.wParam;
            CTLDrawWallpaper(DC, Form.ClientRect, (ocStretchWallpaper in FOptions), SRCCOPY);
          end;
          Exit;
        end;

      WM_MDICREATE:
        with TWMMDICreate(Message) do
          if (Form.MDIChildCount <> 0) then
          begin
            FOldChildPaint := Form.MDIChildren[Form.MDIChildCount-1].OnPaint;
            Form.MDIChildren[Form.MDIChildCount-1].OnPaint := HookedPaint;
            if (ocNoMDIChildrensCaptions in FOptions) then
              MDICreateStruct.Style := MDICreateStruct.Style and (not WS_CAPTION) ;
          end;

      WM_VSCROLL, WM_HSCROLL:
        InvalidateRectEx(Form.ClientHandle, Form.ClientRect, True);
    end;

    with Message do
      Result := CallWindowProc(FDefProc, Form.ClientHandle, Msg, WParam, LParam);
  except
    Application.HandleException(Self);
  end;
end;

{TCoolBtn}
constructor TCoolBtn.Create(AOwner: TComponent);
begin
  FGlyph := TGlyph.Create;
  TGlyph(FGlyph).OnChange := GlyphChanged;
  inherited Create(AOwner);
  FImageChangeLink := TChangeLink.Create;
  FImageChangeLink.OnChange := ImageListChange;
  FCanvas := TCanvas.Create;
  FOptions := [];
  {$IFNDEF VER90}
  ControlStyle := ControlStyle + [csReflector];
  {$ENDIF}

  FShadowColor := clBtnHighlight;
  FShadowSize := 1;
  FShadowPos := spLeftTop;
  FSimpleView := False;
  Color := clBtnFace;

  FColorEnd := clBtnShadow;
  FColorStart := clBtnFace;
  FGradientDirection := gdHorizontal;
  FLayout := blGlyphLeft;
  FSpacing := 4;
  FMargin := -1;
  FImageIndex := 0;

  FTimer := TTimer.Create(Self);
  FTimer.OnTimer := UpdateTimer;
  FTimer.Interval := 1000;
  FTimer.Enabled := False;

  FInterval := 1000;
  FAnimated := False;
  FTransparencyLevel := 0;

  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;
  FidWallpaper := -1;
  FMouseInControl := False;
  ForcedFlat := False;
  FBtnPaintOptions := [bpoDrawFocus, bpoDrawDefault];
end;

destructor TCoolBtn.Destroy;
begin
  FCoolImagesChangeLink.Free;
  FImageChangeLink.Free;
  FTimer.Free;
  inherited Destroy;
  if Assigned(FWallpaper) then FWallPaper.Free;
  FCanvas.Free;
  TGlyph(FGlyph).Free;
end;

procedure TCoolBtn.SetGlyph(Value: TBitmap);
begin
  TGlyph(FGlyph).Glyph := Value;
  Invalidate;
end;

function TCoolBtn.GetGlyph: TBitmap;
begin
  Result := TGlyph(FGlyph).Glyph;
end;

procedure TCoolBtn.SetLayout(Value: TButtonLayout);
begin
  if FLayout <> Value then
  begin
    FLayout := Value;
    Invalidate;
  end;
end;

function TCoolBtn.GetNumGlyphs: TNumGlyphs;
begin
  Result := TGlyph(FGlyph).NumGlyphs;
end;

procedure TCoolBtn.SetNumGlyphs(Value: TNumGlyphs);
begin
  if Value < 0 then Value := 1 else
      if Value > 2 then Value := 2;

  if Value <> TGlyph(FGlyph).NumGlyphs then
  begin
    TGlyph(FGlyph).NumGlyphs := Value;
    Invalidate;
  end;
end;

procedure TCoolBtn.SetSpacing(Value: Integer);
begin
  if FSpacing <> Value then
  begin
    FSpacing := Value;
    Invalidate;
  end;
end;

procedure TCoolBtn.SetTransparencyLevel(Value: Byte);
begin
  if FTransparencyLevel <> Value then
  begin
    FTransparencyLevel := Value;
    Invalidate;
  end;
end;

procedure TCoolBtn.SetImages(Value: TImageList);
begin
  if Assigned(Images) then
    Images.UnRegisterChanges(FImageChangeLink);

  FImages := Value;

  if Assigned(Images) then
    Images.RegisterChanges(FImageChangeLink);

  Invalidate;
end;

procedure TCoolBtn.SetMargin(Value: Integer);
begin
  if (Value <> FMargin) and (Value >= - 1) then
  begin
    FMargin := Value;
    Invalidate;
  end;
end;

procedure TCoolBtn.SetAnimated(Value: Boolean);
begin
  if FAnimated <> Value then
  begin
    FAnimated := Value;
    FTimer.Enabled := Value;
    Invalidate;
  end;
end;

procedure TCoolBtn.SetInterval(Value: Cardinal);
begin
  if FInterval <> Value then
  begin
    FInterval := Value;
    FTimer.Interval := Value;
  end;
end;

procedure TCoolBtn.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;

  FWallpaper.Assign(Value);
  Invalidate;
end;

function TCoolBtn.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolBtn.SetOptions(Value: TCoolOptions);
begin
  if FOptions <> Value then
  begin
    FOptions := Value;
    RecreateWnd;
    Perform(CM_COLORCHANGED, 0, 0);
  end;
end;

procedure TCoolBtn.SetShadowColor(Value: TColor);
begin
  if FShadowColor <> Value then
  begin
    FShadowColor := Value;
    FSimpleView := False;
    Invalidate;
  end;
end;

procedure TCoolBtn.SetShadowSize(Value: Byte);
begin
  if FShadowSize <> Value then
  begin
    FShadowSize := Value;
    FSimpleView := False;
    Invalidate;
  end;
end;

procedure TCoolBtn.SetShadowPos(Value: TShadowPosition);
begin
  if FShadowPos <> Value then
  begin
    FShadowPos := Value;
    FSimpleView := False;
    Invalidate;
  end;
end;

procedure TCoolBtn.SetSimpleView(Value: Boolean);
begin
  if FSimpleView <> Value then
  begin
    FSimpleView := Value;
    Invalidate;
  end;
end;

procedure TCoolBtn.SetColorStart(Value: TColor);
begin
  if FColorStart <> Value then
  begin
    FColorStart := Value;

    if ocPaintGradiently in FOptions then
      Invalidate;
  end;
end;

procedure TCoolBtn.SetColorEnd(Value: TColor);
begin
  if FColorEnd <> Value then
  begin
    FColorEnd := Value;

    if ocPaintGradiently in FOptions then
      Invalidate;
  end;
end;

procedure TCoolBtn.SetGradientDirection(Value: TGradientDirection);
begin
  if FGradientDirection <> Value then
  begin
    FGradientDirection := Value;

    if ocPaintGradiently in FOptions then
      Invalidate;
  end;
end;

procedure TCoolBtn.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do Style := Style or BS_OWNERDRAW;
end;

procedure TCoolBtn.SetButtonStyle(ADefault: Boolean);
begin
  if ADefault <> IsFocused then
  begin
    IsFocused := ADefault;
    Refresh;
  end;
end;

procedure TCoolBtn.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolBtn.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  Invalidate;
end;

function TCoolBtn.CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaper(DC, FWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

procedure TCoolBtn.Loaded;
begin
  inherited Loaded;
end;

procedure TCoolBtn.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FImages) and (AComponent = FImages) then
  begin
    FImages := nil;
    Invalidate;
  end;

  if (Operation = opRemove) and Assigned(FCoolImages)  and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

{$IFDEF DELPHI4_OR_ABOVE}
procedure TCoolBtn.ActionChange(Sender: TObject; CheckDefaults: Boolean);

  procedure CopyImage(ImageList: TCustomImageList; Index: Integer);
  begin
    with Glyph do
    begin
      Width := ImageList.Width;
      Height := ImageList.Height;
      Canvas.Brush.Color := clFuchsia;//! for lack of a better color
      Canvas.FillRect(Rect(0,0, Width, Height));
      ImageList.Draw(Canvas, 0, 0, Index);
    end;
  end;

begin
  inherited ActionChange(Sender, CheckDefaults);
  if Sender is TCustomAction then
    with TCustomAction(Sender) do
    begin
      { Copy image from action's imagelist }
      if (Glyph.Empty) and (ActionList <> nil) and (ActionList.Images <> nil) and
        (ImageIndex >= 0) and (ImageIndex < ActionList.Images.Count) then
        CopyImage(ActionList.Images, ImageIndex);
    end;
end;
{$ENDIF}

procedure TCoolBtn.CoolImagesChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolBtn.GlyphChanged(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolBtn.WallpaperChanged(Sender: TObject);
begin
  Invalidate;
  Perform(CM_COLORCHANGED, 0, 0);
end;

procedure TCoolBtn.ImageListChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolBtn.DrawItem(DrawItemStruct: TDrawItemStruct);
begin
  if ocRoundedForm in FOptions then
    DrawItemCircle(DrawItemStruct) else
    DrawItemRect(DrawItemStruct);

  if Assigned(FOnDrawButton) then
    FOnDrawButton(Self, FCanvas, ClientRect);
end;

procedure TCoolBtn.DrawItemCircle(DrawItemStruct: TDrawItemStruct);
var
  R: TRect;
  IsDefault: Boolean;
  IsDown: Boolean;
  IsFill: Boolean;

  procedure DrawCircleGradient;
  var
    ClipRgn: HRGN;
  begin
    ClipRgn := CreateEllipticRgnIndirect(R);
    try
      SelectClipRgn(FCanvas.Handle, ClipRgn);
      try
        FillGradientRect(FCanvas.Handle, R, FColorStart, FColorEnd, GRADIENT_BANDS, FGradientDirection = gdHorizontal);
      finally
        SelectClipRgn(FCanvas.Handle, 0);
      end;
    finally
      DeleteObject(ClipRgn);
    end;
  end;

  function DrawCircleWallpaper: Boolean;
  var
    ClipRgn: HRGN;
  begin
    ClipRgn := CreateEllipticRgnIndirect(R);
    try
      SelectClipRgn(FCanvas.Handle, ClipRgn);
      try
        Result := CTLDrawWallpaper(FCanvas.Handle, R, (ocStretchWallpaper in FOptions), cmSrcCopy);
      finally
        SelectClipRgn(FCanvas.Handle, 0);
      end;
    finally
      DeleteObject(ClipRgn);
    end;
  end;


  procedure FillCircle;
  var
    ClipRgn: HRGN;
  begin
    ClipRgn := CreateEllipticRgnIndirect(R);
    try
      SelectClipRgn(FCanvas.Handle, ClipRgn);
      try
        FCanvas.Brush.Color := Self.Color;
        FCanvas.FillRect(R);
      finally
        SelectClipRgn(FCanvas.Handle, 0);
      end;
    finally
      DeleteObject(ClipRgn);
    end;
  end;


  procedure DrawControlCircle;
  begin
    with FCanvas, R do
    begin
      Brush.Color := clBtnFace;

      if not IsFill then
        Brush.Style := bsClear else
        begin
          Brush.Style := bsSolid;
          Brush.Color := Color;
        end;

      if IsDown then
      begin
        Pen.Color := clBtnShadow;
        Ellipse(Left, Top, Pred(Right), Pred(Bottom));

        Pen.Color := clBtnHighLight;
        Ellipse(Succ(Left), Succ(Top), Right, Bottom);

        Pen.Color := clWindowFrame;
        Ellipse(Succ(Left), Succ(Top), Pred(Right), Pred(Bottom));

        Pen.Color:= clBtnShadow;
        Arc(Succ(Left), Succ(Top), Pred(Right),  Pred(Bottom), Left, Bottom, Right, Top);
      end else
      begin
        Pen.Color := clBtnShadow;
        Ellipse(Left, Top, Pred(Right), Pred(Bottom));

        Pen.Color := clWindowFrame;
        Ellipse(Succ(Left), Succ(Top), Right, Bottom);

        Pen.Color := clBtnHighLight;
        Ellipse(Succ(Left), Succ(Top), Pred(Right), Pred(Bottom));

        Pen.Color:= clBtnShadow;
        Arc(Succ(Left), Succ(Top), Pred(Right),  Pred(Bottom), Left, Bottom, Right, Top);
      end;
    end;
  end;

  procedure DrawButtonTextGlyph;
  var
    MyGlyph: TGlyph;
  begin
    FCanvas.Font := Self.Font;

    R := ClientRect;
    if IsDown then
      OffsetRect(R, 1, 1);

    if FAnimated then
    begin
      MyGlyph := TGlyph.Create;
      try
        FImages.GetBitmap(FImageIndex, MyGlyph.Glyph);
        MyGlyph.Draw(FCanvas, R, Point(0, 0), Caption, FLayout, FMargin,
          FSpacing, Enabled, True, clNone, FSimpleView, {$IFDEF BCB}{$IFDEF VER100}SPToInt({$ENDIF}{$ENDIF} FShadowPos {$IFDEF BCB}{$IFDEF VER100}){$ENDIF}{$ENDIF}, FShadowColor,
            FShadowSize, {$IFDEF DELPHI4_OR_ABOVE} DrawTextBiDiModeFlags(0) {$ELSE} 0 {$ENDIF});
      finally
        MyGlyph.Free;
      end;
    end else
    begin
      TGlyph(FGlyph).Draw(FCanvas, R, Point(0, 0), Caption, FLayout, FMargin,
        FSpacing, Enabled, True, clNone, FSimpleView, {$IFDEF BCB}{$IFDEF VER100}SPToInt({$ENDIF}{$ENDIF} FShadowPos {$IFDEF BCB}{$IFDEF VER100}){$ENDIF}{$ENDIF}, FShadowColor,
          FShadowSize, {$IFDEF DELPHI4_OR_ABOVE} DrawTextBiDiModeFlags(0) {$ELSE} 0 {$ENDIF});
    end;
  end;

  procedure DrawFocusCircle;
  begin
    with FCanvas, R do
    begin
      Pen.Color:= clBtnShadow;
      Brush.Style := bsClear;

      InflateRect(R, -4, -4);
      Ellipse(Left, Top, Right, Bottom);
    end;
  end;

begin
  with DrawItemStruct do
  begin
    IsDown := ItemState and ODS_SELECTED <> 0;
    IsDefault := ItemState and ODS_FOCUS <> 0;
    FCanvas.Handle := hDC;
    R := ClientRect;

    {Thus non rounded parts always transparent}
    PaintBackground(TrControl(Self, FTransparencyLevel), FCanvas.Handle, True);

    {What about gradiency}
    if (ocPaintGradiently in FOptions) then
    begin
      DrawCircleGradient;
      IsFill := False;
    end else

    {Here we go with the wallpapers}
    if (ocPaintWallpaper in FOptions) then
    begin
      if DrawCircleWallpaper then
        IsFill := False;
    end else

    {Transparent}
    if (ocPaintTransparently in FOptions) then
    begin
      PaintBackgroundEx(TrControl(Self, FTransparencyLevel), FCanvas.Handle, R, True);
      IsFill := False;
    end else

    IsFill := True;

    {Button itself}
    if (((ocFlatBorder in FOptions) and FMouseInControl) or not (ocFlatBorder in FOptions) or (csDesigning in ComponentState)) and not ForcedFlat then
      DrawControlCircle;

    {Here we go with the text anf glyph}
    DrawButtonTextGlyph;

    {Draw controls as focused}
    if IsFocused and IsDefault and (bpoDrawFocus in FBtnPaintOptions) then
      DrawFocusCircle;

    FCanvas.Handle := 0;
  end;
end;

procedure TCoolBtn.DrawItemRect(DrawItemStruct: TDrawItemStruct);
var
  R: TRect;
  IsDefault: Boolean;
  IsDown: Boolean;

  procedure DrawDefaultState;
  begin
    with FCanvas, R do
    begin
      Pen.Color := clWindowFrame;
      Pen.Width := 1;
      Brush.Style := bsClear;
      Rectangle(Left, Top, Right, Bottom);
      InflateRect(R, -1, -1);
    end;
  end;

  procedure DrawDownState;
  begin
    with FCanvas do
    begin
      DrawEdge(Handle, R, BDR_SUNKENINNER, BF_RECT or BF_ADJUST);
    end;
  end;

  procedure DrawNormalState;
  begin
    with FCanvas do
    begin
      DrawEdge(Handle, R, BDR_RAISEDINNER or BDR_RAISEDOUTER, BF_RECT or BF_ADJUST);
    end;
  end;

  procedure DrawSelectedState;
  begin
    with FCanvas do
    begin
      R := ClientRect;
      InflateRect(R, -4, -4);
      Pen.Color := clWindowFrame;
      Brush.Color := GetInvertedColor(FCanvas.Font.Color);
      DrawFocusRect(R);
    end;
  end;

  procedure DrawButtonTextGlyph;
  var
    MyGlyph: TGlyph;
  begin
    FCanvas.Font := Self.Font;

    R := ClientRect;
    if IsDown then
      OffsetRect(R, 1, 1);

    if FAnimated then
    begin
      MyGlyph := TGlyph.Create;
      try
        FImages.GetBitmap(FImageIndex, MyGlyph.Glyph);
        MyGlyph.Draw(FCanvas, R, Point(0, 0), Caption, FLayout, FMargin,
          FSpacing, Enabled, True, clNone, FSimpleView, {$IFDEF BCB}{$IFDEF VER100}SPToInt({$ENDIF}{$ENDIF} FShadowPos {$IFDEF BCB}{$IFDEF VER100}){$ENDIF}{$ENDIF}, FShadowColor,
            FShadowSize, {$IFDEF DELPHI4_OR_ABOVE} DrawTextBiDiModeFlags(0) {$ELSE} 0 {$ENDIF});
      finally
        MyGlyph.Free;
      end;
    end else
    begin
      TGlyph(FGlyph).Draw(FCanvas, R, Point(0, 0), Caption, FLayout, FMargin,
        FSpacing, Enabled, True, clNone, FSimpleView, {$IFDEF BCB}{$IFDEF VER100}SPToInt({$ENDIF}{$ENDIF} FShadowPos {$IFDEF BCB}{$IFDEF VER100}){$ENDIF}{$ENDIF}, FShadowColor,
          FShadowSize, {$IFDEF DELPHI4_OR_ABOVE} DrawTextBiDiModeFlags(0) {$ELSE} 0 {$ENDIF});
    end;
  end;

begin
  with DrawItemStruct do
  begin
    IsDown := ItemState and ODS_SELECTED <> 0;
    IsDefault := ItemState and ODS_FOCUS <> 0;
    FCanvas.Handle := hDC;
    R := ClientRect;

    {How do we fill}
    if (ocPaintTransparently in FOptions) then
      PaintBackground(TrControl(Self, FTransparencyLevel), FCanvas.Handle, True)
    else
      if (ocPaintWallpaper in FOptions) then
        CTLDrawWallpaper(FCanvas.Handle, ClientRect, (ocStretchWallpaper in FOptions), SRCCOPY)
      else
        if (ocPaintGradiently in FOptions) then
          FillGradientRect(FCanvas.Handle, ClientRect, FColorStart, FColorEnd, GRADIENT_BANDS, FGradientDirection = gdHorizontal)
        else
          begin
            FCanvas.Brush.Color := Color;
            FCanvas.FillRect(R);
          end;

    {DrawFrameControl doesn't allow for drawing a button as the default button, so it must be done here.}
    if (IsFocused or IsDefault) and (bpoDrawDefault in FBtnPaintOptions) then
      DrawDefaultState;

    {DrawFrameControl does not draw a pressed button correctly}
    if IsDown then
      DrawDownState else
        if (((ocFlatBorder in FOptions) and FMouseInControl) or not (ocFlatBorder in FOptions) or (csDesigning in ComponentState)) and not ForcedFlat then
          DrawNormalState;

    {Here we go with the text anf glyph}
    DrawButtonTextGlyph;

    {DrawFrameControl does not paint selected frame. What a lazy routine}
    if IsFocused and IsDefault and (bpoDrawFocus in FBtnPaintOptions) then
      DrawSelectedState;

    FCanvas.Handle := 0;
  end;
end;

procedure TCoolBtn.CNMeasureItem(var Message: TWMMeasureItem);
begin
  with Message.MeasureItemStruct^ do
  begin
    ItemWidth := Width;
    ItemHeight := Height;
  end;
end;

procedure TCoolBtn.CNDrawItem(var Message: TWMDrawItem);
begin
  DrawItem(Message.DrawItemStruct^);
end;

procedure TCoolBtn.CMFontChanged(var Message: TMessage);
begin
  inherited;
  Invalidate;
end;

procedure TCoolBtn.CMEnabledChanged(var Message: TMessage);
begin
  inherited;
  Invalidate;
end;

procedure TCoolBtn.CMColorChanged(var Message: TMessage);
begin
  inherited;
  Invalidate;
end;

procedure TCoolBtn.CMParentColorChanged(var Message: TMessage);
begin
  inherited;
  if (ocPaintTransparently in FOptions) or (ocRoundedForm in FOptions) then
    Invalidate;
end;

procedure TCoolBtn.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
  if (ocPaintTransparently in FOptions) then
    PaintBackground(TrControl(Self, FTransparencyLevel), Message.DC, True)
  else
    if (ocPaintWallpaper in FOptions) then
      CTLDrawWallpaper(Message.DC, ClientRect, (ocStretchWallpaper in FOptions), SRCCOPY)
    else
      if (ocPaintGradiently in FOptions) then
        FillGradientRect(Message.DC, ClientRect, FColorStart, FColorEnd, GRADIENT_BANDS, FGradientDirection = gdHorizontal)
      else
        inherited;
end;

procedure TCoolBtn.CMMouseEnter(var Message: TMessage);
begin
  inherited;
  FMouseInControl := True;

  if (ocFlatBorder in FOptions) then
    Invalidate;

  if Assigned(FOnMouseEnter) then
    FOnMouseEnter(Self);
end;

procedure TCoolBtn.CMMouseLeave(var Message: TMessage);
begin
  inherited;
  FMouseInControl := False;

  if (ocFlatBorder in FOptions) then
    Invalidate;

  if Assigned(FOnMouseLeave) then
    FOnMouseLeave(Self);
end;

procedure TCoolBtn.WMMouseMove(var Message: TMessage);
begin
  inherited;
end;

procedure TCoolBtn.UpdateTimer(Sender: TObject);
var
  MyDC: HDC;
  MyGlyph: TGlyph;
  TempDC: HDC;
  OldBmp, TempBmp: HBITMAP;
begin
  if Assigned(FImages) and IsWindowVisible(Handle) then
  begin
    MyDC := GetDC(Handle);
    try
      MyGlyph := TGlyph.Create;
      try
        TempDC := CreateCompatibleDC(MyDC);
        try
          TempBmp := CreateCompatibleBitmap(MyDC, Width, Height);
          try
            OldBmp := SelectObject(TempDC, TempBmp);
            PaintTo(TempDC, 0,0);

            FImages.GetBitmap(FImageIndex, MyGlyph.Glyph);

            {$IFNDEF VER90}
            FCanvas.Lock;
            {$ENDIF}
            FCanvas.Handle := TempDC;
            MyGlyph.DrawImageEx(FCanvas, ClientRect, Point(0, 0), Caption, FLayout, FMargin,
                FSpacing, Enabled, True, clNone, {$IFDEF DELPHI4_OR_ABOVE} DrawTextBiDiModeFlags(0) {$ELSE} 0 {$ENDIF});
            FCanvas.Handle := 0;
            {$IFNDEF VER90}
            FCanvas.UnLock;
            {$ENDIF}

            BitBlt(MyDC, 0, 0, Width, Height, TempDC, 0, 0, SRCCOPY);
	    SelectObject(TempDC, OldBmp);
          finally
            DeleteObject(TempBmp);
          end;
        finally
          DeleteDC(TempDC);
        end;
      finally
        MyGlyph.Free;
      end;
    finally
      ReleaseDC(Handle, MyDC);
    end;

    if FImageIndex < Pred(FImages.Count) then
      Inc(FImageIndex) else
        FImageIndex := 0;
  end;
end;

{TCoolCaptionBtn}
constructor TCoolCaptionBtn.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FCanvas := TCanvas.Create;
  {$IFNDEF VER90}
  ControlStyle := ControlStyle + [csReflector];
  {$ENDIF}

  Width := 14;
  Height := 14;
end;

destructor TCoolCaptionBtn.Destroy;
begin
  inherited Destroy;
  FCanvas.Free;
end;

procedure TCoolCaptionBtn.SetCaptionBtnType(Value: TCaptionBtnType);
begin
  if Value <> FCaptionBtnType then
  begin
    FCaptionBtnType := Value;
    RecreateWnd;
  end;
end;

function TCoolCaptionBtn.GetCaption: TCaption;
begin
  Result := inherited Caption;
end;

procedure TCoolCaptionBtn.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do Style := Style or BS_OWNERDRAW;
end;

procedure TCoolCaptionBtn.SetButtonStyle(ADefault: Boolean);
begin
  if ADefault <> IsFocused then
  begin
    IsFocused := ADefault;
    Refresh;
  end;
end;

procedure TCoolCaptionBtn.DrawItem(DrawItemStruct: TDrawItemStruct);
const
  BtnDowns: array[Boolean] of Longint = (0, DFCS_PUSHED);
  BtnTypes: array[TCaptionBtnType] of Longint = (DFCS_CAPTIONCLOSE, DFCS_CAPTIONHELP,
    DFCS_CAPTIONMAX, DFCS_CAPTIONMIN, DFCS_CAPTIONRESTORE);
var
  R: TRect;
begin
  with DrawItemStruct do
  begin
    FCanvas.Handle := hDC;
    R := Rect(0, 0, Width, Height);
    DrawFrameControl(FCanvas.Handle, R, DFC_CAPTION, BtnTypes[FCaptionBtnType] or BtnDowns[ItemState and ODS_SELECTED <> 0]);
    FCanvas.Handle := 0;
  end;
end;

procedure TCoolCaptionBtn.CNMeasureItem(var Message: TWMMeasureItem);
begin
  with Message.MeasureItemStruct^ do
  begin
    itemWidth := Width;
    itemHeight := Height;
  end;
end;

procedure TCoolCaptionBtn.CNDrawItem(var Message: TWMDrawItem);
begin
  DrawItem(Message.DrawItemStruct^);
end;

{TCoolTrackBar}
constructor TCoolTrackBar.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := [csClickEvents, csCaptureMouse,  csDoubleClicks];

  FOrientation := toHorizontal;
  FMinValue := 0;
  FMaxValue := 10;
  FPosition := 0;

  FBarSize := 10;
  FBarColor := clWindow;
  FBorderWidth := 10;
  FPageSize := 1;
  FSliding := False;

  FTickMarks := tmBottomRight;
  FTransparentThumb := True;
  FOptions := [];
  FPaintOptions := [poDrawFocusRect, poDrawTrackBar, poDrawTicks, poDrawThumb, poDrawThumbStates];

  FBevelInner := bvNone;
  FBevelOuter := bvNone;

  TabStop := True;
  Width := 150;
  Height := 40;

  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;
  FidWallpaper := -1;
  FTransparencyLevel := 0;

  FThumbImage := TBitmap.Create;

  if FOrientation = toHorizontal then
    FThumbImage.Handle := LoadBitmap(HInstance, 'THUMB_HORZ') else
      FThumbImage.Handle := LoadBitmap(HInstance, 'THUMB_VERT');
end;

destructor TCoolTrackBar.Destroy;
begin
  FCoolImagesChangeLink.Free;
  FThumbImage.Free;
  if Assigned(FWallpaper) then FWallPaper.Free;
  if Assigned(FThumbVert) then FThumbVert.Free;
  if Assigned(FThumbHorz) then FThumbHorz.Free;
  if Assigned(FThumbVertSelected) then FThumbVertSelected.Free;
  if Assigned(FThumbHorzSelected) then FThumbHorzSelected.Free;
  inherited Destroy;
end;

procedure TCoolTrackBar.SetFocus;
var
  {$IFNDEF VER90}
  Parent: TCustomForm;
  {$ELSE}
  Parent: TForm;
  {$ENDIF}
begin
  Parent := nil;
  {$IFNDEF VER90}
  if Parent is TCustomForm then
  {$ELSE}
  if Parent is TForm then
  {$ENDIF}
    Parent := GetParentForm(Self);

  if Parent <> nil then
    Parent.FocusControl(Self)
  else
    Windows.SetFocus(Handle);
end;

procedure TCoolTrackBar.SetOrientation(Value: TTrackOrientation);
begin
  if FOrientation <> Value then
  begin
    FOrientation := Value;

    if ComponentState * [csLoading, csUpdating] = [] then
      SetBounds(Left, Top, Height, Width);

    LoadImages;
    Invalidate;
  end;
end;

procedure TCoolTrackBar.SetMinValue(Value: Integer);
begin
  if FMinValue <> Value then
  begin
    if Value > FMaxValue then
      FMinValue := FMaxValue else
        FMinValue := Value;

    if FPosition < FMinValue then
      FPosition := FMinValue;

    Invalidate;
  end;
end;

procedure TCoolTrackBar.SetMaxValue(Value: Integer);
begin
  if FMaxValue <> Value then
  begin
    if Value < FMinValue then
      FMaxValue := FMinValue else
        FMaxValue := Value;

    if FPosition > FMaxValue then
      FPosition := FMaxValue;

    Invalidate;
  end;
end;

procedure TCoolTrackBar.SetTransparencyLevel(Value: Byte);
begin
  if FTransparencyLevel <> Value then
  begin
    FTransparencyLevel := Value;
    Invalidate;
  end;
end;

procedure TCoolTrackBar.SetPosition(Value: Integer);
const
  {$IFDEF DELPHI4_OR_ABOVE}
  FInnerEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER, 0);
  FOuterEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER, 0);
  {$ELSE}
  FInnerEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER);
  FOuterEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER);
  {$ENDIF}
var
  R: TRect;
  TmpBmp: TBitmap;

  MyDC: HDC;
  TempDC: HDC;
  OldBmp, TempBmp: HBITMAP;
begin
  if FPosition <> Value then
  begin
    if Value < FMinValue then
      FPosition := FMinValue else
        if Value > FMaxValue then
          FPosition := FMaxValue else
            FPosition := Value;

    if Assigned(FOnChange) then
      FOnChange(Self);

    TmpBmp := TBitmap.Create;
    try
      TmpBmp.Width := Width;
      TmpBmp.Height := Height;

      //Background
      MyDC := GetDC(Handle);
      try
        TempDC := CreateCompatibleDC(MyDC);
        try
          TempBmp := CreateCompatibleBitmap(MyDC, Width, Height);
          try
            OldBmp := SelectObject(TempDC, TempBmp);

            PaintTo(TempDC, 0, 0);
            BitBlt(TmpBmp.Canvas.Handle, 0, 0, TmpBmp.Width, TmpBmp.Height, TempDC, 0, 0, SRCCOPY);

            SelectObject(TempDC, OldBmp);
          finally
            DeleteObject(TempBmp);
          end;
        finally
          DeleteDC(TempDC);
        end;
      finally
        ReleaseDC(Handle, MyDC);
      end;

      if (poDrawTrackBar in FPaintOptions) then
        DrawTrack(TmpBmp.Canvas);

      if (poDrawTicks in FPaintOptions) then
        DrawTicks(TmpBmp.Canvas);

      if (poDrawThumb in FPaintOptions) then
        DrawThumb(TmpBmp.Canvas);

      R := ClientRect;

      {$IFDEF DELPHI4_OR_ABOVE}
      if not ((FBevelInner in [bvNone, bvSpace]) and (FBevelOuter in [bvNone, bvSpace])) then
      {$ELSE}
      if not ((FBevelInner = bvNone) and (FBevelOuter = bvNone)) then
      {$ENDIF}
      begin
        DrawEdge(TmpBmp.Canvas.Handle, R, FInnerEdges[FBevelInner] or FOuterEdges[FBevelOuter], BF_RECT);
        InflateRect(R, -2, -2);
      end;

      TmpBmp.Canvas.Brush.Color := clBlack;
      if (poDrawFocusRect in FPaintOptions) and CanFocus and Focused then
        TmpBmp.Canvas.DrawFocusRect(R);

      Canvas.Draw(0, 0, TmpBmp);
    finally
      TmpBmp.Free;
    end;
  end;
end;

procedure TCoolTrackBar.SetBarColor(Value: TColor);
begin
  if FBarColor <> Value then
  begin
    FBarColor := Value;
    Invalidate;
  end;
end;

procedure TCoolTrackBar.SetBarSize(Value: Integer);
begin
  if FBarSize <> Value then
  begin
    FBarSize := Value;
    Invalidate;
  end;
end;

procedure TCoolTrackBar.SetTickMarks(Value: TTickMark);
begin
  if FTickMarks <> Value then
  begin
    FTickMarks := Value;
    Invalidate;
  end;
end;

procedure TCoolTrackBar.SetTransparentThumb(Value: Boolean);
begin
  if FTransparentThumb <> Value then
  begin
    FTransparentThumb := Value;
    Invalidate;
  end;
end;

procedure TCoolTrackBar.SetOptions(Value: TCoolOptions);
begin
  if FOptions <> Value then
  begin
    FOptions := Value;
    Invalidate;
    Perform(CM_COLORCHANGED, 0, 0);
  end;
end;

procedure TCoolTrackBar.SetPaintOptions(Value: TPaintOptions);
begin
  if FPaintOptions <> Value then
  begin
    FPaintOptions := Value;
    Invalidate;
  end;
end;

procedure TCoolTrackBar.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;

  FWallPaper.Assign(Value);
  Invalidate;
end;

function TCoolTrackBar.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

function TCoolTrackBar.GetThumbHorz: TBitmap;
begin
  if FThumbHorz = nil then FThumbHorz := TBitmap.Create;
  Result := FThumbHorz;
end;

function TCoolTrackBar.GetThumbVert: TBitmap;
begin
  if FThumbVert = nil then FThumbVert := TBitmap.Create;
  Result := FThumbVert;
end;

function TCoolTrackBar.GetThumbHorzSelected: TBitmap;
begin
  if FThumbHorzSelected = nil then FThumbHorzSelected := TBitmap.Create;
  Result := FThumbHorzSelected;
end;

function TCoolTrackBar.GetThumbVertSelected: TBitmap;
begin
  if FThumbVertSelected = nil then FThumbVertSelected := TBitmap.Create;
  Result := FThumbVertSelected;
end;

procedure TCoolTrackBar.SetThumbHorz(Value: TBitmap);
begin
  if FThumbHorz = nil then FThumbHorz := TBitmap.Create;
  FThumbHorz.Assign(Value);

  LoadImages;
  Invalidate;
end;

procedure TCoolTrackBar.SetThumbVert(Value: TBitmap);
begin
  if FThumbVert = nil then FThumbVert := TBitmap.Create;
  FThumbVert.Assign(Value);

  LoadImages;
  Invalidate;
end;

procedure TCoolTrackBar.SetThumbHorzSelected(Value: TBitmap);
begin
  if FThumbHorzSelected = nil then FThumbHorzSelected := TBitmap.Create;
  FThumbHorzSelected.Assign(Value);
  Invalidate;
end;

procedure TCoolTrackBar.SetThumbVertSelected(Value: TBitmap);
begin
  if FThumbVertSelected = nil then FThumbVertSelected := TBitmap.Create;
  FThumbVertSelected.Assign(Value);
  Invalidate;
end;

procedure TCoolTrackBar.SetBevelInner(Value: TPanelBevel);
begin
  if FBevelInner <> Value then
  begin
    FBevelInner := Value;
    Invalidate;
  end;
end;

procedure TCoolTrackBar.SetBevelOuter(Value: TPanelBevel);
begin
  if FBevelOuter <> Value then
  begin
    FBevelOuter := Value;
    Invalidate;
  end;
end;

procedure TCoolTrackBar.WallpaperChanged(Sender: TObject);
begin
  Invalidate;
  Perform(CM_COLORCHANGED, 0, 0);
end;

procedure TCoolTrackBar.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolTrackBar.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  Invalidate;
end;

function TCoolTrackBar.CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaper(DC, FWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

procedure TCoolTrackBar.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FCoolImages) and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

procedure TCoolTrackBar.CoolImagesChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolTrackBar.DrawTrack(ACanvas: TCanvas);
begin
  if FOrientation = toVertical then
  begin
    FTrackRect.Top := FBorderWidth;
    FTrackRect.Bottom := Height - FBorderWidth;
    FTrackRect.Left := (Width - FBarSize) div 2;
    FTrackRect.Right :=	FTrackRect.Left + FBarSize;
  end else
  begin
    FTrackRect.Top := (Height - FBarSize) div 2;
    FTrackRect.Bottom := FTrackRect.Top + FBarSize;
    FTrackRect.Left := FBorderWidth;
    FTrackRect.Right :=	Width - FBorderWidth;
  end;

  ACanvas.Brush.Color := FBarColor;
  ACanvas.FillRect(FTrackRect);
  DrawEdge(ACanvas.Handle, FTrackRect, BDR_SUNKENINNER or BDR_SUNKENOUTER, BF_RECT or BF_ADJUST);
end;

procedure TCoolTrackBar.DrawTicks(ACanvas: TCanvas);
var
  Offset: Real;
  I, X, Y: Integer;
begin
  ACanvas.Pen.Color := clBlack;

  if FOrientation = toVertical then
  begin
    if FMaxValue - FMinValue > 0 then
      Offset := (Height - 2 * FBorderWidth) / (FMaxValue - FMinValue)
    else
      Offset := (Height - 2 * FBorderWidth);

    for I := 0 to (FMaxValue - FMinValue) do
    begin
      Y := Trunc(Offset * I) + FBorderWidth;

      if FTickMarks in [tmBottomRight, tmBoth] then
      begin
        ACanvas.MoveTo(FTrackRect.Right + 8, Y);
        ACanvas.LineTo(FTrackRect.Right + 12, Y);
      end;
      if FTickMarks in [tmTopLeft, tmBoth] then
      begin
        ACanvas.MoveTo(FTrackRect.Left - 12, Y);
        ACanvas.LineTo(FTrackRect.left - 8, Y);
      end;
    end;
  end else
  begin
    if FMaxValue - FMinValue > 0 then
      Offset := (Width - 2 * FBorderWidth) / (FMaxValue - FMinValue)
    else
      Offset := (Width - 2 * FBorderWidth);

    for I := 0 to (FMaxValue - FMinValue) do
    begin
      X := Trunc(Offset * I) + FBorderWidth;

      if FTickMarks in [tmBottomRight, tmBoth] then
      begin
        ACanvas.MoveTo(X, FTrackRect.Bottom + 8);
        ACanvas.LineTo(X, FTrackRect.Bottom + 12);
      end;
      if FTickMarks in [tmTopLeft, tmBoth] then
      begin
        ACanvas.MoveTo(X, FTrackRect.Top - 12);
        ACanvas.LineTo(X, FTrackRect.Top - 8);
      end;
    end;
  end;
end;

procedure TCoolTrackBar.DrawThumb(ACanvas: TCanvas);
var
  Offset: Real;
begin
  if FOrientation = toVertical then
  begin
    if FMaxValue - FMinValue > 0 then
      Offset := (Height - 2 * FBorderWidth) / (FMaxValue - FMinValue)
    else
      Offset := (Height - 2 * FBorderWidth);

    Offset := Trunc(Offset * FPosition) + FBorderWidth - FMinValue * Offset;

    FThumbRect.Left := (Width - FThumbImage.Width) div 2;
    FThumbRect.Right :=	FThumbRect.Left + FThumbImage.Width;
    FThumbRect.Top := Trunc(Offset) - FThumbImage.Height div 2;
    FThumbRect.Bottom :=  FThumbRect.Top + FThumbImage.Height;
  end else
  begin
    if FMaxValue - FMinValue > 0 then
      Offset := (Width - 2 * FBorderWidth) / (FMaxValue - FMinValue)
    else
      Offset := (Width - 2 * FBorderWidth);

    Offset := Trunc(Offset * FPosition) + FBorderWidth - FMinValue * Offset;

    FThumbRect.Left := Trunc(Offset) - FThumbImage.Width div 2;
    FThumbRect.Right :=	FThumbRect.Left + FThumbImage.Width;
    FThumbRect.Top := (Height - FThumbImage.Height) div 2;
    FThumbRect.Bottom :=  FThumbRect.Top + FThumbImage.Height;
  end;

  {$IFNDEF VER90}
  FThumbImage.Transparent := FTransparentThumb;
  ACanvas.StretchDraw(FThumbRect, FThumbImage);
  {$ELSE}
  if FTransparentThumb then
    TransparentStretchBltEx(ACanvas.Handle, FThumbImage.Canvas.Handle, FThumbRect, Rect(0, 0, FThumbImage.Width, FThumbImage.Height), FThumbImage.TransparentColor) else
      ACanvas.StretchDraw(FThumbRect, FThumbImage);
  {$ENDIF}
end;

procedure TCoolTrackBar.LoadImages;
begin
  if not FSliding and Enabled then
    if FOrientation = toHorizontal then
    begin
      if Assigned(FThumbHorz) and not FThumbHorz.Empty then
        FThumbImage.Assign(FThumbHorz) else
          FThumbImage.Handle := LoadBitmap(HInstance, 'THUMB_HORZ')
    end else
    begin
      if Assigned(FThumbVert) and not FThumbVert.Empty then
        FThumbImage.Assign(FThumbVert) else
          FThumbImage.Handle := LoadBitmap(HInstance, 'THUMB_VERT');
    end else

    if FOrientation = toHorizontal then
    begin
      if Assigned(FThumbHorzSelected) and not FThumbHorzSelected.Empty then
        FThumbImage.Assign(FThumbHorzSelected) else
          FThumbImage.Handle := LoadBitmap(HInstance, 'THUMB_HORZ_INVERT')
    end else
    begin
      if Assigned(FThumbVertSelected) and not FThumbVertSelected.Empty then
        FThumbImage.Assign(FThumbVertSelected) else
          FThumbImage.Handle := LoadBitmap(HInstance, 'THUMB_VERT_INVERT');
    end;
end;

procedure TCoolTrackBar.InvalidateThumb;
begin
  InvalidateRectEx(Handle, FThumbRect, True);
end;

procedure TCoolTrackBar.Loaded;
begin
  inherited Loaded;
  LoadImages;
end;

procedure TCoolTrackBar.Paint;
const
  {$IFDEF DELPHI4_OR_ABOVE}
  FInnerEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER, 0);
  FOuterEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER, 0);
  {$ELSE}
  FInnerEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER);
  FOuterEdges: array[TPanelBevel] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER);
  {$ENDIF}
var
  R: TRect;
begin
  inherited Paint;

  if (poDrawTrackBar in FPaintOptions) then
    DrawTrack(Canvas);

  if (poDrawTicks in FPaintOptions) then
    DrawTicks(Canvas);

  if (poDrawThumb in FPaintOptions) then
    DrawThumb(Canvas);

  R := ClientRect;

  {$IFDEF DELPHI4_OR_ABOVE}
  if not ((FBevelInner in [bvNone, bvSpace]) and (FBevelOuter in [bvNone, bvSpace])) then
  {$ELSE}
  if not ((FBevelInner = bvNone) and (FBevelOuter = bvNone)) then
  {$ENDIF}
  begin
    DrawEdge(Canvas.Handle, R, FInnerEdges[FBevelInner] or FOuterEdges[FBevelOuter], BF_RECT);
    InflateRect(R, -2, -2);
  end;

  if (poDrawFocusRect in FPaintOptions) and CanFocus and Focused then
    Canvas.DrawFocusRect(R);
end;

procedure TCoolTrackBar.DoEnter;
begin
  inherited DoEnter;
  Invalidate;
end;

procedure TCoolTrackBar.DoExit;
begin
  inherited DoExit;
  Invalidate;
end;

procedure TCoolTrackBar.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited KeyDown(Key, Shift);
  if Enabled then
    case Key of
      VK_PRIOR:
        Position := FPosition - FPageSize;

      VK_NEXT:
        Position := FPosition + FPageSize;

      VK_END:
        Position := FMaxValue;

      VK_HOME:
        Position := FMinValue;

      VK_LEFT:
        if FPosition > FMinValue then
          Position := Pred(FPosition);

      VK_RIGHT:
        if FPosition < FMaxValue then
          Position := Succ(FPosition);

      VK_DOWN:
        if FPosition < FMaxValue then
          Position := Succ(FPosition);

      VK_UP:
        if FPosition > FMinValue then
          Position := Pred(FPosition);
    end;
end;

procedure TCoolTrackBar.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  inherited MouseDown(Button, Shift, X, Y);
  if (Button = mbLeft) and Enabled then
  begin
    SetFocus;
    if PtInRect(FThumbRect, Point(X, Y)) then
    begin
      FSliding := True;

      if (poDrawThumbStates in FPaintOptions) then
        LoadImages;

      InvalidateThumb;
    end else
    if PtInRect(ClientRect, Point(X, Y)) then
    begin
      if FOrientation = toVertical then
      begin
        if Y > FThumbRect.Bottom then
          Position := Succ(Position) else

        if Y < FThumbRect.Top then
          Position := Pred(Position);
      end else
      begin
        if X > FThumbRect.Right then
          Position := Succ(Position) else

        if X < FThumbRect.Left then
          Position := Pred(Position);
      end;
    end;
  end;
end;

procedure TCoolTrackBar.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  inherited MouseUp(Button, Shift, X, Y);

  FSliding := False;

  if (poDrawThumbStates in FPaintOptions) then
    LoadImages;

  InvalidateThumb;
end;

procedure TCoolTrackBar.MouseMove(Shift: TShiftState; X, Y: Integer);
var
  Offset: Real;
  NewPos: Integer;
begin
  inherited MouseMove(Shift, X, Y);

  if FSliding then
    if FOrientation = toVertical then
    begin
      Offset := (FMaxValue - FMinValue) / (Height - 2 * FBorderWidth);
      NewPos := Round((Y - FThumbRect.Top - ((FThumbRect.Bottom - FThumbRect.Top) div 2)) * Offset);
      Position := Position + NewPos;
    end else
    begin
      Offset := (FMaxValue - FMinValue) / (Width - 2 * FBorderWidth);
      NewPos := Round((X - FThumbRect.Left - ((FThumbRect.Right - FThumbRect.Left) div 2)) * Offset);
      Position := Position + NewPos;
    end;
end;

procedure TCoolTrackBar.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
  Message.Result := DLGC_WANTARROWS;
end;

procedure TCoolTrackBar.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
  if (ocPaintTransparently in FOptions) then
    PaintBackground(TrControl(Self, FTransparencyLevel), Message.DC, True) else
      if (ocPaintWallpaper in FOptions) then
        if not CTLDrawWallpaper(Message.DC, ClientRect, (ocStretchWallpaper in FOptions), SRCCOPY) then
          inherited else else
            inherited;
end;

procedure TCoolTrackBar.WMSize(var Message: TWMSize);
begin
  inherited;
  if Height > Width then
    Orientation := toVertical else
      Orientation := toHorizontal;
end;

procedure TCoolTrackBar.CMParentColorChanged(var Message: TMessage);
begin
  inherited;
  if ocPaintTransparently in FOptions then
    Invalidate;
end;

procedure TCoolTrackBar.CMEnabledChanged(var Message: TMessage);
begin
  inherited;
  LoadImages;
  Invalidate;
end;

procedure TCoolTrackBar.CMMouseEnter (var Message: TMessage);
begin
  inherited;
  if Assigned(FOnMouseEnter) then
    FOnMouseEnter(Self);
end;

procedure TCoolTrackBar.CMMouseLeave (var Message: TMessage);
begin
  inherited;
  if Assigned(FOnMouseLeave) then
    FOnMouseLeave(Self);
end;

{TCoolThumbTab}
constructor TCoolThumbTab.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FWindowHook := TWndHook.Create(Self);
  FWindowHook.OnAfterMessage := AfterMessage;

  FTransparent := False;
  FThumbPosition := tpRightBottom;
  Width := 49;
  Height := 49;

  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;
  FidWallpaper := -1;

  FStretched := False;
end;

destructor TCoolThumbTab.Destroy;
begin
  FCoolImagesChangeLink.Free;
  if Assigned(FWallpaper) then FWallPaper.Free;
  FWindowHook.Free;
  inherited Destroy;
end;

procedure TCoolThumbTab.SetThumbPosition(Value: TCoolThumbTabPosition);
begin
  if FThumbPosition <> Value then
  begin
    FThumbPosition := Value;
    Invalidate;
  end;
end;

procedure TCoolThumbTab.SetTransparent(Value: Boolean);
begin
  if FTransparent <> Value then
  begin
    FTransparent := Value;
    Invalidate;
  end;
end;

procedure TCoolThumbTab.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  FWallPaper.Assign(Value);
  Invalidate;
end;

function TCoolThumbTab.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolThumbTab.WallpaperChanged(Sender: TObject);
begin
  Invalidate;
  Perform(CM_COLORCHANGED, 0, 0);
end;

procedure TCoolThumbTab.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolThumbTab.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  Invalidate;
end;

procedure TCoolThumbTab.SetStretched(Value: Boolean);
begin
  if FStretched <> Value then
  begin
    FStretched := Value;
    Invalidate;
  end;
end;

function TCoolThumbTab.CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaper(DC, FWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

procedure TCoolThumbTab.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FCoolImages) and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

procedure TCoolThumbTab.CoolImagesChange(Sender: TObject);
begin
  Invalidate;
end;

function TCoolThumbTab.SubRect: TRect;
const
  RectOffset = 8;
begin
  Result := Rect(Width div RectOffset, Height div RectOffset, Width - Width div RectOffset, Height - Height div RectOffset);
end;

procedure TCoolThumbTab.AfterMessage(Sender: TObject; var Msg: TMessage; var Handled: Boolean);
var
  R: TRect;
  P: TPoint;
begin
  if Enabled and not (csDesigning in ComponentState) then
    case Msg.Msg of
      WM_NCHITTEST:
        with TWMNCHitTest(Msg) do
        begin
          P := Point(XPos, YPos);
          P := ScreenToClient(P);
          R := SubRect;

          case FThumbPosition of
            tpRightBottom:
              if PtInRect(R, P) then
                Result := HTBOTTOMRIGHT;
            tpLeftBottom:
              if PtInRect(R, P) then
                Result := HTBOTTOMLEFT;
            tpRightTop:
              if PtInRect(R, P) then
                Result := HTTOPRIGHT;
            tpLeftTop:
              if PtInRect(R, P) then
                Result := HTTOPLEFT;
          end;
        end;
    end;
end;

procedure TCoolThumbTab.Paint;
const
  Mode: LongInt = 0;
var
  R: TRect;
  MyRgn: HRGN;
  Points: array[0..2] of TPoint;
begin
  inherited Paint;
  with Canvas, ClientRect do
  begin
    case FThumbPosition of
      tpRightBottom:
        begin
          Pen.Color := clBtnHighlight;
          MoveTo(Left, Succ(Bottom));
          LineTo(Succ(Right), Top);

          Pen.Color := clBtnShadow;
          MoveTo(Left, Bottom);
          LineTo(Right, Top);

          R := SubRect;
          InflateRect(R, -2, -2);
          Points[0] := Point(R.Left, R.Top);
          Points[1] := Point(R.Left, R.Bottom);
          Points[2] := Point(R.Right, R.Top);

          Mode := BF_TOPLEFT;
        end;

      tpRightTop:
        begin
          Pen.Color := clBtnHighlight;
          MoveTo(Left, Top);
          LineTo(Right, Bottom);

          Pen.Color := clBtnShadow;
          MoveTo(Succ(Left), Top);
          LineTo(Right, Pred(Bottom));

          R := SubRect;
          InflateRect(R, -2, -2);
          Points[0] := Point(R.Left, R.Top);
          Points[1] := Point(R.Right, R.Bottom);
          Points[2] := Point(R.Left, R.Bottom);

          Mode := BF_BOTTOMLEFT;
        end;

      tpLeftTop:
        begin
          Pen.Color := clBtnHighlight;
          MoveTo(Left, Pred(Bottom));
          LineTo(Pred(Right), Top);

          Pen.Color := clBtnShadow;
          MoveTo(Left, Pred(Pred(Bottom)));
          LineTo(Pred(Pred(Right)), Top);

          R := SubRect;
          InflateRect(R, -2, -2);
          Points[0] := Point(R.Left, R.Bottom);
          Points[1] := Point(R.Right, R.Top);
          Points[2] := Point(R.Right, R.Bottom);

          Mode := BF_BOTTOMRIGHT;
        end;

      tpLeftBottom:
        begin
          Pen.Color := clBtnHighlight;
          MoveTo(Left, Succ(Top));
          LineTo(Pred(Right), Bottom);

          Pen.Color := clBtnShadow;
          MoveTo(Left, Succ(Succ(Top)));
          LineTo(Pred(Pred(Right)), Bottom);

          R := SubRect;
          InflateRect(R, -2, -2);
          Points[0] := Point(R.Left, R.Top);
          Points[1] := Point(R.Right, R.Bottom);
          Points[2] := Point(R.Right, R.Top);

          Mode := BF_TOPRIGHT;
        end;
    end;

    R := SubRect;
    Brush.Style := bsClear;
    DrawEdge(Handle, R, EDGE_ETCHED, Mode);

    MyRgn := CreatePolygonRgn(Points, 3, WINDING);
    try
      OffsetRgn(MyRgn, Self.Left, Self.Top);
      SelectClipRgn(Handle, MyRgn);
      try
        if not FTransparent then
          if not CTLDrawWallpaper(Handle, R, FStretched, SRCCOPY) then
          begin
            Brush.Style := bsSolid;
            Brush.Color := Color;
            FillRect(R);
          end;
      finally
        SelectClipRgn(Handle, 0);
      end;
    finally
      DeleteObject(MyRgn);
    end;
  end;
end;

procedure TCoolThumbTab.Loaded;
begin
  inherited Loaded;
  // For a while... Gotta be fixed later.
  FWindowHook.WinControl := TWinControl(Owner);
  FWindowHook.Active := True;
end;

procedure TCoolThumbTab.WndProc(var Message: TMessage);
begin
  inherited WndProc(Message);
end;

procedure TCoolThumbTab.SetParent(AParent: TWinControl);
begin
  inherited SetParent(AParent);
end;

{TCoolBevel}
constructor TCoolBevel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;
  FTransparent := True;
  FColor := clBtnFace;
  FFlat := False;
  FidWallpaper := -1;
  FStretched := False;
end;

destructor TCoolBevel.Destroy;
begin
  if Assigned(FWallpaper) then FWallPaper.Free;
  FCoolImagesChangeLink.Free;
  inherited Destroy;
end;

procedure TCoolBevel.SetColor(Value: TColor);
begin
  if FColor <> Value then
  begin
    FColor := Value;
    Invalidate;
  end;
end;

procedure TCoolBevel.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  Invalidate;
end;

procedure TCoolBevel.SetFlat(Value: Boolean);
begin
  if FFlat <> Value then
  begin
    FFlat := Value;
    Invalidate;
  end;
end;

procedure TCoolBevel.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolBevel.SetStretched(Value: Boolean);
begin
  if FStretched <> Value then
  begin
    FStretched := Value;
    Invalidate;
  end;
end;

function TCoolBevel.IsWallpaperAssigned: Boolean;
begin
  Result := (Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty) or
            (Assigned(FWallpaper) and not FWallpaper.Empty);
end;

function TCoolBevel.CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaper(DC, FWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

procedure TCoolBevel.CoolImagesChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolBevel.SetTransparent(Value: Boolean);
begin
  if FTransparent <> Value then
  begin
    FTransparent := Value;
    Invalidate;
  end;
end;

function TCoolBevel.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolBevel.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  FWallPaper.Assign(Value);
  Invalidate;
end;

procedure TCoolBevel.WallpaperChanged(Sender: TObject);
begin
  Invalidate;
  Perform(CM_COLORCHANGED, 0, 0);
end;

procedure TCoolBevel.Paint;
begin
  if not FTransparent then
    if IsWallpaperAssigned then
      CTLDrawWallpaper(Canvas.Handle, ClientRect, FStretched, SRCCOPY) else
        begin
          Canvas.Brush.Color := FColor;
          Canvas.FillRect(ClientRect);
        end;

  if not FFlat then
    inherited Paint;
end;

procedure TCoolBevel.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FCoolImages)  and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

procedure TCoolBevel.CMMouseEnter(var Message: TMessage);
begin
  inherited;
  if Assigned(FOnMouseEnter) then
    FOnMouseEnter(Self);
end;

procedure TCoolBevel.CMMouseLeave(var Message: TMessage);
begin
  inherited;
  if Assigned(FOnMouseLeave) then
    FOnMouseLeave(Self);
end;

{TCustomCoolCheckRadioGroup}
constructor TCustomCoolCheckRadioGroup.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := [csSetCaption, csDoubleClicks];
  FCheckRadioType := crRadioBox;
  FFlat := False;
  FButtons := TList.Create;
  FItems := TStringList.Create;
  TStringList(FItems).OnChange := ItemsChange;
  FItemIndex := -1;
  FColumns := 1;
end;

destructor TCustomCoolCheckRadioGroup.Destroy;
begin
  SetButtonCount(0);
  TStringList(FItems).OnChange := nil;
  FItems.Free;
  FButtons.Free;
  if Assigned(FGlyphNormal) then FGlyphNormal.Free;
  if Assigned(FGlyphMarked) then FGlyphMarked.Free;
  inherited Destroy;
end;

procedure TCustomCoolCheckRadioGroup.ArrangeButtons;
var
  ButtonsPerCol, ButtonWidth, ButtonHeight, TopMargin, I: Integer;
  DC: HDC;
  SaveFont: HFont;
  Metrics: TTextMetric;
  DeferHandle: THandle;
  ALeft: Integer;
begin
  if (FButtons.Count <> 0) and not FReading then
  begin
    DC := GetDC(0);
    SaveFont := SelectObject(DC, Font.Handle);
    GetTextMetrics(DC, Metrics);
    SelectObject(DC, SaveFont);
    ReleaseDC(0, DC);
    ButtonsPerCol := (FButtons.Count + FColumns - 1) div FColumns;
    ButtonWidth := (Width - 10) div FColumns;
    I := Height - Metrics.tmHeight - 5;
    ButtonHeight := I div ButtonsPerCol;
    TopMargin := Metrics.tmHeight + 1 + (I mod ButtonsPerCol) div 2;
    DeferHandle := BeginDeferWindowPos(FButtons.Count);
    try
      for I := 0 to FButtons.Count - 1 do
        with TCoolCheckRadioBox(FButtons[I]) do
        begin
          {$IFDEF DELPHI4_OR_ABOVE}
          BiDiMode := Self.BiDiMode;
          {$ENDIF}
          ALeft := (I div ButtonsPerCol) * ButtonWidth + 8;
          {$IFDEF DELPHI4_OR_ABOVE}
          if UseRightToLeftAlignment then
            ALeft := Self.ClientWidth - ALeft - ButtonWidth;
          {$ENDIF}
          DeferHandle := DeferWindowPos(DeferHandle, Handle, 0,
            ALeft,
            (I mod ButtonsPerCol) * ButtonHeight + TopMargin,
            ButtonWidth, ButtonHeight,
            SWP_NOZORDER or SWP_NOACTIVATE);
          Visible := True;
        end;
    finally
      EndDeferWindowPos(DeferHandle);
    end;
  end;
end;

procedure TCustomCoolCheckRadioGroup.ButtonClick(Sender: TObject);
begin
  if not FUpdating then
  begin
    FItemIndex := FButtons.IndexOf(Sender);
    {$IFNDEF VER90}
    Changed;
    {$ELSE}
    Perform(CM_CHANGED, 0, 0);
    {$ENDIF}
    Click;
  end;
end;

procedure TCustomCoolCheckRadioGroup.ItemsChange(Sender: TObject);
begin
  if not FReading then
  begin
    if FItemIndex >= FItems.Count then FItemIndex := FItems.Count - 1;
    UpdateButtons;
  end;
end;

procedure TCustomCoolCheckRadioGroup.ReadState(Reader: TReader);
begin
  FReading := True;
  inherited ReadState(Reader);
  FReading := False;
  UpdateButtons;
end;

procedure TCustomCoolCheckRadioGroup.Loaded;
begin
  inherited Loaded;
  {$IFNDEF VER90}
  Changed;
  {$ENDIF}
  if FItemIndex >= 0 then
    TCoolCheckRadioBox(FButtons[FItemIndex]).TabStop := True;
end;

procedure TCustomCoolCheckRadioGroup.SetButtonCount(Value: Integer);
var
  CheckRadioBox: TCoolCheckRadioBox;
begin
  while FButtons.Count < Value do
  begin
    CheckRadioBox := TCoolCheckRadioBox.Create(Self);
    CheckRadioBox.CheckRadioType := FCheckRadioType;
    CheckRadioBox.Transparent := True;
    CheckRadioBox.SimpleView := FSimpleView;
    CheckRadioBox.ShadowSize := FShadowSize;
    CheckRadioBox.ShadowColor := FShadowColor;
    CheckRadioBox.ShadowPos := FShadowPos;

    CheckRadioBox.Enabled := Enabled;
    CheckRadioBox.OnClick := ButtonClick;
    CheckRadioBox.Parent := Self;

    CheckRadioBox.OwnerDraw := (Assigned(FGlyphNormal) and not FGlyphNormal.Empty) or (Assigned(FGlyphMarked) and not FGlyphMarked.Empty);
    CheckRadioBox.GlyphNormal := FGlyphNormal;
    CheckRadioBox.GlyphMarked := FGlyphMarked;
    CheckRadioBox.Flat := FFlat;

    FButtons.Add(CheckRadioBox);
  end;

  while FButtons.Count > Value do
  begin
    TCoolCheckRadioBox(FButtons.Last).Free;
    FButtons.Remove(TCoolCheckRadioBox(FButtons.Last));
  end;
end;

procedure TCustomCoolCheckRadioGroup.SetColumns(Value: Integer);
begin
  if Value < 1 then Value := 1;
  if Value > 16 then Value := 16;
  if FColumns <> Value then
  begin
    FColumns := Value;
    ArrangeButtons;
    Invalidate;
  end;
end;

procedure TCustomCoolCheckRadioGroup.SetItemIndex(Value: Integer);
begin
  if FReading then FItemIndex := Value else
  begin
    if Value < -1 then Value := -1;
    if Value >= FButtons.Count then Value := FButtons.Count - 1;
    if FItemIndex <> Value then
    begin
      if FItemIndex >= 0 then
        TCoolCheckRadioBox(FButtons[FItemIndex]).Checked := False;

      FItemIndex := Value;

      if FItemIndex >= 0 then
      begin
        TCoolCheckRadioBox(FButtons[FItemIndex]).Checked := True;
        TCoolCheckRadioBox(FButtons[FItemIndex]).TabStop := True;
      end;
    end;
  end;
end;

procedure TCustomCoolCheckRadioGroup.SetItems(Value: TStrings);
begin
  FItems.Assign(Value);
end;

procedure TCustomCoolCheckRadioGroup.SetCheckRadioType(Value: TCheckRadioType);
var
  I: Integer;
begin
  if FCheckRadioType <> Value then
  begin
    FCheckRadioType := Value;
    for I := 0 to FButtons.Count - 1 do
      TCoolCheckRadioBox(FButtons[I]).CheckRadioType := CheckRadioType;
  end;
end;

procedure TCustomCoolCheckRadioGroup.SetFlat(Value: Boolean);
var
  I: Integer;
begin
  if FFlat <> Value then
  begin
    FFlat := Value;
    for I := 0 to FButtons.Count - 1 do
      TCoolCheckRadioBox(FButtons[I]).Flat := FFlat;
  end;
end;

procedure TCustomCoolCheckRadioGroup.SetGlyphNormal(Value: TBitmap);
begin
  if FGlyphNormal = nil then FGlyphNormal := TBitmap.Create;
  FGlyphNormal.Assign(Value);
  {$IFNDEF VER90}
  Changed;
  {$ELSE}
  Perform(CM_CHANGED, 0, 0);
  {$ENDIF}
end;

function TCustomCoolCheckRadioGroup.GetGlyphNormal: TBitmap;
begin
  if FGlyphNormal = nil then FGlyphNormal := TBitmap.Create;
  Result := FGlyphNormal;
end;

procedure TCustomCoolCheckRadioGroup.SetGlyphMarked(Value: TBitmap);
begin
  if FGlyphMarked = nil then FGlyphMarked := TBitmap.Create;
  FGlyphMarked.Assign(Value);
  {$IFNDEF VER90}
  Changed;
  {$ELSE}
  Perform(CM_CHANGED, 0, 0);
  {$ENDIF}
end;

function TCustomCoolCheckRadioGroup.GetGlyphMarked: TBitmap;
begin
  if FGlyphMarked = nil then FGlyphMarked := TBitmap.Create;
  Result := FGlyphMarked;
end;

procedure TCustomCoolCheckRadioGroup.UpdateButtons;
var
  I: Integer;
begin
  SetButtonCount(FItems.Count);
  for I := 0 to FButtons.Count - 1 do
    TCoolCheckRadioBox(FButtons[I]).Caption := FItems[I];

  if FItemIndex >= 0 then
  begin
    FUpdating := True;
    TCoolCheckRadioBox(FButtons[FItemIndex]).Checked := True;
    FUpdating := False;
  end;

  ArrangeButtons;
  Invalidate;
end;

procedure TCustomCoolCheckRadioGroup.CMEnabledChanged(var Message: TMessage);
var
  I: Integer;
begin
  inherited;
  for I := 0 to FButtons.Count - 1 do
    TCoolCheckRadioBox(FButtons[I]).Enabled := Enabled;
end;

procedure TCustomCoolCheckRadioGroup.CMFontChanged(var Message: TMessage);
begin
  inherited;
  ArrangeButtons;
end;

procedure TCustomCoolCheckRadioGroup.WMSize(var Message: TWMSize);
begin
  inherited;
  ArrangeButtons;
end;

procedure TCustomCoolCheckRadioGroup.CMChanged(var Message: TMessage);
var
  I: Integer;
begin
  inherited;
  for I := 0 to FButtons.Count - 1 do
  begin
    TCoolCheckRadioBox(FButtons[I]).SimpleView := SimpleView;
    TCoolCheckRadioBox(FButtons[I]).ShadowSize := ShadowSize;
    TCoolCheckRadioBox(FButtons[I]).ShadowColor := ShadowColor;
    TCoolCheckRadioBox(FButtons[I]).ShadowPos := ShadowPos;
    TCoolCheckRadioBox(FButtons[I]).OwnerDraw := (Assigned(FGlyphNormal) and not FGlyphNormal.Empty) or (Assigned(FGlyphMarked) and not FGlyphMarked.Empty);
    TCoolCheckRadioBox(FButtons[I]).GlyphNormal := FGlyphNormal;
    TCoolCheckRadioBox(FButtons[I]).GlyphMarked := FGlyphMarked;
  end;
end;

{TCustomPopupButton}
constructor TCustomPopupButton.Create(AOwner: TComponent);
begin
  FGlyph := TGlyph.Create;
  TGlyph(FGlyph).OnChange := GlyphChanged;

  inherited Create(AOwner);
  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;

  SetBounds(Left, Top, 119, 19);
  FButtonStateEx := bseNoneBoth;

  Handle := AllocateHWnd(WndProc);

  FLayout := blGlyphLeft;
  FSpacing := 4;
  FMargin := -1;

  FShadowColor := clBtnHighlight;
  FShadowSize := 1;
  FShadowPos := spLeftTop;
  FSimpleView := False;

  FFlat := False;
  FTransparent := False;
  FidWallpaper := -1;
  FBtnAddSize := 16;

  FStretched := False;
end;

destructor TCustomPopupButton.Destroy;
begin
  if Assigned(FWallpaper) then FWallPaper.Free;
  FCoolImagesChangeLink.Free;
  DeallocateHWnd(Handle);
  inherited Destroy;
  TGlyph(FGlyph).Free;
end;

procedure TCustomPopupButton.SetGlyph(Value: TBitmap);
begin
  TGlyph(FGlyph).Glyph := Value;
  Invalidate;
end;

function TCustomPopupButton.GetGlyph: TBitmap;
begin
  Result := TGlyph(FGlyph).Glyph;
end;

procedure TCustomPopupButton.GlyphChanged(Sender: TObject);
begin
  Invalidate;
end;

procedure TCustomPopupButton.SetLayout(Value: TButtonLayout);
begin
  if FLayout <> Value then
  begin
    FLayout := Value;
    Invalidate;
  end;
end;

function TCustomPopupButton.GetNumGlyphs: TNumGlyphs;
begin
  Result := TGlyph(FGlyph).NumGlyphs;
end;

procedure TCustomPopupButton.SetNumGlyphs(Value: TNumGlyphs);
begin
  if Value < 0 then Value := 1 else
      if Value > 2 then Value := 2;

  if Value <> TGlyph(FGlyph).NumGlyphs then
  begin
    TGlyph(FGlyph).NumGlyphs := Value;
    Invalidate;
  end;
end;

procedure TCustomPopupButton.SetSpacing(Value: Integer);
begin
  if FSpacing <> Value then
  begin
    FSpacing := Value;
    Invalidate;
  end;
end;

procedure TCustomPopupButton.SetMargin(Value: Integer);
begin
  if (Value <> FMargin) and (Value >= - 1) then
  begin
    FMargin := Value;
    Invalidate;
  end;
end;

procedure TCustomPopupButton.SetShadowColor(Value: TColor);
begin
  if FShadowColor <> Value then
  begin
    FShadowColor := Value;
    FSimpleView := False;
    Invalidate;
  end;
end;

procedure TCustomPopupButton.SetShadowSize(Value: Byte);
begin
  if FShadowSize <> Value then
  begin
    FShadowSize := Value;
    FSimpleView := False;
    Invalidate;
  end;
end;

procedure TCustomPopupButton.SetShadowPos(Value: TShadowPosition);
begin
  if FShadowPos <> Value then
  begin
    FShadowPos := Value;
    FSimpleView := False;
    Invalidate;
  end;
end;

procedure TCustomPopupButton.SetSimpleView(Value: Boolean);
begin
  if FSimpleView <> Value then
  begin
    FSimpleView := Value;
    Invalidate;
  end;
end;

procedure TCustomPopupButton.SetTransparent(Value: Boolean);
begin
  if FTransparent <> Value then
  begin
    FTransparent := Value;
    Invalidate;
  end;
end;

procedure TCustomPopupButton.SetBtnAddSize(Value: Integer);
begin
  if FBtnAddSize <> Value then
  begin
    FBtnAddSize := Value;
    Invalidate;
  end;
end;

procedure TCustomPopupButton.SetFlat(Value: Boolean);
begin
  if FFlat <> Value then
  begin
    FFlat := Value;
    Invalidate;
  end;
end;

procedure TCustomPopupButton.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  FWallPaper.Assign(Value);
  Invalidate;
end;

function TCustomPopupButton.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCustomPopupButton.SetStretched(Value: Boolean);
begin
  if FStretched <> Value then
  begin
    FStretched := Value;
    Invalidate;
  end;
end;

procedure TCustomPopupButton.WallpaperChanged(Sender: TObject);
begin
  Invalidate;
  Perform(CM_COLORCHANGED, 0, 0);
end;

function TCustomPopupButton.CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaper(DC, FWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

function TCustomPopupButton.IsWallpaperAssigned: Boolean;
begin
  Result := (Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty) or
            (Assigned(FWallpaper) and not FWallpaper.Empty);
end;

procedure TCustomPopupButton.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCustomPopupButton.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  Invalidate;
end;

procedure TCustomPopupButton.CoolImagesChange(Sender: TObject);
begin
  Invalidate;
end;

type
  TMenuItemEx = class(TMenuItem);

procedure TCustomPopupButton.WndProc(var Message: TMessage);
begin
  inherited WndProc(Message);
end;

procedure TCustomPopupButton.Click;
begin
end;

procedure TCustomPopupButton.ClickAdd;
begin
end;

procedure TCustomPopupButton.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  inherited MouseDown(Button, Shift, X, Y);

  if Button = mbLeft then
    if X <= ClientWidth - FBtnAddSize then
    begin
      FButtonStateEx := bseDownBoth;

      Invalidate;
      if Assigned(OnClick) then OnClick(Self);
    end else
    begin
      if FButtonStateEx <> bseDownAdd then
        FButtonStateEx := bseDownAdd else
          FButtonStateEx := bseUpBoth;

     Invalidate;
     if FButtonStateEx = bseDownAdd then ClickAdd;
    end;
end;

procedure TCustomPopupButton.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  inherited MouseUp(Button, Shift, X, Y);

  if Button = mbLeft then
  begin
    if X <= ClientWidth - FBtnAddSize then
      FButtonStateEx := bseUpBoth;

    Invalidate;
  end;
end;

procedure TCustomPopupButton.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FCoolImages)  and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

procedure TCustomPopupButton.Paint;
var
  R: TRect;
  B: TBitmap;
  X, Y, StartPos: Integer;
begin
  with Canvas do
  begin
    Font := Self.Font;

    if not FTransparent then
        if IsWallpaperAssigned then
          CTLDrawWallpaper(Handle, ClientRect, FStretched, SRCCOPY) else
          begin
            Brush.Color := Self.Color;
            FillRect(ClientRect);
          end;

    B := TBitmap.Create;
    try
      B.Handle := LoadBitmap(HInstance, 'BTN_DOWN');

      StartPos := ClientWidth - FBtnAddSize;
      X := StartPos + (FBtnAddSize - B.Width) div 2;
      Y := (Height - B.Height) div 2;

      if (FButtonStateEx = bseDownBoth) or (FButtonStateEx = bseDownAdd) then
      begin
        Inc(X);
        Inc(Y);
      end;

      {$IFNDEF VER90}
      B.Transparent := True;
      Draw(X, Y, B);
      {$ELSE}
      TransparentStretchBltEx(Handle, B.Canvas.Handle, Rect(X, Y, X + B.Width, Y + B.Height), Rect(0, 0, B.Width, B.Height), B.TransparentColor);
      {$ENDIF}
    finally
      B.Free;
    end;

    R := Rect(0, 0, ClientWidth - FBtnAddSize, ClientHeight);

    if FButtonStateEx = bseDownBoth then
      OffsetRect(R, 1, 1);

    TGlyph(FGlyph).DrawFast(Canvas, R, Point(0, 0), Caption, FLayout, FMargin,
      FSpacing, Enabled, True, clNone, FSimpleView, {$IFDEF BCB}{$IFDEF VER100}SPToInt({$ENDIF}{$ENDIF} FShadowPos {$IFDEF BCB}{$IFDEF VER100}){$ENDIF}{$ENDIF}, FShadowColor,
        FShadowSize, {$IFDEF DELPHI4_OR_ABOVE} DrawTextBiDiModeFlags(0) {$ELSE} 0 {$ENDIF});

    if FButtonStateEx <> bseNoneBoth then
    begin
      if FButtonStateEx = bseUpBoth then
      begin
        R := Rect(0, 0, ClientWidth - FBtnAddSize, ClientHeight);
        DrawEdge(Handle, R, BDR_RAISEDINNER, BF_RECT or BF_ADJUST);
        R := Rect(ClientWidth - FBtnAddSize, 0, ClientWidth, ClientHeight);
        DrawEdge(Handle, R, BDR_RAISEDINNER, BF_RECT or BF_ADJUST);
      end else
      begin
        if FButtonStateEx = bseDownBoth then
        begin
          R := Rect(0, 0, ClientWidth - FBtnAddSize, ClientHeight);
          DrawEdge(Handle, R, BDR_SUNKENOUTER, BF_RECT or BF_ADJUST);
          R := Rect(ClientWidth - FBtnAddSize, 0, ClientWidth, ClientHeight);
          DrawEdge(Handle, R, BDR_SUNKENOUTER, BF_RECT or BF_ADJUST);
        end else
        if FButtonStateEx = bseDownAdd then
        begin
          R := Rect(0, 0, ClientWidth - FBtnAddSize, ClientHeight);
          DrawEdge(Handle, R, BDR_RAISEDINNER, BF_RECT or BF_ADJUST);
          R := Rect(ClientWidth - FBtnAddSize, 0, ClientWidth, ClientHeight);
          DrawEdge(Handle, R, BDR_SUNKENOUTER, BF_RECT or BF_ADJUST);
        end;
      end;
    end else
    if (csDesigning in ComponentState) or not FFlat then
    begin
      R := Rect(0, 0, ClientWidth - FBtnAddSize, ClientHeight);
      DrawEdge(Handle, R, BDR_RAISEDINNER, BF_RECT or BF_ADJUST);
      R := Rect(ClientWidth - FBtnAddSize, 0, ClientWidth, ClientHeight);
      DrawEdge(Handle, R, BDR_RAISEDINNER, BF_RECT or BF_ADJUST);
    end;
  end;
  inherited Paint;
end;

procedure TCustomPopupButton.CMMouseEnter(var Message: TMessage);
begin
  inherited;
  FButtonStateEx := bseUpBoth;
  if FFlat then
    Invalidate;
end;

procedure TCustomPopupButton.CMMouseLeave(var Message: TMessage);
begin
  inherited;
  FButtonStateEx := bseNoneBoth;
  if FFlat then
    Invalidate;
end;

procedure TCustomPopupButton.CMHitTest(var Message: TCMHitTest);
begin
  inherited;
end;

procedure TCustomPopupButton.CMTextChanged(var Message: TMessage);
begin
  inherited;
  Invalidate;
end;

{TCoolPopupButton}
procedure TCoolPopupButton.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FDownMenu) and (AComponent = FDownMenu) then
    FDownMenu := nil;
end;

{$IFDEF DELPHI4_OR_ABOVE}
procedure TCoolPopupButton.WndProc(var Message: TMessage);
var
  DC: HDC;
  P: TPoint;
  R: TRect;
  Canv: TCanvas;
  SaveFont: HFONT;
  Item: Integer;
  MenuItem: TMenuItem;
  FindKind: TFindItemKind;
  ContextID: Integer;

  function GetMenuFont: HFONT;
  var
    NonClientMetrics: TNonClientMetrics;
  begin
    NonClientMetrics.cbSize := sizeof(NonClientMetrics);
    if SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @NonClientMetrics, 0) then
      Result := CreateFontIndirect(NonClientMetrics.lfMenuFont)
    else
      Result := GetStockObject(SYSTEM_FONT);
  end;

begin
  if Assigned(FDownMenu) then
  try
    case Message.Msg of
      WM_COMMAND:
          if FDownMenu.DispatchCommand(Message.wParam) then Exit;
      WM_INITMENUPOPUP:
          with TWMInitMenuPopup(Message) do
            if FDownMenu.DispatchPopup(MenuPopup) then Exit;
      WM_MENUSELECT:
        with TWMMenuSelect(Message) do
        begin
          FindKind := fkCommand;
          if MenuFlag and MF_POPUP <> 0 then FindKind := fkHandle;

          if FindKind = fkHandle then
          begin
            if Menu <> 0 then
              Item := GetSubMenu(Menu, IDItem) else
              Item := -1;
          end
          else
            Item := IDItem;
          MenuItem := FDownMenu.FindItem(Item, FindKind);
          if MenuItem <> nil then
          begin
            Application.Hint := GetLongHint(MenuItem.Hint);
            Exit;
          end;

          Application.Hint := '';
        end;
      WM_HELP:
        with PHelpInfo(Message.LParam)^ do
        begin
          if hItemHandle = FDownMenu.Handle then
            MenuItem := FDownMenu.Items
          else
            MenuItem := FDownMenu.FindItem(hItemHandle, fkHandle);
          if MenuItem <> nil then
          begin
            ContextID := FDownMenu.GetHelpContext(iCtrlID, True);
            if ContextID = 0 then
              ContextID := FDownMenu.GetHelpContext(hItemHandle, False);
            if Screen.ActiveForm = nil then Exit;
            if (ContextID = 0) then
              ContextID := Screen.ActiveForm.HelpContext;
            if (biHelp in Screen.ActiveForm.BorderIcons) then
              Application.HelpCommand(HELP_CONTEXTPOPUP, ContextID)
            else
              Application.HelpContext(ContextID);
            Exit;
          end;
        end;
      WM_DRAWITEM:
        with PDrawItemStruct(Message.LParam)^ do
        begin
          MenuItem := FDownMenu.FindItem(itemID, fkCommand);
          if MenuItem <> nil then
          begin
            Canv := TControlCanvas.Create;
            with Canv do
            try
              SaveFont := SelectObject(hDC, GetStockObject(SYSTEM_FONT));
              try
                Handle := hDC;
                Font.Handle := GetMenuFont;
                if itemState and ODS_SELECTED <> 0 then
                begin
                  Brush.Color := clHighlight;
                  Font.Color := clHighlightText
                end
                else
                begin
                  Brush.Color := clMenu;
                  Font.Color := clMenuText;
                end;
                TMenuItemEx(MenuItem).DrawItem(Canv, rcItem, itemState and ODS_SELECTED <> 0);
              finally
                Handle := 0;
                if SaveFont <> 0 then SelectObject(hDC, SaveFont);
              end;
            finally
              Canv.Free;
            end;
            Exit;
          end;
        end;
      WM_MEASUREITEM:
        with PMeasureItemStruct(Message.LParam)^ do
        begin
          MenuItem := FDownMenu.FindItem(itemID, fkCommand);
          if MenuItem <> nil then
          begin
            DC := GetWindowDC(Handle);
            try
              Canv := TControlCanvas.Create;
              with Canv do
              try
                SaveFont := SelectObject(DC, GetStockObject(SYSTEM_FONT));
                try
                  Handle := DC;
                  Font.Handle := GetMenuFont;
                  TMenuItemEx(MenuItem).MeasureItem(Canv, Integer(itemWidth),
                    Integer(itemHeight));
                finally
                  Handle := 0;
                  if SaveFont <> 0 then SelectObject(DC, SaveFont);
                end;
              finally
                Canv.Free;
              end;
            finally
              ReleaseDC(Handle, DC);
            end;
            Exit;
          end;
        end;
      WM_MENUCHAR:
          with FDownMenu do
            if (Handle = HMENU(Message.LParam)) or (FindItem(Message.LParam, fkHandle) <> nil) then
            begin
              ProcessMenuChar(TWMMenuChar(Message));
              Exit;
            end;
      WM_EXITMENULOOP:
          begin
            GetCursorPos(P);
            P := Parent.ScreenToClient(P);
            R := Rect(Left, Top, Left + Width, Top + Height);

            if PtInRect(R, P) then
              if Hi(GetAsyncKeyState(VK_LBUTTON)) = 0 then
                FButtonStateEx := bseUpBoth else else
                  FButtonStateEx := bseNoneBoth;

            Invalidate;
          end;
    end;

  except
    Application.HandleException(Self);
  end;
  inherited WndProc(Message);
end;
{$ELSE}
procedure TCoolPopupButton.WndProc(var Message: TMessage);
var
  P: TPoint;
  R: TRect;
  MenuItem: TMenuItem;
  FindKind: TFindItemKind;
begin
  try
    case Message.Msg of
      WM_COMMAND:
        if FDownMenu.DispatchCommand(Message.wParam) then Exit;
      WM_MENUSELECT:
        with TWMMenuSelect(Message) do
        begin
          FindKind := fkCommand;
          if MenuFlag and MF_POPUP <> 0 then FindKind := fkHandle;

          MenuItem := FDownMenu.FindItem(IDItem, FindKind);
          if MenuItem <> nil then
          begin
            FMenuHelp := MenuItem.HelpContext;
            Application.Hint := MenuItem.Hint;
            Exit;
          end;

          FMenuHelp := 0;
          Application.Hint := '';
        end;
      WM_ENTERIDLE:
        if (TWMEnterIdle(Message).Source = MSGF_MENU) and
          (GetKeyState(VK_F1) < 0) and (FMenuHelp <> 0) then
        begin
          Application.HelpContext(FMenuHelp);
          FMenuHelp := 0;
          Exit;
        end;
      WM_EXITMENULOOP:
          begin
            GetCursorPos(P);
            P := Parent.ScreenToClient(P);
            R := Rect(Left, Top, Left + Width, Top + Height);

            if PtInRect(R, P) then
              if Hi(GetAsyncKeyState(VK_LBUTTON)) = 0 then
                FButtonStateEx := bseUpBoth else else
                  FButtonStateEx := bseNoneBoth;

            Invalidate;
          end;
    end;
  except
    Application.HandleException(Self);
  end;
  inherited WndProc(Message);
end;
{$ENDIF}

procedure TCoolPopupButton.Click;
begin
  inherited Click;
end;

procedure TCoolPopupButton.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  inherited MouseDown(Button, Shift, X, Y);
end;

procedure TCoolPopupButton.ClickAdd;
const
  Flags: array[Boolean, TPopupAlignment] of Word =
    ((TPM_LEFTALIGN, TPM_RIGHTALIGN, TPM_CENTERALIGN),
     (TPM_RIGHTALIGN, TPM_LEFTALIGN, TPM_CENTERALIGN));
  {$IFDEF DELPHI4_OR_ABOVE}
  Buttons: array[TTrackButton] of Word = (TPM_RIGHTBUTTON, TPM_LEFTBUTTON);
  {$ENDIF}
var
  P: TPoint;
begin
  P := Parent.ClientToScreen(Point(Left, Top + Height));

  if Assigned(FDownMenu) then
    TrackPopupMenu(FDownMenu.Handle, Flags[{$IFDEF DELPHI4_OR_ABOVE}UseRightToLeftAlignment,{$ELSE}False,{$ENDIF} FDownMenu.Alignment] {$IFDEF DELPHI4_OR_ABOVE} or Buttons[FDownMenu.TrackButton] {$ENDIF}, P.X, P.Y, 0, Handle, nil);
end;

{TCoolListBoxEx}
procedure TCoolListBoxEx.WMMouseActivate(var Message: TWMMouseActivate);
begin
  if Message.HitTestCode = HTVSCROLL then
  begin
    Message.Result := MA_NOACTIVATE;
    CanClose := False;
  end else
  begin
    Message.Result := MA_NOACTIVATEANDEAT;
    CanClose := True;
  end;
end;

procedure TCoolListBoxEx.WMLButtonUp(var Message: TWMLButtonUp);
begin
  inherited;
end;

procedure TCoolListBoxEx.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  inherited MouseDown(Button, Shift, X, Y);
end;

procedure TCoolListBoxEx.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  inherited MouseUp(Button, Shift, X, Y);
  if ItemIndex <> -1 then Click;
end;

procedure TCoolListBoxEx.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited KeyDown(Key, Shift);
end;

procedure TCoolListBoxEx.KeyUp(var Key: Word; Shift: TShiftState);
begin
  inherited KeyUp(Key, Shift);
  if ItemIndex <> -1 then Click;
end;

procedure TCoolListBoxEx.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do
  begin
    WndParent := Application.Handle;
    Style := WS_POPUP or WS_CLIPSIBLINGS or WS_CLIPCHILDREN or WS_BORDER or WS_VSCROLL;
  end;
end;

procedure TCoolListBoxEx.Click;
begin
  inherited Click;
end;

{TCoolPopupBox}
constructor TCoolPopupBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  FListBox := TCoolListBoxEx.Create(Self);
  FListBox.IntegralHeight := True;
  FListBox.HotTray := True;
  FListBox.OnClick := Change;

  SetBounds(Left, Top,  150,  Height);

  if not (csDesigning in ComponentState) then
  begin
    FPrevMessage := Application.OnMessage;
    Application.OnMessage := AppMessage;
  end;
end;

destructor TCoolPopupBox.Destroy;
begin
  if not (csDesigning in ComponentState) then
    Application.OnMessage := FPrevMessage;

  FListBox.Free;
  inherited Destroy;
end;

function TCoolPopupBox.GetItems: TStrings;
begin
  Result := FListBox.Items;
end;

procedure TCoolPopupBox.SetItems(Value: TStrings);
begin
  FListBox.Items.Assign(Value);
end;

function TCoolPopupBox.GetItemIndex: Integer;
begin
  Result := FListBox.ItemIndex;
end;

procedure TCoolPopupBox.SetItemIndex(Value: Integer);
begin
  FListBox.ItemIndex := Value;
end;

procedure TCoolPopupBox.Change;
begin
  if Assigned(FOnChange) then
    FOnChange(Self);
end;

procedure TCoolPopupBox.AppMessage(var Msg: TMsg; var Handled: Boolean);
var
  P: TPoint;
  R: TRect;
begin
  if IsWindowVisible(FListBox.Handle) and IsCloseMsg(Msg) and
    not FMouseAction and ((Msg.hwnd <> FListBox.Handle) or FListBox.CanClose) then
  if IsWindowVisible(FListBox.Handle) and IsCloseMsg(Msg) and not FMouseAction then
  begin
    ShowWindow(FListBox.Handle, SW_HIDE);

    GetCursorPos(P);
    P := Parent.ScreenToClient(P);
    R := Rect(Left, Top, Left + Width, Top + Height);

    if PtInRect(R, P) then
      if Hi(GetAsyncKeyState(VK_LBUTTON)) = 0 then
        ButtonStateEx := bseUpBoth else else
          ButtonStateEx := bseNoneBoth;

    Invalidate;
  end;

  if ((Msg.Message = WM_LBUTTONUP) or (Msg.Message = WM_LBUTTONDOWN)) and IsWindowVisible(FListBox.Handle) then
    FListBox.Perform(Msg.Message, Msg.wParam, Msg.lParam);

  if ((Msg.Message = WM_KEYDOWN) or (Msg.Message = WM_KEYUP)) and IsWindowVisible(FListBox.Handle) then
  begin
    if Msg.wParam in [VK_UP, VK_DOWN, VK_PRIOR, VK_NEXT] then
      FListBox.Perform(Msg.Message, Msg.wParam, Msg.lParam);

    if (Msg.Message = WM_KEYDOWN) and (Msg.wParam in [VK_ESCAPE, VK_RETURN]) then
    begin
      ShowWindow(FListBox.Handle, SW_HIDE);

      GetCursorPos(P);
      P := Parent.ScreenToClient(P);
      R := Rect(Left, Top, Left + Width, Top + Height);

      if PtInRect(R, P) then
        if Hi(GetAsyncKeyState(VK_LBUTTON)) = 0 then
          ButtonStateEx := bseUpBoth else else
            ButtonStateEx := bseNoneBoth;

      Invalidate;
    end;
    Handled := True;
  end;

  if Assigned(FPrevMessage) then
    FPrevMessage(Msg, Handled);
end;

function TCoolPopupBox.IsCloseMsg(var Msg: TMsg): Boolean;
begin
  with Msg do
    Result := ((Message = CM_ACTIVATE) or (Message = CM_DEACTIVATE) or
               (Message = WM_SYSKEYDOWN) or (Message = CM_APPKEYDOWN) or
               (Message = CM_APPSYSCOMMAND) or (Message = WM_COMMAND) or
               (Message > WM_MOUSEMOVE) and (Message <= WM_MOUSELAST) or
              ((Message > WM_NCMOUSEMOVE) and (Message <= WM_NCMBUTTONDBLCLK)));
end;

procedure TCoolPopupBox.Click;
begin
  inherited Click;
end;

procedure TCoolPopupBox.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  inherited MouseDown(Button, Shift, X, Y);
  FMouseAction := True;
end;

procedure TCoolPopupBox.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  inherited MouseUp(Button, Shift, X, Y);
  FMouseAction := False;
end;

procedure TCoolPopupBox.ClickAdd;
var
  P: TPoint;
begin
  FListBox.Font.Assign(Font);
  P := Parent.ClientToScreen(Point(Left, Top + Height));
  SetWindowPos(FListBox.Handle, HWND_TOP, P.X, P.Y, Width, 100, SWP_SHOWWINDOW or SWP_NOACTIVATE);
end;

procedure TCoolPopupBox.CMEnabledChanged(var Message: TMessage);
begin
  inherited;
  FListBox.Enabled := Enabled;
end;

procedure TCoolPopupBox.CMFontChanged(var Message: TMessage);
begin
  inherited;
  FListBox.Font := Font;
end;

procedure TCoolPopupBox.CMColorChanged(var Message: TMessage);
begin
  inherited;
end;

procedure TCoolPopupBox.CMMouseEnter(var Message: TMessage);
begin
  if not IsWindowVisible(FListBox.Handle) then
    inherited;
end;

procedure TCoolPopupBox.CMMouseLeave(var Message: TMessage);
begin
  if not IsWindowVisible(FListBox.Handle) then
    inherited;
end;

{TCoolPopupButton2}
constructor TCoolPopupButton2.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  SetBounds(Left, Top, 119, Height);
end;

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

{$IFDEF DELPHI4_OR_ABOVE}
procedure TCoolPopupButton2.WndProc(var Message: TMessage);
var
  DC: HDC;
  Canv: TCanvas;
  SaveFont: HFONT;
  Item: Integer;
  MenuItem: TMenuItem;
  FindKind: TFindItemKind;
  ContextID: Integer;

  function GetMenuFont: HFONT;
  var
    NonClientMetrics: TNonClientMetrics;
  begin
    NonClientMetrics.cbSize := sizeof(NonClientMetrics);
    if SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @NonClientMetrics, 0) then
      Result := CreateFontIndirect(NonClientMetrics.lfMenuFont)
    else
      Result := GetStockObject(SYSTEM_FONT);
  end;

begin
  if Assigned(FDownMenu) then
  try
    case Message.Msg of
      WM_COMMAND:
          if FDownMenu.DispatchCommand(Message.wParam) then Exit;
      WM_INITMENUPOPUP:
          with TWMInitMenuPopup(Message) do
            if FDownMenu.DispatchPopup(MenuPopup) then Exit;
      WM_MENUSELECT:
        with TWMMenuSelect(Message) do
        begin
          FindKind := fkCommand;
          if MenuFlag and MF_POPUP <> 0 then FindKind := fkHandle;

          if FindKind = fkHandle then
          begin
            if Menu <> 0 then
              Item := GetSubMenu(Menu, IDItem) else
              Item := -1;
          end
          else
            Item := IDItem;
          MenuItem := FDownMenu.FindItem(Item, FindKind);
          if MenuItem <> nil then
          begin
            Application.Hint := GetLongHint(MenuItem.Hint);
            Exit;
          end;

          Application.Hint := '';
        end;
      WM_HELP:
        with PHelpInfo(Message.LParam)^ do
        begin
          if hItemHandle = FDownMenu.Handle then
            MenuItem := FDownMenu.Items
          else
            MenuItem := FDownMenu.FindItem(hItemHandle, fkHandle);
          if MenuItem <> nil then
          begin
            ContextID := FDownMenu.GetHelpContext(iCtrlID, True);
            if ContextID = 0 then
              ContextID := FDownMenu.GetHelpContext(hItemHandle, False);
            if Screen.ActiveForm = nil then Exit;
            if (ContextID = 0) then
              ContextID := Screen.ActiveForm.HelpContext;
            if (biHelp in Screen.ActiveForm.BorderIcons) then
              Application.HelpCommand(HELP_CONTEXTPOPUP, ContextID)
            else
              Application.HelpContext(ContextID);
            Exit;
          end;
        end;
      WM_DRAWITEM:
        with PDrawItemStruct(Message.LParam)^ do
        begin
          MenuItem := FDownMenu.FindItem(itemID, fkCommand);
          if MenuItem <> nil then
          begin
            Canv := TControlCanvas.Create;
            with Canv do
            try
              SaveFont := SelectObject(hDC, GetStockObject(SYSTEM_FONT));
              try
                Handle := hDC;
                Font.Handle := GetMenuFont;
                if itemState and ODS_SELECTED <> 0 then
                begin
                  Brush.Color := clHighlight;
                  Font.Color := clHighlightText
                end
                else
                begin
                  Brush.Color := clMenu;
                  Font.Color := clMenuText;
                end;
                TMenuItemEx(MenuItem).DrawItem(Canv, rcItem, itemState and ODS_SELECTED <> 0);
              finally
                Handle := 0;
                if SaveFont <> 0 then SelectObject(hDC, SaveFont);
              end;
            finally
              Canv.Free;
            end;
            Exit;
          end;
        end;
      WM_MEASUREITEM:
        with PMeasureItemStruct(Message.LParam)^ do
        begin
          MenuItem := FDownMenu.FindItem(itemID, fkCommand);
          if MenuItem <> nil then
          begin
            DC := GetWindowDC(Handle);
            try
              Canv := TControlCanvas.Create;
              with Canv do
              try
                SaveFont := SelectObject(DC, GetStockObject(SYSTEM_FONT));
                try
                  Handle := DC;
                  Font.Handle := GetMenuFont;
                  TMenuItemEx(MenuItem).MeasureItem(Canv, Integer(itemWidth),
                    Integer(itemHeight));
                finally
                  Handle := 0;
                  if SaveFont <> 0 then SelectObject(DC, SaveFont);
                end;
              finally
                Canv.Free;
              end;
            finally
              ReleaseDC(Handle, DC);
            end;
            Exit;
          end;
        end;
      WM_MENUCHAR:
          with FDownMenu do
            if (Handle = HMENU(Message.LParam)) or (FindItem(Message.LParam, fkHandle) <> nil) then
            begin
              ProcessMenuChar(TWMMenuChar(Message));
              Exit;
            end;
      WM_EXITMENULOOP:
          begin
            ForcedFlat := False;
            Invalidate;
          end;
    end;

  except
    Application.HandleException(Self);
  end;
  inherited WndProc(Message);
end;
{$ELSE}
procedure TCoolPopupButton2.WndProc(var Message: TMessage);
var
  MenuItem: TMenuItem;
  FindKind: TFindItemKind;
begin
  try
    case Message.Msg of
      WM_COMMAND:
        if FDownMenu.DispatchCommand(Message.wParam) then Exit;
      WM_MENUSELECT:
        with TWMMenuSelect(Message) do
        begin
          FindKind := fkCommand;
          if MenuFlag and MF_POPUP <> 0 then FindKind := fkHandle;

          MenuItem := FDownMenu.FindItem(IDItem, FindKind);
          if MenuItem <> nil then
          begin
            FMenuHelp := MenuItem.HelpContext;
            Application.Hint := MenuItem.Hint;
            Exit;
          end;

          FMenuHelp := 0;
          Application.Hint := '';
        end;
      WM_ENTERIDLE:
        if (TWMEnterIdle(Message).Source = MSGF_MENU) and
          (GetKeyState(VK_F1) < 0) and (FMenuHelp <> 0) then
        begin
          Application.HelpContext(FMenuHelp);
          FMenuHelp := 0;
          Exit;
        end;
      WM_EXITMENULOOP:
          begin
            ForcedFlat := False;
            Invalidate;
          end;
    end;
  except
    Application.HandleException(Self);
  end;
  inherited WndProc(Message);
end;
{$ENDIF}

procedure TCoolPopupButton2.Click;
const
  Flags: array[Boolean, TPopupAlignment] of Word =
    ((TPM_LEFTALIGN, TPM_RIGHTALIGN, TPM_CENTERALIGN),
     (TPM_RIGHTALIGN, TPM_LEFTALIGN, TPM_CENTERALIGN));
  {$IFDEF DELPHI4_OR_ABOVE}
  Buttons: array[TTrackButton] of Word = (TPM_RIGHTBUTTON, TPM_LEFTBUTTON);
  {$ENDIF}
var
  P: TPoint;
begin
  inherited Click;

  P := Parent.ClientToScreen(Point(Left, Top + Height));

  if Assigned(FDownMenu) then
  begin
    ForcedFlat := True;
    Invalidate;
    TrackPopupMenu(FDownMenu.Handle, Flags[{$IFDEF DELPHI4_OR_ABOVE}UseRightToLeftAlignment,{$ELSE}False,{$ENDIF} FDownMenu.Alignment] {$IFDEF DELPHI4_OR_ABOVE} or Buttons[FDownMenu.TrackButton] {$ENDIF}, P.X, P.Y, 0, Handle, nil);
  end;
end;

{TCoolPopupBox2}
{TCoolPopupBox2}
constructor TCoolPopupBox2.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  FListBox := TCoolListBoxEx.Create(Self);
  FListBox.IntegralHeight := True;
  FListBox.HotTray := True;
  FListBox.OnClick := Change;

  SetBounds(Left, Top, 119, Height);

  if not (csDesigning in ComponentState) then
  begin
    FPrevMessage := Application.OnMessage;
    Application.OnMessage := AppMessage;
  end;
end;

destructor TCoolPopupBox2.Destroy;
begin
  if not (csDesigning in ComponentState) then
    Application.OnMessage := FPrevMessage;

  FListBox.Free;
  inherited Destroy;
end;

function TCoolPopupBox2.GetItemIndex: Integer;
begin
  Result := FListBox.ItemIndex;
end;

procedure TCoolPopupBox2.SetItemIndex(Value: Integer);
begin
  FListBox.ItemIndex := Value;
end;

function TCoolPopupBox2.GetItems: TStrings;
begin
  Result := FListBox.Items;
end;

procedure TCoolPopupBox2.SetItems(Value: TStrings);
begin
  FListBox.Items.Assign(Value);
end;

procedure TCoolPopupBox2.Loaded;
begin
  inherited Loaded;
end;

procedure TCoolPopupBox2.Change;
begin
  if Assigned(FOnChange) then
    FOnChange(Self);
end;

procedure TCoolPopupBox2.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
  if IsWindowVisible(FListBox.Handle) and IsCloseMsg(Msg) and ((Msg.hwnd <> FListBox.Handle) or FListBox.CanClose) then
  begin
    ShowWindow(FListBox.Handle, SW_HIDE);
    ForcedFlat := False;
    Invalidate;
  end;

  if ((Msg.Message = WM_LBUTTONUP) or (Msg.Message = WM_LBUTTONDOWN)) and IsWindowVisible(FListBox.Handle) then
    FListBox.Perform(Msg.Message, Msg.wParam, Msg.lParam);

  if ((Msg.Message = WM_KEYDOWN) or (Msg.Message = WM_KEYUP)) and IsWindowVisible(FListBox.Handle) then
  begin
    if Msg.wParam in [VK_UP, VK_DOWN, VK_PRIOR, VK_NEXT] then
      FListBox.Perform(Msg.Message, Msg.wParam, Msg.lParam);

    if (Msg.Message = WM_KEYDOWN) and (Msg.wParam in [VK_ESCAPE, VK_RETURN]) then
    begin
      ShowWindow(FListBox.Handle, SW_HIDE);
      ForcedFlat := False;
      Invalidate;
    end;
    Handled := True;
  end;

  if Assigned(FPrevMessage) then
    FPrevMessage(Msg, Handled);
end;

function TCoolPopupBox2.IsCloseMsg(var Msg: TMsg): Boolean;
begin
  with Msg do
    Result := ((Message = CM_ACTIVATE) or (Message = CM_DEACTIVATE) or
               (Message = WM_SYSKEYDOWN) or (Message = CM_APPKEYDOWN) or
               (Message = CM_APPSYSCOMMAND) or (Message = WM_COMMAND) or
               (Message > WM_MOUSEMOVE) and (Message <= WM_MOUSELAST) or
              ((Message > WM_NCMOUSEMOVE) and (Message <= WM_NCMBUTTONDBLCLK)));
end;

procedure TCoolPopupBox2.Click;
var
  P: TPoint;
begin
  inherited Click;

  FListBox.Font.Assign(Font);
  P := Parent.ClientToScreen(Point(Left, Top + Height));
  SetWindowPos(FListBox.Handle, HWND_TOPMOST, P.X, P.Y, Width, 100, SWP_SHOWWINDOW or SWP_NOACTIVATE);

  ForcedFlat := True;
  Invalidate;
end;

{$IFNDEF VER90}
{TCoolSpeedButton}
constructor TCoolSpeedButton.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Layout := blGlyphTop;
  FDowned := False;
  FBkColor := clBtnShadow;
  Transparent := True;
  HasMouse := False;
  if not (csDesigning in ComponentState) then
    Flat := True;
end;

destructor TCoolSpeedButton.Destroy;
begin
  if Assigned(Parent) then
    SendMessage(Parent.Handle, CM_BUTTONDESTROYED, 0, LongInt(Self));

  inherited Destroy;
end;

{$IFNDEF DELPHI4_OR_ABOVE}
procedure TCoolSpeedButton.SetTransparent(Value: Boolean);
begin
  if Value <> FTransparent then
  begin
    FTransparent := Value;
    if Value then
      ControlStyle := ControlStyle - [csOpaque] else
      ControlStyle := ControlStyle + [csOpaque];
    Invalidate;
  end;
end;
{$ENDIF}

procedure TCoolSpeedButton.CMMouseEnter(var Message: TMessage);
begin
  inherited;
  HasMouse := True;
  SendMessage(Parent.Handle, CM_MOUSECAPTURECHANGE, Integer(HasMouse), Integer(Self));

  if Enabled then
  begin
    Transparent := False;
    Font.Color := clBlack;
  end;

  if Assigned(FOnMouseEnter) then
    FOnMouseEnter(Self);
end;

procedure TCoolSpeedButton.CMMouseLeave(var Message: TMessage);
begin
  inherited;
  HasMouse := False;
  SendMessage(Parent.Handle, CM_MOUSECAPTURECHANGE, Integer(HasMouse), Integer(Self));

  if Enabled then
  begin
    Transparent := True;
    Font.Color := TCoolButtonPanel(Parent).InactiveFontColor;
  end;

  if Assigned(FOnMouseLeave) then
    FOnMouseLeave(Self);
end;

procedure TCoolSpeedButton.MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer);
begin
  FDowned := True;
  inherited MouseDown(Button, Shift, X, Y);
end;

procedure TCoolSpeedButton.MouseUp(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer);
begin
  FDowned := False;
  inherited MouseUp(Button, Shift, X, Y);
  {$IFNDEF DELPHI4_OR_ABOVE}
  SendMessage(Parent.Handle, CM_BUTTONMOUSEUP, 0, 0);
  {$ENDIF}
end;

procedure TCoolSpeedButton.Paint;
{$IFNDEF DELPHI4_OR_ABOVE}
const
  DownStyles: array[Boolean] of Integer = (BDR_RAISEDINNER, BDR_SUNKENOUTER);
  FillStyles: array[Boolean] of Integer = (BF_MIDDLE, 0);
{$ENDIF}
var
  P: TPoint;
{$IFNDEF DELPHI4_OR_ABOVE}
  R: TRect;
{$ENDIF}
begin
  GetCursorPos(P);

  {$IFNDEF DELPHI4_OR_ABOVE}
  if (FindDragTarget(P, True) = Self) then
  begin
    R := ClientRect;
    DrawEdge(Canvas.Handle, R, DownStyles[FState in [bsDown, bsExclusive]],
             FillStyles[Transparent] or BF_RECT);
  end;
  {$ENDIF}

  inherited Paint;

  if FDowned and not (FindDragTarget(P, True) = Self) then
  begin
    FBkColor := SendMessage(Parent.Handle, CM_PARENTBACKCOLOR, 0, 0);
    Canvas.Pen.Color := FBkColor;
    Canvas.Rectangle(0, 0, Width, Height);
  end;
end;

procedure TCoolSpeedButton.ReadState(Reader: TReader);
begin
  inherited ReadState(Reader);
  //
  // If the button isnt selected.
  //
  Font.Color := TCoolButtonPanel(Reader.Parent).InactiveFontColor;

  TCoolButtonPanel(Reader.Parent).FButtons.Add(Self);
end;

{TCoolPanel}
constructor TCoolPanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;
  FidWallpaper := -1;
  FTransparent := False;
  FStretched := False;
  FInactiveFontColor := clWhite;
end;

destructor TCoolPanel.Destroy;
begin
  FCoolImagesChangeLink.Free;
  if Assigned(FWallPaper) then FWallPaper.Free;
  inherited Destroy;
end;

procedure TCoolPanel.CMParentColorChanged(var Message: TMessage);
begin
  inherited;
  if FTransparent then
    Invalidate;
end;

procedure TCoolPanel.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
  if FTransparent then
    PaintBackground(TrControl(Self, FTransparencyLevel), Message.DC, True) else
      if not CTLDrawWallpaper(Message.DC, ClientRect, FStretched, SRCCOPY) then
        inherited;
end;

procedure TCoolPanel.SetTransparencyLevel(Value: Byte);
begin
  if FTransparencyLevel <> Value then
  begin
    FTransparencyLevel := Value;
    Invalidate;
  end;
end;

procedure TCoolPanel.SetWallpaper(Value: TBitmap);
begin
  if FWallpaper <> Value then
  begin
    if FWallpaper = nil then FWallpaper := TBitmap.Create;

    FTransparent := False;
    FWallpaper.Assign(Value);
    Invalidate;
  end;
end;

function TCoolPanel.GetWallpaper: TBitmap;
begin
  if FWallpaper = nil then FWallpaper := TBitmap.Create;
  Result := FWallpaper;
  Result.OnChange := WallpaperChanged;
end;

procedure TCoolPanel.SetTransparent(Value: Boolean);
begin
  if FTransparent <> Value then
  begin
    FTransparent := Value;
    Repaint;
  end;
end;

procedure TCoolPanel.WallpaperChanged(Sender: TObject);
begin
  Invalidate;
  Perform(CM_COLORCHANGED, 0, 0);
end;

procedure TCoolPanel.SetidWallpaper(Value: Integer);
begin
  if FidWallpaper <> Value then
  begin
    FidWallpaper := Value;
    Invalidate;
  end;
end;

procedure TCoolPanel.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(CoolImages) then
    CoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

  if Assigned(CoolImages) then
    CoolImages.RegisterChanges(FCoolImagesChangeLink);

  Invalidate;
end;

procedure TCoolPanel.SetStretched(Value: Boolean);
begin
  if FStretched <> Value then
  begin
    FStretched := Value;
    Invalidate;
  end;
end;

procedure TCoolPanel.SetInactiveFontColor(Value: TColor);
begin
  if FInactiveFontColor <> Value then
  begin
    FInactiveFontColor := Value;
  end;
end;

function TCoolPanel.CTLDrawWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;
begin
  Result := False;
  if Assigned(FCoolImages) and (FidWallpaper >= 0) and (FidWallpaper <= Pred(FCoolImages.Images.Count)) and Assigned(FCoolImages.Images.Items[FidWallpaper].Bitmap) and not FCoolImages.Images.Items[FidWallpaper].Bitmap.Empty then
  begin
    DrawWallpaper(DC, FCoolImages.Images.Items[FidWallpaper].Bitmap, R, IsStretch, Mode);
    Result := True;
  end else
  if Assigned(FWallpaper) and not FWallpaper.Empty then
  begin
    DrawWallpaper(DC, FWallpaper, R, IsStretch, Mode);
    Result := True;
  end;
end;

procedure TCoolPanel.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FCoolImages) and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

procedure TCoolPanel.CoolImagesChange(Sender: TObject);
begin
  Invalidate;
end;

procedure TCoolPanel.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
  inherited MouseMove(Shift, X, Y);
end;

procedure TCoolPanel.Loaded;
begin
  inherited Loaded;
end;

procedure TCoolPanel.Paint;
const
  Alignments: array[TAlignment] of Longint = (DT_LEFT, DT_RIGHT, DT_CENTER);
var
  Rect: TRect;
  TopColor, BottomColor: TColor;
  FontHeight: Integer;
  Flags: Longint;

  procedure AdjustColors(Bevel: TPanelBevel);
  begin    
    if Bevel = bvLowered then
    begin
      TopColor := clBtnShadow;
      BottomColor := clBtnHighlight;
    end else
    begin
      TopColor := clBtnHighlight;        
      BottomColor := clBtnShadow;
    end;
  end;

begin
  Rect := GetClientRect;

  with Canvas do
  begin
    if FTransparent then
      PaintBackground(TrControl(Self, FTransparencyLevel), Handle, True) else
        if not CTLDrawWallpaper(Handle, Rect, FStretched, SRCCOPY) then
        begin
          Brush.Color := Color;
          FillRect(Rect);
          Brush.Style := bsClear;
        end;

    if BevelOuter <> bvNone then
    begin
      AdjustColors(BevelOuter);
      Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth);
    end;

    Frame3D(Self.Canvas, Rect, Self.Color, Self.Color, BorderWidth);
    if BevelInner <> bvNone then
    begin
      AdjustColors(BevelInner);
      Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth);
    end;

    Font := Self.Font;
    FontHeight := TextHeight('W');
    with Rect do
    begin
      Top := ((Bottom + Top) - FontHeight) div 2;
      Bottom := Top + FontHeight;
    end;
    Flags := DT_EXPANDTABS or DT_VCENTER or Alignments[Alignment];
    {$IFDEF DELPHI4_OR_ABOVE}
    Flags := DrawTextBiDiModeFlags(Flags);
    {$ENDIF}
    SetBkMode(Handle, Windows.TRANSPARENT);
    DrawText(Handle, PChar(Caption), -1, Rect, Flags);
  end;
end;

{TCoolButtonPanel}
constructor TCoolButtonPanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Width := 66;
  Color := clBtnShadow;
  BevelOuter := bvLowered;

  FButtonWidth := 64;
  FButtonHeight := 64;

  FButtons := TList.Create;
  FScrollUpBtn := TSpeedButton.Create(Self);
  FScrollDownBtn := TSpeedButton.Create(Self);

  with FScrollUpBtn do
  begin
    Glyph.Handle := LoadBitmap(HInstance, 'BTN_UP');
    OnClick := ScrollUp;
    {$IFDEF DELPHI4_OR_ABOVE}
    Transparent := False;
    Flat := True;
    {$ENDIF}
    Width := FButtonWidth;
    Height := 16;
    if not (csDesigning in ComponentState) then
      Parent := Self;
  end;

  with FScrollDownBtn do
  begin
    Glyph.Handle := LoadBitmap(HInstance, 'BTN_DOWN');
    OnClick := ScrollDown;
    {$IFDEF DELPHI4_OR_ABOVE}
    Transparent := False;
    Flat := True;
    {$ENDIF}
    Width := FButtonWidth;
    Height := 16;
    if not (csDesigning in ComponentState) then
      Parent := Self;
  end;
end;

destructor TCoolButtonPanel.Destroy;
begin
  FButtons.Free;
  FScrollUpBtn := nil;
  FScrollDownBtn := nil;
  inherited Destroy;
end;

procedure TCoolButtonPanel.CMButtonDestroyed(var Message: TMessage);
var
  I: Integer;
begin
  for I := Pred(ButtonsCount) downto 0 do
    if Buttons[I] = TCoolSpeedButton(Message.lParam) then
    begin
      FButtons.Remove(Buttons[I]);
      ReorderButtons;
      Break;
    end;
end;

procedure TCoolButtonPanel.CMButtonMouseUp(var Message: TMessage);
var
  I: Integer;
  P: TPoint;
begin
  GetCursorPos(P);
  for I := 0 to Pred(ButtonsCount) do
    if (FindDragTarget(P, True) = Buttons[I]) then
      Buttons[I].Perform(CM_MOUSEENTER, 0, 0);
end;

procedure TCoolButtonPanel.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
  inherited;
  FScrollUpBtn.BringToFront;
  FScrollDownBtn.BringToFront;
end;

procedure TCoolButtonPanel.CMMouseCaptureChange(var Message: TMessage);
var
  I: Integer;
begin
  if Boolean(Message.wParam) then
    for I := 0 to Pred(ButtonsCount) do
      if (Buttons[I].HasMouse) and (Buttons[I] <> TCoolSpeedButton(Message.lParam)) then
        Buttons[I].Perform(CM_MOUSELEAVE, 0, 0);
end;

procedure TCoolButtonPanel.SetButtonHeight(Value: Integer);
begin
  if Value <> FButtonHeight then
  begin
    FButtonHeight := Value;
    ReorderButtons;
  end;
end;

procedure TCoolButtonPanel.SetButtonWidth(Value: Integer);
begin
  if Value <> FButtonWidth then
  begin
    FButtonWidth := Value;
    Width := FButtonWidth + 2;
    ReorderButtons;
  end;
end;

function TCoolButtonPanel.CreateButton: TCoolSpeedButton;
begin
  Result := TCoolSpeedButton.Create(Owner);
  try
    Result.Width := FButtonWidth;
    Result.Height := FButtonHeight;
    Result.Visible := True;
    Result.Parent := Self;
    FButtons.Add(Result);
    ReorderButtons;
  except
    Result.Free;
  end;
end;

function TCoolButtonPanel.GetButton(Index: Integer): TCoolSpeedButton;
begin
  Result := TCoolSpeedButton(FButtons[Index]);
end;

function TCoolButtonPanel.GetButtonCount: Integer;
begin
  Result := FButtons.Count;
end;

procedure TCoolButtonPanel.ScrollUp(Sender: TObject);
var
  R: TRect;
begin
  R := ClientRect;
  InflateRectEx(R, 17, 0, -17, 0);
  ScrollByEx(0, FButtonHeight, R);

  if Assigned(FOnScrollUp) then
    FOnScrollUp(Self);
end;

procedure TCoolButtonPanel.ScrollDown(Sender: TObject);
var
  R: TRect;
begin
  R := ClientRect;
  InflateRectEx(R, 17, 0, -17, 0);
  ScrollByEx(0, -FButtonHeight, R);

  if Assigned(FOnScrollDown) then
    FOnScrollDown(Self);
end;

procedure TCoolButtonPanel.ReorderButtons;
var
  I: Integer;
begin
  for I := 0 to Pred(ButtonsCount) do
    with Buttons[I] do
    begin
      Height := FButtonHeight;
      Width := FButtonWidth;
      Top := I * FButtonHeight;
      Left := 1;
    end;

  with FScrollUpBtn do
  begin
    Width := FButtonWidth;
    Height := 16;
    Top := 0;
    Left := 1;
  end;

  with FScrollDownBtn do
  begin
    Width := FButtonWidth;
    Height := 16;
    Top := Self.Height - 16;
    Left := 1;
  end;
end;

procedure TCoolButtonPanel.ScrollByEx(DeltaX, DeltaY: Integer; R: TRect);
var
  IsVisible: Boolean;
  I: Integer;
  Control: TControl;
begin
  IsVisible := (Handle <> 0) and IsWindowVisible(Handle);
  if IsVisible then ScrollWindow(Handle, DeltaX, DeltaY, @R, nil);
  for I := 0 to ControlCount - 1 do
  begin
    Control := Controls[I];
    if (not (Control is TWinControl) or (TWinControl(Control).Handle = 0)) and not ((Control = FScrollUpBtn) or (Control = FScrollDownBtn)) then
    begin
      Control.Left := Control.Left + DeltaX;
      Control.Top := Control.Top + DeltaY;
    end else
      if not IsVisible then
        with TWinControl(Control) do
          SetWindowPos(Handle, 0, Left + DeltaX, Top + DeltaY,
            Width, Height, SWP_NOZORDER + SWP_NOACTIVATE);
  end;
  Realign;
end;

procedure TCoolButtonPanel.Paint;
var
  I: Integer;
  BtnUpVisible,
  BtnDownVisible: Boolean;

begin
  inherited Paint;

  BtnUpVisible := False;
  BtnDownVisible := False;

  for I := 0 to Pred(FButtons.Count) do
  begin
    if Buttons[I].Top < FScrollUpBtn.Top then
      BtnUpVisible := True;

    if Buttons[I].Top + FButtonHeight > FScrollDownBtn.Top + 16 then
      BtnDownVisible := True;
  end;

  FScrollUpBtn.Visible := BtnUpVisible;
  FScrollDownBtn.Visible := BtnDownVisible;
end;

procedure TCoolButtonPanel.Resize;
begin
  inherited Resize;
  if not (csDestroying in ComponentState) then
    ReorderButtons;
end;
{$ENDIF}

{$IFNDEF Registered}
initialization
  if not DelphiRunning and not DelphiRunningByExeName(Application.ExeName) then
    {$IFNDEF VER90}
    with TFormAbout.Create(Application) do
    try
      LabelVersion.Caption := 'Version 3.04h';
      LabelText.Caption := 'Please register CoolControls package. ' +
                           'Read help to find out how to register or ' +
                           'contact us at info@cooldev.com.';
      ShowModal;
    finally
      Free;
    end;
    {$ELSE}
    Application.MessageBox('I hope you like the way your controls look now' + #13 +
                           'Please register the CoolControls package' + #13 +
                           'Read help to learn how to register or either' + #13 +
                           'write at info@cooldev.com / visit www.cooldev.com',
                           'Information', MB_ICONINFORMATION);
    {$ENDIF}
finalization
  if not DelphiRunningByExeName(Application.ExeName) then
    {$IFNDEF VER90}
    with TFormAbout.Create(Application) do
    try
      LabelVersion.Caption := 'Version 3.04h';
      LabelText.Caption := 'Please register CoolControls package. ' +
                           'Read help to find out how to register or ' +
                           'contact us at info@cooldev.com.';

      Show;
      repeat
        Application.HandleMessage;
      until ModalResult <> 0;
      Hide;
    finally
      Free;
    end;
    {$ELSE}
    Application.MessageBox('I hope you like the way your controls look now' + #13 +
                           'Please register the CoolControls package' + #13 +
                           'Read help to learn how to register or either' + #13 +
                           'write at info@cooldev.com / visit www.cooldev.com',
                           'Information', MB_ICONINFORMATION);
    {$ENDIF}
{$ENDIF}
end.
