{

  Copyright (c) 1997-2003 by CoolDev.Com. Part of CoolControls package.

}

{$I versions.inc}
unit CoolCtrlsDB;

interface

uses Dialogs,
  Windows, Messages, Classes, Graphics, StdCtrls, Controls, Forms, DBCtrls,
  {$IFDEF ver90} DBTables, {$ENDIF} DB, SysUtils, CoolUtils, Grids, DBGrids,
  {$IFNDEF ver90} ToolWin, {$ENDIF} ExtCtrls, CoolCtrls {$IFDEF DELPHI6_OR_ABOVE} , Variants {$ENDIF};

type
  // TDBCoolCheckRadioBox is data aware version of the TCoolCheckRadioBox control;
  // it inherites all functionality of the latter and extends it with the data related
  // properties and methods.
  TDBCoolCheckRadioBox = class(TCoolCheckRadioBox)
  private
    FDataLink: TFieldDataLink;
    FValueCheck: string;
    FValueUncheck: string;
    procedure DataChange(Sender: TObject);
    function GetDataField: string;
    function GetDataSource: TDataSource;
    function GetField: TField;
    function GetFieldState: TCheckBoxState;
    function GetReadOnly: Boolean;
    procedure SetDataField(const Value: string);
    procedure SetDataSource(Value: TDataSource);
    procedure SetReadOnly(Value: Boolean);
    procedure SetValueCheck(const Value: string);
    procedure SetValueUncheck(const Value: string);
    procedure UpdateData(Sender: TObject);
    function ValueMatch(const ValueList, Value: string): Boolean;
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure CMExit(var Message: TCMExit); message CM_EXIT;
    procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK;
  protected
    function Toggle: Boolean; override;
    procedure KeyPress(var Key: Char); override;
    procedure Notification(AComponent: TComponent;
      Operation: TOperation); override;
    procedure WndProc(var Message: TMessage); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    {$IFDEF DELPHI4_OR_ABOVE}
    function ExecuteAction(Action: TBasicAction): Boolean; override;
    function UpdateAction(Action: TBasicAction): Boolean; override;
    function UseRightToLeftAlignment: Boolean; override;
    {$ENDIF}
    property Checked;
    property State;
    // Use the TField reference provided by the Field property when you want
    // to change the value of the data in the field programmatically.
    property Field: TField read GetField;
  published
    // Set DataField to the field name of the field component that the control represents.
    // Access by the control to the dataset in which the field is located is provided by a TDataSource component,
    // specified in the DataSource property.
    property DataField: string read GetDataField write SetDataField;
    // Specify the data source component through which the data from a dataset component is provided
    // to the control. To allow the control to represent the data for a field, both the DataSource and
    // the DataField properties must be set.
    property DataSource: TDataSource read GetDataSource write SetDataSource;
    // Use ReadOnly to specify whether the control allows the user to change the field value
    // by checking or unchecking the box. When ReadOnly is True, the control can only be used
    // to display the value of the field on the current record. When ReadOnly is False, the user
    // can use the control to change the field value.
    property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;

    // Use ValueChecked to specify the field value represented by the check box when it is checked. If the
    // value of the ValueChecked property is equal to the data in the field of the current record of the dataset,
    // the database check box appears checked. When the user checks the database check box, the field
    // value is set to ValueChecked.
    //
    // ValueChecked can represent more than one value in a semicolon-delimited
    // list of items. If any of the items matches the contents of the field of the current record in the dataset,
    // the check box appears checked.
    property ValueChecked: string read FValueCheck write SetValueCheck;
    // Use ValueUnchecked to specify the field value represented by the check box when it
    // is unchecked. If the value of the ValueUnchecked property is equal to the data in the field
    // of the current record of the dataset, the database check box appears unchecked. When the user
    // unchecks the database check box, the field value is set to ValueUnchecked.
    //
    // ValueUnchecked can represent more than one value in a semicolon-delimited list of items. If any
    // of the items matches the contents of the field of the current record in the dataset, the check box
    // appears unchecked.
    property ValueUnchecked: string read FValueUncheck write SetValueUncheck;
  end;

  // TDBCoolCheckRadioGroup is data aware version of the TCoolCheckRadioGroup control;
  // it inherites all functionality of the latter and extends it with the data related
  // properties and methods.
  TDBCoolCheckRadioGroup = class(TCustomCoolCheckRadioGroup)
  private
    FDataLink: TFieldDataLink;
    FValue: string;
    FValues: TStrings;
    FInSetValue: Boolean;
    FOnChange: TNotifyEvent;
    procedure DataChange(Sender: TObject);
    procedure UpdateData(Sender: TObject);
    function GetDataField: string;
    function GetDataSource: TDataSource;
    function GetField: TField;
    function GetReadOnly: Boolean;
    function GetButtonValue(Index: Integer): string;
    procedure SetDataField(const Value: string);
    procedure SetDataSource(Value: TDataSource);
    procedure SetReadOnly(Value: Boolean);
    procedure SetValue(const Value: string);
    procedure SetItems(Value: TStrings);
    procedure SetValues(Value: TStrings);
    procedure CMExit(var Message: TCMExit); message CM_EXIT;
  protected
    procedure Change; dynamic;
    procedure Click; override;
    procedure KeyPress(var Key: Char); override;
    procedure Notification(AComponent: TComponent;
      Operation: TOperation); override;
    property DataLink: TFieldDataLink read FDataLink;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    {$IFDEF DELPHI4_OR_ABOVE}
    function ExecuteAction(Action: TBasicAction): Boolean; override;
    function UpdateAction(Action: TBasicAction): Boolean; override;
    function UseRightToLeftAlignment: Boolean; override;
    {$ENDIF}
    // Use the TField reference provided by the Field property when you want
    // to change the value of the data in the field programmatically.
    property Field: TField read GetField;
    property ItemIndex;
    // Value holds the content of the linked field for the current record. If the user
    // selects a different radio button, the Value property changes.
    property Value: string read FValue write SetValue;
  published
    // Set DataField to the field name of the field component that the control represents.
    // Access by the control to the dataset in which the field is located is provided by a TDataSource component,
    // specified in the DataSource property.
    property DataField: string read GetDataField write SetDataField;
    // Specify the data source component through which the data from a dataset component is provided
    // to the control. To allow the control to represent the data for a field, both the DataSource and
    // the DataField properties must be set.
    property DataSource: TDataSource read GetDataSource write SetDataSource;
    // Items holds a TStrings object that lists the captions of the radio buttons in the group.
    property Items write SetItems;
    // Use ReadOnly to specify whether the control allows the user to change the field value
    // by checking or unchecking the box. When ReadOnly is True, the control can only be used
    // to display the value of the field on the current record. When ReadOnly is False, the user
    // can use the control to change the field value.
    property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
    // When the user selects a radio button, the “value” of that button is written to the linked field in the
    // database. By default, the value of a button is simply the caption that appears next to it on the screen, as
    // determined by the Items property.
    //
    // In some cases, you may want the values of the radio buttons to differ from their captions. For example, if you
    // use radio buttons to represent a database field whose content can be “Y” or “N”, you may want the buttons’ captions
    // to be “Yes” and “No”. In this case, you would enter “Yes” and “No” in the Items list, and enter “Y” and “N” in the Values list.
    //
    // You can edit the Values list in the Object Inspector, just as you would the Items list. To keep the buttons’ captions as
    // their values, leave the Values property empty.
    property Values: TStrings read FValues write SetValues;
    // Event occurs when another radiobox becomes chosen.
    property OnChange: TNotifyEvent read FOnChange write FOnChange;

    property Columns;
    property GlyphMarked;
    property GlyphNormal;
    property Flat;
  end;

  {$IFDEF VER90}
  TSysLocale = packed record
    DefaultLCID: LCID;
    PriLangID: LANGID;
    SubLangID: LANGID;
    FarEast: Boolean;
  end;
  {$ENDIF}

  // TDBCoolListBox is data aware version of the TCoolListBox control;
  // it inherites all functionality of the latter and extends it with the data related
  // properties and methods.
  TDBCoolListBox = class(TCoolListBox)
  private
    FDataLink: TFieldDataLink;
    procedure DataChange(Sender: TObject);
    procedure UpdateData(Sender: TObject);
    function GetDataField: string;
    function GetDataSource: TDataSource;
    function GetField: TField;
    function GetReadOnly: Boolean;
    procedure SetDataField(const Value: string);
    procedure SetDataSource(Value: TDataSource);
    procedure SetReadOnly(Value: Boolean);
    procedure SetItems(Value: TStrings);
    procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
    procedure CMExit(var Message: TCMExit); message CM_EXIT;
  protected
    procedure Click; override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyPress(var Key: Char); override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure BuildItems;
    // Use the TField reference provided by the Field property when you want
    // to change the value of the data in the field programmatically.
    property Field: TField read GetField;
  published
    // Set DataField to the field name of the field component that the control represents.
    // Access by the control to the dataset in which the field is located is provided by a TDataSource component,
    // specified in the DataSource property.
    property DataField: string read GetDataField write SetDataField;
    // Specify the data source component through which the data from a dataset component is provided
    // to the control. To allow the control to represent the data for a field, both the DataSource and
    // the DataField properties must be set.
    property DataSource: TDataSource read GetDataSource write SetDataSource;
    // Use Items to specify the values the user can choose from. Because Items is an object of
    // type TStrings, you can add, delete, insert, and move items using the Add, Delete, Insert,
    // Exchange, and Move methods of the TStrings object.
    property Items write SetItems;
    // Use ReadOnly to specify whether the control allows the user to change the field value
    // by checking or unchecking the box. When ReadOnly is True, the control can only be used
    // to display the value of the field on the current record. When ReadOnly is False, the user
    // can use the control to change the field value.
    property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
  end;

  // TDBCoolComboBox is data aware version of the TCoolComboBox control;
  // it inherites all functionality of the latter and extends it with the data related
  // properties and methods.
  TDBCoolComboBox = class(TCoolComboBox)
  private
    FDataLink: TFieldDataLink;
    procedure DataChange(Sender: TObject);
    procedure EditingChange(Sender: TObject);
    function GetComboText: string;
    function GetDataField: string;
    function GetDataSource: TDataSource;
    function GetField: TField;
    function GetReadOnly: Boolean;
    procedure SetComboText(const Value: string);
    procedure SetDataField(const Value: string);
    procedure SetDataSource(Value: TDataSource);
    procedure SetEditReadOnly;
    procedure SetItems(Value: TStrings);
    procedure SetReadOnly(Value: Boolean);
    procedure UpdateData(Sender: TObject);
    procedure CMEnter(var Message: TCMEnter); message CM_ENTER;
    procedure CMExit(var Message: TCMExit); message CM_EXIT;
    procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK;
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  protected
    procedure Change; override;
    procedure Click; override;
    procedure ComboWndProc(var Message: TMessage; ComboWnd: HWnd;
      ComboProc: Pointer); override;
    procedure CreateWnd; override;
    procedure DropDown; override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyPress(var Key: Char); override;
    procedure Loaded; override;
    procedure Notification(AComponent: TComponent;
      Operation: TOperation); override;
    procedure SetStyle(Value: TComboboxStyle); override;
    procedure WndProc(var Message: TMessage); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure BuildItems;
    // Use the TField reference provided by the Field property when you want
    // to change the value of the data in the field programmatically.
    property Field: TField read GetField;
    property Text;
  published
    // Set DataField to the field name of the field component that the control represents.
    // Access by the control to the dataset in which the field is located is provided by a TDataSource component,
    // specified in the DataSource property.
    property DataField: string read GetDataField write SetDataField;
    // Specify the data source component through which the data from a dataset component is provided
    // to the control. To allow the control to represent the data for a field, both the DataSource and
    // the DataField properties must be set.
    property DataSource: TDataSource read GetDataSource write SetDataSource;
    // Use Items to specify the values the user can choose from. Because Items is an object of
    // type TStrings, you can add, delete, insert, and move items using the Add, Delete, Insert,
    // Exchange, and Move methods of the TStrings object.
    property Items write SetItems;
    // Use ReadOnly to specify whether the control allows the user to change the field value
    // by checking or unchecking the box. When ReadOnly is True, the control can only be used
    // to display the value of the field on the current record. When ReadOnly is False, the user
    // can use the control to change the field value.
    property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
  end;

  // TDBCoolEdit is data aware version of the TCoolEdit control;
  // it inherites all functionality of the latter and extends it with the data related
  // properties and methods.
  TDBCoolEdit = class(TCoolEdit)
  private
    FDataLink: TFieldDataLink;
    FFocused: Boolean;
    procedure DataChange(Sender: TObject);
    procedure EditingChange(Sender: TObject);
    procedure UpdateData(Sender: TObject);
    function GetDataField: string;
    function GetDataSource: TDataSource;
    function GetField: TField;
    function GetReadOnly: Boolean;
    procedure SetDataField(const Value: string);
    procedure SetDataSource(Value: TDataSource);
    procedure SetFocused(Value: Boolean);
    procedure SetReadOnly(Value: Boolean);
    procedure WMCut(var Message: TMessage); message WM_CUT;
    procedure WMPaste(var Message: TMessage); message WM_PASTE;
    procedure CMEnter(var Message: TCMEnter); message CM_ENTER;
    procedure CMExit(var Message: TCMExit); message CM_EXIT;
    procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK;
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  protected
    procedure Change; override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyPress(var Key: Char); override;
    procedure Loaded; override;
    procedure Notification(AComponent: TComponent;
      Operation: TOperation); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    // Use the TField reference provided by the Field property when you want
    // to change the value of the data in the field programmatically.
    property Field: TField read GetField;
  published
    // Set DataField to the field name of the field component that the control represents.
    // Access by the control to the dataset in which the field is located is provided by a TDataSource component,
    // specified in the DataSource property.
    property DataField: string read GetDataField write SetDataField;
    // Specify the data source component through which the data from a dataset component is provided
    // to the control. To allow the control to represent the data for a field, both the DataSource and
    // the DataField properties must be set.
    property DataSource: TDataSource read GetDataSource write SetDataSource;
    // Use ReadOnly to specify whether the control allows the user to change the field value
    // by checking or unchecking the box. When ReadOnly is True, the control can only be used
    // to display the value of the field on the current record. When ReadOnly is False, the user
    // can use the control to change the field value.
    property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
  end;

  // TDBCoolEditBtn is data aware version of the TCoolEditBtn control;
  // it inherites all functionality of the latter and extends it with the data related
  // properties and methods.
  TDBCoolEditBtn = class(TCoolEditBtn)
  private
    FDataLink: TFieldDataLink;
    FFocused: Boolean;
    procedure DataChange(Sender: TObject);
    procedure EditingChange(Sender: TObject);
    procedure UpdateData(Sender: TObject);
    function GetDataField: string;
    function GetDataSource: TDataSource;
    function GetField: TField;
    function GetReadOnly: Boolean;
    procedure SetDataField(const Value: string);
    procedure SetDataSource(Value: TDataSource);
    procedure SetFocused(Value: Boolean);
    procedure SetReadOnly(Value: Boolean);
    procedure WMCut(var Message: TMessage); message WM_CUT;
    procedure WMPaste(var Message: TMessage); message WM_PASTE;
    procedure CMEnter(var Message: TCMEnter); message CM_ENTER;
    procedure CMExit(var Message: TCMExit); message CM_EXIT;
    procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK;
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  protected
    procedure Change; override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyPress(var Key: Char); override;
    procedure Loaded; override;
    procedure Notification(AComponent: TComponent;
      Operation: TOperation); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    // Use the TField reference provided by the Field property when you want
    // to change the value of the data in the field programmatically.
    property Field: TField read GetField;
  published
    // Set DataField to the field name of the field component that the control represents.
    // Access by the control to the dataset in which the field is located is provided by a TDataSource component,
    // specified in the DataSource property.
    property DataField: string read GetDataField write SetDataField;
    // Specify the data source component through which the data from a dataset component is provided
    // to the control. To allow the control to represent the data for a field, both the DataSource and
    // the DataField properties must be set.
    property DataSource: TDataSource read GetDataSource write SetDataSource;
    // Use ReadOnly to specify whether the control allows the user to change the field value
    // by checking or unchecking the box. When ReadOnly is True, the control can only be used
    // to display the value of the field on the current record. When ReadOnly is False, the user
    // can use the control to change the field value.
    property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
  end;

  // TDBCoolMemo is data aware version of the TCoolMemo control;
  // it inherites all functionality of the latter and extends it with the data related
  // properties and methods.
  TDBCoolMemo = class(TCoolMemo)
  private
    FDataLink: TFieldDataLink;
    FFocused: Boolean;
    FMemoLoaded: Boolean;
    FAutoDisplay: Boolean;
    procedure DataChange(Sender: TObject);
    procedure EditingChange(Sender: TObject);
    procedure UpdateData(Sender: TObject);
    function GetDataField: string;
    function GetDataSource: TDataSource;
    function GetField: TField;
    function GetReadOnly: Boolean;
    procedure SetDataField(const Value: string);
    procedure SetDataSource(Value: TDataSource);
    procedure SetFocused(Value: Boolean);
    procedure SetReadOnly(Value: Boolean);
    procedure SetAutoDisplay(Value: Boolean);
    procedure WMCut(var Message: TMessage); message WM_CUT;
    procedure WMPaste(var Message: TMessage); message WM_PASTE;
    procedure CMEnter(var Message: TCMEnter); message CM_ENTER;
    procedure CMExit(var Message: TCMExit); message CM_EXIT;
    procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK;
    procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message WM_LBUTTONDBLCLK;
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
    procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
    procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
  protected
    procedure Change; override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyPress(var Key: Char); override;
    procedure Loaded; override;
    procedure Notification(AComponent: TComponent;
      Operation: TOperation); override;
    procedure WndProc(var Message: TMessage); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    // Use the TField reference provided by the Field property when you want
    // to change the value of the data in the field programmatically.
    property Field: TField read GetField;
    procedure LoadMemo;
    {$IFDEF DELPHI4_OR_ABOVE}
    function ExecuteAction(Action: TBasicAction): Boolean; override;
    function UpdateAction(Action: TBasicAction): Boolean; override;
    {$ENDIF}
  published
    property AutoDisplay: Boolean read FAutoDisplay write SetAutoDisplay default True;
    // Set DataField to the field name of the field component that the control represents.
    // Access by the control to the dataset in which the field is located is provided by a TDataSource component,
    // specified in the DataSource property.
    property DataField: string read GetDataField write SetDataField;
    // Specify the data source component through which the data from a dataset component is provided
    // to the control. To allow the control to represent the data for a field, both the DataSource and
    // the DataField properties must be set.
    property DataSource: TDataSource read GetDataSource write SetDataSource;
    // Use ReadOnly to specify whether the control allows the user to change the field value
    // by checking or unchecking the box. When ReadOnly is True, the control can only be used
    // to display the value of the field on the current record. When ReadOnly is False, the user
    // can use the control to change the field value.
    property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False;
  end;

  // TDBCoolText is data aware version of the TCoolText control;
  // it inherites all functionality of the latter and extends it with the data related
  // properties and methods.
  TDBCoolText = class(TCoolLabel)
  private
    FDataLink: TFieldDataLink;
    procedure DataChange(Sender: TObject);
    function GetDataField: string;
    function GetDataSource: TDataSource;
    function GetField: TField;
    function GetFieldText: string;
    procedure SetDataField(const Value: string);
    procedure SetDataSource(Value: TDataSource);
    procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK;
  protected
    function GetLabelText: string; override;
    procedure Loaded; override;
    procedure Notification(AComponent: TComponent;
      Operation: TOperation); override;
    procedure SetAutoSize(Value: Boolean); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    {$IFDEF DELPHI4_OR_ABOVE}
    function ExecuteAction(Action: TBasicAction): Boolean; override;
    function UpdateAction(Action: TBasicAction): Boolean; override;
    function UseRightToLeftAlignment: Boolean; override;
    {$ENDIF}
    // Use the TField reference provided by the Field property when you want
    // to change the value of the data in the field programmatically.
    property Field: TField read GetField;
  published
    property AutoSize default False;
    // Set DataField to the field name of the field component that the control represents.
    // Access by the control to the dataset in which the field is located is provided by a TDataSource component,
    // specified in the DataSource property.
    property DataField: string read GetDataField write SetDataField;
    // Specify the data source component through which the data from a dataset component is provided
    // to the control. To allow the control to represent the data for a field, both the DataSource and
    // the DataField properties must be set.
    property DataSource: TDataSource read GetDataSource write SetDataSource;
  end;

  // TDBCoolScrollingText is data aware version of the TCoolScrollingText control;
  // it inherites all functionality of the latter and extends it with the data related
  // properties and methods.
  TDBCoolScrollingText = class(TCoolScrollingText)
  private
    FDataLink: TFieldDataLink;
    procedure DataChange(Sender: TObject);
    function GetDataField: string;
    function GetDataSource: TDataSource;
    function GetField: TField;
    function GetFieldText: string;
    procedure SetDataField(const Value: string);
    procedure SetDataSource(Value: TDataSource);
    procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK;
  protected
    function GetStrings: TStrings; override;
    procedure Loaded; override;
    procedure Notification(AComponent: TComponent;
      Operation: TOperation); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    {$IFDEF DELPHI4_OR_ABOVE}
    function ExecuteAction(Action: TBasicAction): Boolean; override;
    function UpdateAction(Action: TBasicAction): Boolean; override;
    function UseRightToLeftAlignment: Boolean; override;
    {$ENDIF}
    // Use the TField reference provided by the Field property when you want
    // to change the value of the data in the field programmatically.
    property Field: TField read GetField;
  published
    // Set DataField to the field name of the field component that the control represents.
    // Access by the control to the dataset in which the field is located is provided by a TDataSource component,
    // specified in the DataSource property.
    property DataField: string read GetDataField write SetDataField;
    // Specify the data source component through which the data from a dataset component is provided
    // to the control. To allow the control to represent the data for a field, both the DataSource and
    // the DataField properties must be set.
    property DataSource: TDataSource read GetDataSource write SetDataSource;
  end;

  // TDBCoolGrid is data aware version of the TCoolGrid control;
  // it inherites all functionality of the latter and extends it with the data related
  // properties and methods.
  TDBCoolGrid = class(TDBGrid)
  private
    FAboutBox: TCCAboutBox;

    FWallpaper,
    FSelWallpaper,
    FCaptionWallpaper: TBitmap;

    FSelColor,
    FCaptionColor,
    FCaptionTextColor: TColor;

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

    FExOptions: TCoolOptions;
    FTransparencyLevel: Byte;

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

    procedure SetCaptionColor(Value: TColor);
    procedure SetCaptionTextColor(Value: TColor);

    procedure SetWallpaper(Value: TBitmap);
    function GetWallpaper: TBitmap;
    procedure SetSelWallpaper(Value: TBitmap);
    function GetSelWallpaper: TBitmap;
    procedure SetCaptionWallpaper(Value: TBitmap);
    function GetCaptionWallpaper: TBitmap;
    procedure WallpaperChanged(Sender: TObject);

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    procedure SetidSelWallpaper(Value: Integer);
    procedure SetidCaptionWallpaper(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 CTLDrawCaptionWallpaper(DC: HDC; R: TRect; IsStretch: Boolean; Mode: Integer): Boolean;

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

    procedure SetExOptions(Value: TCoolOptions);
    procedure SetTransparencyLevel(Value: Byte);

    function TrControl: TWinControl;

    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
    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 WMNCLButtonDblClk(var Message: TWMNCLButtonDblClk); message WM_NCLBUTTONDBLCLK;
    procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
    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;
  protected
    EditValue: string;
    procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure NCCtlChanged; virtual;
    procedure TopLeftChanged; override;
    procedure Scroll(Distance: Integer); override;
    procedure SetEditText(ACol, ARow: Longint; const Value: string); override;
    function GetEditText(ACol, ARow: Longint): string; override;
    function CreateEditor: TInplaceEdit; override;
    procedure CreateParams(var Params: TCreateParams); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure MakeTransparency;
    property Canvas;
    property SelectedRows;
  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;
    // 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];
    // 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;
    // 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;
    // 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 OnEndCellEditing: TEndCellEditingEvent read FOnEndCellEditing write FOnEndCellEditing;
    property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
    property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
    property OnPaint: TNotifyEvent read FOnPaint write FOnPaint;
    property Align;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Anchors;
    property BiDiMode;
    {$ENDIF}
    property BorderStyle;
    property Color;
    property Columns stored False;
    {$IFDEF DELPHI4_OR_ABOVE}
    property Constraints;
    {$ENDIF}
    property Ctl3D;
    // Specify the data source component through which the data from a dataset component is provided
    // to the control. To allow the control to represent the data for a field, both the DataSource and
    // the DataField properties must be set.
    property DataSource;
    property DefaultDrawing;
    property DragCursor;
    {$IFDEF DELPHI4_OR_ABOVE}
    property DragKind;
    {$ENDIF}
    property DragMode;
    property Enabled;
    property FixedColor;
    property Font;
    {$IFNDEF VER90}
    property ImeMode;
    property ImeName;
    {$ENDIF}
    // 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;
    {$IFDEF DELPHI4_OR_ABOVE}
    property ParentBiDiMode;
    {$ENDIF}
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    // Use ReadOnly to specify whether the control allows the user to change the field value
    // by checking or unchecking the box. When ReadOnly is True, the control can only be used
    // to display the value of the field on the current record. When ReadOnly is False, the user
    // can use the control to change the field value.
    property ReadOnly;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property TitleFont;
    property Visible;
    {$IFNDEF VER90}
    property OnCellClick;
    {$ENDIF}
    property OnColEnter;
    property OnColExit;
    property OnColumnMoved;
    property OnDrawDataCell;  { obsolete }
    property OnDrawColumnCell;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEditButtonClick;
    {$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;
    {$IFNDEF VER90}
    property OnTitleClick;
    {$ENDIF}
  end;

  {$IFDEF DELPHI4_OR_ABOVE}
  // TDBCoolLookupListBox is data aware version of the TCoolLookupListBox control;
  // it inherites all functionality of the latter and extends it with the data related
  // properties and methods.
  TDBCoolLookupListBox = class(TDBLookupListBox)
  private
    FAboutBox: TCCAboutBox;
    FOptions: TCoolOptions;
    FTransparencyLevel: Byte;

    FWallpaper: TBitmap;
    FSelWallpaper,
    FCaptionWallpaper: TBitmap;

    FBevelInner,
    FBevelOuter: TPanelBevel;

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

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

    FSelColor,
    FCaptionColor,
    FCaptionTextColor: TColor;
    FSelFont: TFont;

    FPopup: Boolean;

    FOnMouseEnter,
    FOnMouseLeave: TNotifyEvent;

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

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

    procedure SetSelWallpaper(Value: TBitmap);
    function GetSelWallpaper: TBitmap;
    procedure SetCaptionWallpaper(Value: TBitmap);
    function GetCaptionWallpaper: TBitmap;

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

    procedure SetCaptionColor(Value: TColor);
    procedure SetCaptionTextColor(Value: TColor);

    procedure SetSelFont(Value: TFont);

    procedure SelFontChange(Sender: TObject);
    procedure SetTransparencyLevel(Value: Byte);

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    procedure SetidSelWallpaper(Value: Integer);
    procedure SetidCaptionWallpaper(Value: Integer);
    function IsWallpaperAssigned: Boolean;
    function IsSelWallpaperAssigned: Boolean;
    procedure CoolImagesChange(Sender: TObject);

    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;

    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure WMEraseBkGnd(var Message: TWMEraseBkGnd); message WM_ERASEBKGND;
    procedure WMSetText(var Message: TMessage); message WM_SETTEXT;
    procedure WMNCPaint (var Message: TMessage); message WM_NCPAINT;
    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 CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure CMParentFontChanged(var Message: TMessage); message CM_PARENTFONTCHANGED;
  protected
    procedure NCCtlChanged; virtual;
    procedure Loaded; override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure Paint; override;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure SelectItemAt(X, Y: Integer);
  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 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;
    // 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 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;
    // 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;
    // 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 Caption;
  end;

  {TPopupDataList}
  TPopupDataList = class(TDBCoolLookupListBox)
  private
    procedure WMMouseActivate(var Message: TMessage); message WM_MOUSEACTIVATE;
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  // TDBCoolLookupComboBox is data aware version of the TCoolLookupComboBox control;
  // it inherites all functionality of the latter and extends it with the data related
  // properties and methods.
  TDBCoolLookupComboBox = class(TDBLookupControl)
  private
    FDataList: TPopupDataList;
    FButtonWidth: Integer;
    FText: string;
    FDropDownRows: Integer;
    FDropDownWidth: Integer;
    FDropDownAlign: TDropDownAlign;
    FListVisible: Boolean;
    FPressed: Boolean;
    FTracking: Boolean;
    FAlignment: TAlignment;
    FLookupMode: Boolean;
    FOnDropDown: TNotifyEvent;
    FOnCloseUp: TNotifyEvent;

    ///cool begin///

    FAboutBox: TCCAboutBox;
    FOptions: TCoolOptions;
    FTransparencyLevel: Byte;

    FWallpaper: TBitmap;
    FSelWallpaper: TBitmap;

    FBevelInner,
    FBevelOuter: TPanelBevel;

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

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

    FSelColor: TColor;
    FSelFont: TFont;

    FBorderStyle: TBorderStyle;

    FOnMouseEnter,
    FOnMouseLeave: TNotifyEvent;

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

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

    procedure SetSelWallpaper(Value: TBitmap);
    function GetSelWallpaper: TBitmap;

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

    procedure SetSelFont(Value: TFont);

    procedure SelFontChange(Sender: TObject);
    procedure SetTransparencyLevel(Value: Byte);

    procedure SetCoolImages(Value: TCoolImages);
    procedure SetidWallpaper(Value: Integer);
    procedure SetidSelWallpaper(Value: Integer);
    function IsWallpaperAssigned: Boolean;
    function IsSelWallpaperAssigned: Boolean;
    procedure CoolImagesChange(Sender: TObject);

    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;

    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
    procedure WMEraseBkGnd(var Message: TWMEraseBkGnd); message WM_ERASEBKGND;
    procedure WMSetText(var Message: TMessage); message WM_SETTEXT;
    procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
    procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure CMParentFontChanged(var Message: TMessage); message CM_PARENTFONTCHANGED;

    ///cool end///

    procedure ListMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure StopTracking;
    procedure TrackButton(X, Y: Integer);
    procedure CMDialogKey(var Message: TCMDialogKey); message CM_DIALOGKEY;
    procedure CMCancelMode(var Message: TCMCancelMode); message CM_CANCELMODE;
    procedure CMCtl3DChanged(var Message: TMessage); message CM_CTL3DCHANGED;
    procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
    procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK;
    procedure WMCancelMode(var Message: TMessage); message WM_CANCELMODE;
    procedure CMBiDiModeChanged(var Message: TMessage); message CM_BIDIMODECHANGED;
  protected
    procedure Loaded; override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;

    procedure CreateParams(var Params: TCreateParams); override;
    procedure Paint; override;
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyPress(var Key: Char); override;
    procedure KeyValueChanged; override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure UpdateListFields; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure CloseUp(Accept: Boolean); virtual;
    procedure DropDown; virtual;
    function ExecuteAction(Action: TBasicAction): Boolean; override;
    procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
    function UpdateAction(Action: TBasicAction): Boolean; override;
    function UseRightToLeftAlignment: Boolean; override;
    property KeyValue;
    property ListVisible: Boolean read FListVisible;
    property Text: string read FText;
  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;
    // 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;
    // 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 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;
    // 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;
    // 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 Anchors;
    property BiDiMode;
    property Color;
    property Constraints;
    property Ctl3D;
    // Set DataField to the field name of the field component that the control represents.
    // Access by the control to the dataset in which the field is located is provided by a TDataSource component,
    // specified in the DataSource property.
    property DataField;
    // Specify the data source component through which the data from a dataset component is provided
    // to the control. To allow the control to represent the data for a field, both the DataSource and
    // the DataField properties must be set.
    property DataSource;
    property DragCursor;
    property DragKind;
    property DragMode;
    property DropDownAlign: TDropDownAlign read FDropDownAlign write FDropDownAlign default daLeft;
    property DropDownRows: Integer read FDropDownRows write FDropDownRows default 7;
    property DropDownWidth: Integer read FDropDownWidth write FDropDownWidth default 0;
    property Enabled;
    property Font;
    property ImeMode;
    property ImeName;
    property KeyField;
    property ListField;
    property ListFieldIndex;
    property ListSource;
    property ParentBiDiMode;
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    // Use ReadOnly to specify whether the control allows the user to change the field value
    // by checking or unchecking the box. When ReadOnly is True, the control can only be used
    // to display the value of the field on the current record. When ReadOnly is False, the user
    // can use the control to change the field value.
    property ReadOnly;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Visible;
    property OnClick;
    property OnCloseUp: TNotifyEvent read FOnCloseUp write FOnCloseUp;
    {$IFDEF DELPHI5_OR_ABOVE}
    property OnContextPopup;
    {$ENDIF}
    property OnDragDrop;
    property OnDragOver;
    property OnDropDown: TNotifyEvent read FOnDropDown write FOnDropDown;
    property OnEndDock;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDock;
    property OnStartDrag;
  end;
  {$ENDIF}

implementation

{$IFDEF VER90}
var
  SysLocale: TSysLocale;
{$ENDIF}

{TDBCoolCheckRadioBox}
constructor TDBCoolCheckRadioBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := ControlStyle + [csReplicatable];
  State := cbUnchecked;
  FValueCheck := 'True';
  FValueUncheck := 'False';
  FDataLink := TFieldDataLink.Create;
  FDataLink.Control := Self;
  FDataLink.OnDataChange := DataChange;
  FDataLink.OnUpdateData := UpdateData;
end;

destructor TDBCoolCheckRadioBox.Destroy;
begin
  FDataLink.Free;
  FDataLink := nil;
  inherited Destroy;
end;

procedure TDBCoolCheckRadioBox.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and (FDataLink <> nil) and
    (AComponent = DataSource) then DataSource := nil;
end;

{$IFDEF DELPHI4_OR_ABOVE}
function TDBCoolCheckRadioBox.UseRightToLeftAlignment: Boolean;
begin
  Result := DBUseRightToLeftAlignment(Self, Field);
end;
{$ENDIF}

function TDBCoolCheckRadioBox.GetFieldState: TCheckBoxState;
var
  Text: string;
begin
  if FDatalink.Field <> nil then
    if FDataLink.Field.IsNull then
      Result := cbGrayed
    else if FDataLink.Field.DataType = ftBoolean then
      if FDataLink.Field.AsBoolean then
        Result := cbChecked
      else
        Result := cbUnchecked
    else
    begin
      Result := cbGrayed;
      Text := FDataLink.Field.Text;
      if ValueMatch(FValueCheck, Text) then Result := cbChecked else
        if ValueMatch(FValueUncheck, Text) then Result := cbUnchecked;
    end
  else
    Result := cbUnchecked;
end;

procedure TDBCoolCheckRadioBox.DataChange(Sender: TObject);
begin
  State := GetFieldState;
end;

procedure TDBCoolCheckRadioBox.UpdateData(Sender: TObject);
var
  Pos: Integer;
  S: string;
begin
  if State = cbGrayed then
    FDataLink.Field.Clear
  else
    if FDataLink.Field.DataType = ftBoolean then
      FDataLink.Field.AsBoolean := Checked
    else
    begin
      if Checked then S := FValueCheck else S := FValueUncheck;
      Pos := 1;
      FDataLink.Field.Text := ExtractFieldName(S, Pos);
    end;
end;

function TDBCoolCheckRadioBox.ValueMatch(const ValueList, Value: string): Boolean;
var
  Pos: Integer;
begin
  Result := False;
  Pos := 1;
  while Pos <= Length(ValueList) do
    if AnsiCompareText(ExtractFieldName(ValueList, Pos), Value) = 0 then
    begin
      Result := True;
      Break;
    end;
end;

function TDBCoolCheckRadioBox.Toggle: Boolean;
begin
  Result := inherited Toggle;
  if FDataLink.Edit then
    FDataLink.Modified;
end;

function TDBCoolCheckRadioBox.GetDataSource: TDataSource;
begin
  Result := FDataLink.DataSource;
end;

procedure TDBCoolCheckRadioBox.SetDataSource(Value: TDataSource);
begin
  if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then
    FDataLink.DataSource := Value;
  if Value <> nil then Value.FreeNotification(Self);
end;

function TDBCoolCheckRadioBox.GetDataField: string;
begin
  Result := FDataLink.FieldName;
end;

procedure TDBCoolCheckRadioBox.SetDataField(const Value: string);
begin
  FDataLink.FieldName := Value;
end;

function TDBCoolCheckRadioBox.GetReadOnly: Boolean;
begin
  Result := FDataLink.ReadOnly;
end;

procedure TDBCoolCheckRadioBox.SetReadOnly(Value: Boolean);
begin
  FDataLink.ReadOnly := Value;
end;

function TDBCoolCheckRadioBox.GetField: TField;
begin
  Result := FDataLink.Field;
end;

procedure TDBCoolCheckRadioBox.KeyPress(var Key: Char);
begin
  inherited KeyPress(Key);
  case Key of
    #8, ' ':
      FDataLink.Edit;
    #27:
      FDataLink.Reset;
  end;
end;

procedure TDBCoolCheckRadioBox.SetValueCheck(const Value: string);
begin
  FValueCheck := Value;
  DataChange(Self);
end;

procedure TDBCoolCheckRadioBox.SetValueUncheck(const Value: string);
begin
  FValueUncheck := Value;
  DataChange(Self);
end;

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

procedure TDBCoolCheckRadioBox.WMPaint(var Message: TWMPaint);
var
  OldState: TCheckBoxState;
begin
  if not (csPaintCopy in ControlState) then inherited else
  begin
    OldState := FState;
    FState := GetFieldState;
    inherited;
    FState := OldState;
  end;
end;

procedure TDBCoolCheckRadioBox.CMExit(var Message: TCMExit);
begin
  try
    FDataLink.UpdateRecord;
  except
    SetFocus;
    raise;
  end;
  inherited;
end;

procedure TDBCoolCheckRadioBox.CMGetDataLink(var Message: TMessage);
begin
  Message.Result := Integer(FDataLink);
end;

{$IFDEF DELPHI4_OR_ABOVE}
function TDBCoolCheckRadioBox.ExecuteAction(Action: TBasicAction): Boolean;
begin
  Result := inherited ExecuteAction(Action) or (FDataLink <> nil) and
    FDataLink.ExecuteAction(Action);
end;

function TDBCoolCheckRadioBox.UpdateAction(Action: TBasicAction): Boolean;
begin
  Result := inherited UpdateAction(Action) or (FDataLink <> nil) and
    FDataLink.UpdateAction(Action);
end;
{$ENDIF}

{TDBCoolCheckRadioGroup}
constructor TDBCoolCheckRadioGroup.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FDataLink := TFieldDataLink.Create;
  FDataLink.Control := Self;
  FDataLink.OnDataChange := DataChange;
  FDataLink.OnUpdateData := UpdateData;
  FValues := TStringList.Create;
end;

destructor TDBCoolCheckRadioGroup.Destroy;
begin
  FDataLink.Free;
  FDataLink := nil;
  FValues.Free;
  inherited Destroy;
end;

procedure TDBCoolCheckRadioGroup.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and (FDataLink <> nil) and
    (AComponent = DataSource) then DataSource := nil;
end;

{$IFDEF DELPHI4_OR_ABOVE}
function TDBCoolCheckRadioGroup.UseRightToLeftAlignment: Boolean;
begin
  Result := inherited UseRightToLeftAlignment;
end;
{$ENDIF}

procedure TDBCoolCheckRadioGroup.DataChange(Sender: TObject);
begin
  if GetParentForm(Self).Visible and CanFocus then
    SetFocus;

  if FDataLink.Field <> nil then
    Value := FDataLink.Field.Text else
    Value := '';
end;

procedure TDBCoolCheckRadioGroup.UpdateData(Sender: TObject);
begin
  if FDataLink.Field <> nil then FDataLink.Field.Text := Value;
end;

function TDBCoolCheckRadioGroup.GetDataSource: TDataSource;
begin
  Result := FDataLink.DataSource;
end;

procedure TDBCoolCheckRadioGroup.SetDataSource(Value: TDataSource);
begin
  FDataLink.DataSource := Value;
  if Value <> nil then Value.FreeNotification(Self);
end;

function TDBCoolCheckRadioGroup.GetDataField: string;
begin
  Result := FDataLink.FieldName;
end;

procedure TDBCoolCheckRadioGroup.SetDataField(const Value: string);
begin
  FDataLink.FieldName := Value;
end;

function TDBCoolCheckRadioGroup.GetReadOnly: Boolean;
begin
  Result := FDataLink.ReadOnly;
end;

procedure TDBCoolCheckRadioGroup.SetReadOnly(Value: Boolean);
begin
  FDataLink.ReadOnly := Value;
end;

function TDBCoolCheckRadioGroup.GetField: TField;
begin
  Result := FDataLink.Field;
end;

function TDBCoolCheckRadioGroup.GetButtonValue(Index: Integer): string;
begin
  if (Index < FValues.Count) and (FValues[Index] <> '') then
    Result := FValues[Index]
  else if Index < Items.Count then
    Result := Items[Index]
  else
    Result := '';
end;

procedure TDBCoolCheckRadioGroup.SetValue(const Value: string);
var
  I, Index: Integer;
begin
  if FValue <> Value then
  begin
    FInSetValue := True;
    try
      Index := -1;
      for I := 0 to Items.Count - 1 do
        if Value = GetButtonValue(I) then
        begin
          Index := I;
          Break;
        end;
      ItemIndex := Index;
    finally
      FInSetValue := False;
    end;
    FValue := Value;
    Change;
  end;
end;

procedure TDBCoolCheckRadioGroup.CMExit(var Message: TCMExit);
begin
  try
    FDataLink.UpdateRecord;
  except
    if ItemIndex >= 0 then
      TCoolCheckRadioBox(Controls[ItemIndex]).SetFocus else
      TCoolCheckRadioBox(Controls[0]).SetFocus;
    raise;
  end;
  inherited;
end;

procedure TDBCoolCheckRadioGroup.Click;
begin
  if not FInSetValue then
  begin
    FDataLink.Edit;
    inherited Click;
    if ItemIndex >= 0 then Value := GetButtonValue(ItemIndex);
    if FDataLink.Editing then FDataLink.Modified;
  end;
end;

procedure TDBCoolCheckRadioGroup.SetItems(Value: TStrings);
begin
  Items.Assign(Value);
  DataChange(Self);
end;

procedure TDBCoolCheckRadioGroup.SetValues(Value: TStrings);
begin
  FValues.Assign(Value);
  DataChange(Self);
end;

procedure TDBCoolCheckRadioGroup.Change;
begin
  if Assigned(FOnChange) then FOnChange(Self);
end;

procedure TDBCoolCheckRadioGroup.KeyPress(var Key: Char);
begin
  inherited KeyPress(Key);
  case Key of
    #8, ' ': FDataLink.Edit;
    #27: FDataLink.Reset;
  end;
end;

{$IFDEF DELPHI4_OR_ABOVE}
function TDBCoolCheckRadioGroup.ExecuteAction(Action: TBasicAction): Boolean;
begin
  Result := inherited ExecuteAction(Action) or (DataLink <> nil) and
    DataLink.ExecuteAction(Action);
end;

function TDBCoolCheckRadioGroup.UpdateAction(Action: TBasicAction): Boolean;
begin
  Result := inherited UpdateAction(Action) or (DataLink <> nil) and
    DataLink.UpdateAction(Action);
end;
{$ENDIF}

{TDBCoolListBox}
constructor TDBCoolListBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FDataLink := TFieldDataLink.Create;
  FDataLink.Control := Self;
  FDataLink.OnDataChange := DataChange;
  FDataLink.OnUpdateData := UpdateData;
end;

destructor TDBCoolListBox.Destroy;
begin
  FDataLink.Free;
  FDataLink := nil;
  inherited Destroy;
end;

procedure TDBCoolListBox.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FDataLink) and (AComponent = DataSource) then
    DataSource := nil;
end;

procedure TDBCoolListBox.DataChange(Sender: TObject);
begin
  if Assigned(FDataLink.Field) then
    ItemIndex := Items.IndexOf(FDataLink.Field.Text)
  else
    ItemIndex := -1;
end;

procedure TDBCoolListBox.UpdateData(Sender: TObject);
begin
  if ItemIndex >= 0 then
    FDataLink.Field.Text := Items[ItemIndex]
  else
    FDataLink.Field.Text := '';
end;

procedure TDBCoolListBox.Click;
begin
  if FDataLink.Edit then
  begin
    inherited Click;
    FDataLink.Modified;
  end;
end;

function TDBCoolListBox.GetDataSource: TDataSource;
begin
  Result := FDataLink.DataSource;
end;

procedure TDBCoolListBox.SetDataSource(Value: TDataSource);
begin
  FDataLink.DataSource := Value;
  if Assigned(Value) then
    Value.FreeNotification(Self);
end;

function TDBCoolListBox.GetDataField: string;
begin
  Result := FDataLink.FieldName;
end;

procedure TDBCoolListBox.SetDataField(const Value: string);
begin
  FDataLink.FieldName := Value;
end;

function TDBCoolListBox.GetReadOnly: Boolean;
begin
  Result := FDataLink.ReadOnly;
end;

procedure TDBCoolListBox.SetReadOnly(Value: Boolean);
begin
  FDataLink.ReadOnly := Value;
end;

function TDBCoolListBox.GetField: TField;
begin
  Result := FDataLink.Field;
end;

procedure TDBCoolListBox.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited KeyDown(Key, Shift);
  if Key in [VK_PRIOR, VK_NEXT, VK_END, VK_HOME, VK_LEFT, VK_UP,
    VK_RIGHT, VK_DOWN] then
    if not FDataLink.Edit then Key := 0;
end;

procedure TDBCoolListBox.KeyPress(var Key: Char);
begin
  inherited KeyPress(Key);
  case Key of
    #32..#255:
      if not FDataLink.Edit then Key := #0;
    #27:
      FDataLink.Reset;
  end;
end;

procedure TDBCoolListBox.WMLButtonDown(var Message: TWMLButtonDown);
begin
  if FDataLink.Edit then inherited
  else
  begin
    SetFocus;
    with Message do
      MouseDown(mbLeft, KeysToShiftState(Keys), XPos, YPos);
  end;
end;

procedure TDBCoolListBox.CMExit(var Message: TCMExit);
begin
  try
    FDataLink.UpdateRecord;
  except
    SetFocus;
    raise;
  end;
  inherited;
end;

procedure TDBCoolListBox.SetItems(Value: TStrings);
begin
  Items.Assign(Value);
  DataChange(Self);
end;

procedure TDBCoolListBox.BuildItems;
var
  BookMark: TBookMark;
begin
  if Assigned(FDataLink.Field) then
  begin
    BookMark := FDataLink.DataSet.GetBookMark;

    FDataLink.DataSet.DisableControls;
    Items.BeginUpdate;
    Items.Clear;

    FDataLink.DataSet.First;
    while not FDataLink.DataSet.Eof do
    begin
      Items.Add(FDataLink.Field.Text);
      FDataLink.DataSet.Next;
    end;
    Items.EndUpdate;
    FDataLink.DataSet.EnableControls;

    FDataLink.DataSet.GotoBookMark(BookMark);
    FDataLink.DataSet.FreeBookMark(BookMark);
  end;
end;

{TDBCoolCombobox}
constructor TDBCoolCombobox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := ControlStyle + [csReplicatable];
  FDataLink := TFieldDataLink.Create;
  FDataLink.Control := Self;
  FDataLink.OnDataChange := DataChange;
  FDataLink.OnUpdateData := UpdateData;
  FDataLink.OnEditingChange := EditingChange;
end;

destructor TDBCoolCombobox.Destroy;
begin
  FDataLink.Free;
  FDataLink := nil;
  inherited Destroy;
end;

procedure TDBCoolCombobox.Loaded;
begin
  inherited Loaded;
  if (csDesigning in ComponentState) then DataChange(Self);
end;

procedure TDBCoolCombobox.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FDataLink) and (AComponent = DataSource) then
    DataSource := nil;
end;

procedure TDBCoolCombobox.CreateWnd;
begin
  inherited CreateWnd;
  SetEditReadOnly;
end;

procedure TDBCoolCombobox.DataChange(Sender: TObject);
begin
  if DroppedDown then Exit;
  if Assigned(FDataLink.Field) then
    SetComboText(FDataLink.Field.Text)
  else
    if csDesigning in ComponentState then
      SetComboText(Name)
    else
      SetComboText('');
end;

procedure TDBCoolCombobox.UpdateData(Sender: TObject);
begin
  FDataLink.Field.Text := GetComboText;
end;

procedure TDBCoolCombobox.SetComboText(const Value: string);
var
  I: Integer;
  Redraw: Boolean;
begin
  if Value <> GetComboText then
  begin
    if Style <> csDropDown then
    begin
      Redraw := (Style <> csSimple) and HandleAllocated;
      if Redraw then SendMessage(Handle, WM_SETREDRAW, 0, 0);
      try
        if Value = '' then I := -1 else I := Items.IndexOf(Value);
        ItemIndex := I;
      finally
        if Redraw then
        begin
          SendMessage(Handle, WM_SETREDRAW, 1, 0);
          Invalidate;
        end;
      end;
      if I >= 0 then Exit;
    end;

    if Style in [csDropDown, csSimple] then 
      Text := Value;
  end;
end;

function TDBCoolCombobox.GetComboText: string;
var
  I: Integer;
begin
  if Style in [csDropDown, csSimple] then 
    Result := Text
  else
    begin
      I := ItemIndex;
      if I < 0 then Result := '' else Result := Items[I];
    end;
end;

procedure TDBCoolCombobox.Change;
begin
  FDataLink.Edit;
  inherited Change;
  FDataLink.Modified;
end;

procedure TDBCoolCombobox.Click;
begin
  FDataLink.Edit;
  inherited Click;
  FDataLink.Modified;
end;

procedure TDBCoolCombobox.DropDown;
begin
  inherited DropDown;
end;

function TDBCoolCombobox.GetDataSource: TDataSource;
begin
  Result := FDataLink.DataSource;
end;

procedure TDBCoolCombobox.SetDataSource(Value: TDataSource);
begin
  FDataLink.DataSource := Value;
  if Assigned(Value) then
    Value.FreeNotification(Self);
end;

function TDBCoolCombobox.GetDataField: string;
begin
  Result := FDataLink.FieldName;
end;

procedure TDBCoolCombobox.SetDataField(const Value: string);
begin
  FDataLink.FieldName := Value;
end;

function TDBCoolCombobox.GetReadOnly: Boolean;
begin
  Result := FDataLink.ReadOnly;
end;

procedure TDBCoolCombobox.SetReadOnly(Value: Boolean);
begin
  FDataLink.ReadOnly := Value;
end;

function TDBCoolCombobox.GetField: TField;
begin
  Result := FDataLink.Field;
end;

procedure TDBCoolCombobox.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited KeyDown(Key, Shift);
  if Key in [VK_BACK, VK_DELETE, VK_UP, VK_DOWN, 32..255] then
  begin
    if not FDataLink.Edit and (Key in [VK_UP, VK_DOWN]) then
      Key := 0;
  end;
end;

procedure TDBCoolCombobox.KeyPress(var Key: Char);
begin
  inherited KeyPress(Key);
  if (Key in [#32..#255]) and Assigned(FDataLink.Field) and  not FDataLink.Field.IsValidChar(Key) then
  begin
    MessageBeep(0);
    Key := #0;
  end;
  case Key of
    ^H, ^V, ^X, #32..#255:
      FDataLink.Edit;
    #27:
      begin
        FDataLink.Reset;
        SelectAll;
      end;
  end;
end;

procedure TDBCoolCombobox.EditingChange(Sender: TObject);
begin
  SetEditReadOnly;
end;

procedure TDBCoolCombobox.SetEditReadOnly;
begin
  if (Style in [csDropDown, csSimple]) and HandleAllocated then
    SendMessage(EditHandle, EM_SETREADONLY, Ord(not FDataLink.Editing), 0);
end;

procedure TDBCoolCombobox.WndProc(var Message: TMessage);
begin
  if not (csDesigning in ComponentState) then
    case Message.Msg of

      WM_COMMAND:
        if TWMCommand(Message).NotifyCode = CBN_SELCHANGE then
          if not FDataLink.Edit then
          begin
            if Style <> csSimple then
              PostMessage(Handle, CB_SHOWDROPDOWN, 0, 0);
            Exit;
          end;

      CB_SHOWDROPDOWN:
        if Message.WParam <> 0 then FDataLink.Edit else
          if not FDataLink.Editing then DataChange(Self); {Restore text}

    end;
  inherited WndProc(Message);
end;

procedure TDBCoolCombobox.ComboWndProc(var Message: TMessage; ComboWnd: HWnd;
  ComboProc: Pointer);
begin
  if not (csDesigning in ComponentState) then
    case Message.Msg of
      WM_LBUTTONDOWN:
        if (Style = csSimple) and (ComboWnd <> EditHandle) then
          if not FDataLink.Edit then Exit;
    end;
  inherited ComboWndProc(Message, ComboWnd, ComboProc);
end;

procedure TDBCoolCombobox.CMEnter(var Message: TCMEnter);
begin
  inherited;
  if SysLocale.FarEast and FDataLink.CanModify then
    SendMessage(EditHandle, EM_SETREADONLY, Ord(False), 0);
end;

procedure TDBCoolCombobox.CMExit(var Message: TCMExit);
begin
  try
    FDataLink.UpdateRecord;
  except
    SelectAll;
    SetFocus;
    raise;
  end;
  inherited;
end;

procedure TDBCoolCombobox.WMPaint(var Message: TWMPaint);
begin
  if Focused or not (csPaintCopy in ControlState) then inherited else
  begin
  end;
end;

procedure TDBCoolCombobox.SetItems(Value: TStrings);
begin
  Items.Assign(Value);
  DataChange(Self);
end;

procedure TDBCoolCombobox.SetStyle(Value: TComboboxStyle);
begin
  if (Value = csSimple) and Assigned(FDatalink) and FDatalink.DatasourceFixed then
    DatabaseError('Database not replicatable');
  inherited SetStyle(Value);
end;

procedure TDBCoolCombobox.CMGetDatalink(var Message: TMessage);
begin
  Message.Result := Integer(FDataLink);
end;

procedure TDBCoolCombobox.BuildItems;
var
  BookMark: TBookMark;
begin
  if Assigned(FDataLink.Field) then
  begin
    BookMark := FDataLink.DataSet.GetBookMark;

    FDataLink.DataSet.DisableControls;
    Items.BeginUpdate;
    Items.Clear;

    FDataLink.DataSet.First;
    while not FDataLink.DataSet.Eof do
    begin
      Items.Add(FDataLink.Field.Text);
      FDataLink.DataSet.Next;
    end;
    Items.EndUpdate;
    FDataLink.DataSet.EnableControls;

    FDataLink.DataSet.GotoBookMark(BookMark);
    FDataLink.DataSet.FreeBookMark(BookMark);
  end;
end;

{TDBCoolEdit}
constructor TDBCoolEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  inherited ReadOnly := True;
  ControlStyle := ControlStyle + [csReplicatable];
  FDataLink := TFieldDataLink.Create;
  FDataLink.Control := Self;
  FDataLink.OnDataChange := DataChange;
  FDataLink.OnUpdateData := UpdateData;
  FDataLink.OnEditingChange := EditingChange;
end;

destructor TDBCoolEdit.Destroy;
begin
  FDataLink.Free;
  FDataLink := nil;
  inherited Destroy;
end;

procedure TDBCoolEdit.Loaded;
begin
  inherited Loaded;
  if (csDesigning in ComponentState) then
    DataChange(Self);
end;

procedure TDBCoolEdit.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and (FDataLink <> nil) and
    (AComponent = DataSource) then DataSource := nil;
end;

procedure TDBCoolEdit.SetFocused(Value: Boolean);
begin
  if FFocused <> Value then
  begin
    FFocused := Value;
    FDataLink.Reset;
  end;
end;

procedure TDBCoolEdit.Change;
begin
  FDataLink.Modified;
  inherited Change;
end;

function TDBCoolEdit.GetDataSource: TDataSource;
begin
  Result := FDataLink.DataSource;
end;

procedure TDBCoolEdit.SetDataSource(Value: TDataSource);
begin
  FDataLink.DataSource := Value;
  if Value <> nil then Value.FreeNotification(Self);
end;

function TDBCoolEdit.GetDataField: string;
begin
  Result := FDataLink.FieldName;
end;

procedure TDBCoolEdit.SetDataField(const Value: string);
begin
  FDataLink.FieldName := Value;
end;

function TDBCoolEdit.GetField: TField;
begin
  Result := FDataLink.Field;
end;

function TDBCoolEdit.GetReadOnly: Boolean;
begin
  Result := FDataLink.ReadOnly;
end;

procedure TDBCoolEdit.SetReadOnly(Value: Boolean);
begin
  FDataLink.ReadOnly := Value;
end;

procedure TDBCoolEdit.WMPaste(var Message: TMessage);
begin
  FDataLink.Edit;
  inherited;
end;

procedure TDBCoolEdit.WMCut(var Message: TMessage);
begin
  FDataLink.Edit;
  inherited;
end;

procedure TDBCoolEdit.CMEnter(var Message: TCMEnter);
begin
  SetFocused(True);
  inherited;
end;

procedure TDBCoolEdit.CMExit(var Message: TCMExit);
begin
  try
    FDataLink.UpdateRecord;
  except
    SelectAll;
    SetFocus;
    raise;
  end;
  SetFocused(False);
  DoExit;
end;

procedure TDBCoolEdit.WMPaint(var Message: TWMPaint);
const
  Alignments: array[TAlignment] of Word = (DT_LEFT, DT_RIGHT, DT_CENTER);
var
  S: string;
  R: TRect;
begin
  if Focused or not (csPaintCopy in ControlState) then inherited else
  begin
    if FDataLink.Field <> nil then
      begin
        S := FDataLink.Field.DisplayText;
        case CharCase of
          ecUpperCase: S := AnsiUpperCase(S);
          ecLowerCase: S := AnsiLowerCase(S);
        end;
      end;

    Perform(EM_GETRECT, 0, Integer(@R));
    SelectObject(Message.DC, Font.Handle);
    SetBkMode(Message.DC, Transparent);
    DrawText(Message.DC, PChar(S), Length(S), R, DT_WORDBREAK or Alignments[TextAlign]);
  end;
end;

procedure TDBCoolEdit.CMGetDataLink(var Message: TMessage);
begin
  Message.Result := Integer(FDataLink);
end;

procedure TDBCoolEdit.DataChange(Sender: TObject);
begin
  if FDataLink.Field <> nil then
  begin
    if FDataLink.Field.DataType = ftString then
      MaxLength := FDataLink.Field.Size else
      MaxLength := 0;
    if FFocused and FDataLink.CanModify then
      Text := FDataLink.Field.Text
    else
      Text := FDataLink.Field.DisplayText;
  end else
  begin
    if csDesigning in ComponentState then
      Text := Name else
      Text := '';
  end;
end;

procedure TDBCoolEdit.UpdateData(Sender: TObject);
begin
  FDataLink.Field.Text := Text;
end;

procedure TDBCoolEdit.EditingChange(Sender: TObject);
begin
  inherited ReadOnly := not FDataLink.Editing;
end;

procedure TDBCoolEdit.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited KeyDown(Key, Shift);
  if (Key = VK_DELETE) or ((Key = VK_INSERT) and (ssShift in Shift)) then
    FDataLink.Edit;
end;

procedure TDBCoolEdit.KeyPress(var Key: Char);
begin
  inherited KeyPress(Key);
  if (Key in [#32..#255]) and (FDataLink.Field <> nil) and
    not FDataLink.Field.IsValidChar(Key) then
  begin
    MessageBeep(0);
    Key := #0;
  end;
  case Key of
    ^H, ^V, ^X, #32..#255:
      FDataLink.Edit;
    #27:
      begin
        FDataLink.Reset;
        SelectAll;
        Key := #0;
      end;
  end;
end;

{TDBCoolEditBtn}
constructor TDBCoolEditBtn.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  inherited ReadOnly := True;
  ControlStyle := ControlStyle + [csReplicatable];
  FDataLink := TFieldDataLink.Create;
  FDataLink.Control := Self;
  FDataLink.OnDataChange := DataChange;
  FDataLink.OnUpdateData := UpdateData;
  FDataLink.OnEditingChange := EditingChange;
end;

destructor TDBCoolEditBtn.Destroy;
begin
  FDataLink.Free;
  FDataLink := nil;
  inherited Destroy;
end;

procedure TDBCoolEditBtn.Loaded;
begin
  inherited Loaded;
  if (csDesigning in ComponentState) then
    DataChange(Self);
end;

procedure TDBCoolEditBtn.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and (FDataLink <> nil) and
    (AComponent = DataSource) then DataSource := nil;
end;

procedure TDBCoolEditBtn.SetFocused(Value: Boolean);
begin
  if FFocused <> Value then
  begin
    FFocused := Value;
    FDataLink.Reset;
  end;
end;

procedure TDBCoolEditBtn.Change;
begin
  FDataLink.Modified;
  inherited Change;
end;

function TDBCoolEditBtn.GetDataSource: TDataSource;
begin
  Result := FDataLink.DataSource;
end;

procedure TDBCoolEditBtn.SetDataSource(Value: TDataSource);
begin
  FDataLink.DataSource := Value;
  if Value <> nil then Value.FreeNotification(Self);
end;

function TDBCoolEditBtn.GetDataField: string;
begin
  Result := FDataLink.FieldName;
end;

procedure TDBCoolEditBtn.SetDataField(const Value: string);
begin
  FDataLink.FieldName := Value;
end;

function TDBCoolEditBtn.GetField: TField;
begin
  Result := FDataLink.Field;
end;

function TDBCoolEditBtn.GetReadOnly: Boolean;
begin
  Result := FDataLink.ReadOnly;
end;

procedure TDBCoolEditBtn.SetReadOnly(Value: Boolean);
begin
  FDataLink.ReadOnly := Value;
end;

procedure TDBCoolEditBtn.WMPaint(var Message: TWMPaint);
const
  Alignments: array[TAlignment] of Word = (DT_LEFT, DT_RIGHT, DT_CENTER);
var
  S: string;
  R: TRect;
begin
  if Focused or not (csPaintCopy in ControlState) then inherited else
  begin
    if FDataLink.Field <> nil then
      begin
        S := FDataLink.Field.DisplayText;
        case CharCase of
          ecUpperCase: S := AnsiUpperCase(S);
          ecLowerCase: S := AnsiLowerCase(S);
        end;
      end;

    Perform(EM_GETRECT, 0, Integer(@R));
    SelectObject(Message.DC, Font.Handle);
    SetBkMode(Message.DC, Transparent);
    DrawText(Message.DC, PChar(S), Length(S), R, DT_WORDBREAK or Alignments[TextAlign]);
  end;
end;

procedure TDBCoolEditBtn.WMPaste(var Message: TMessage);
begin
  FDataLink.Edit;
  inherited;
end;

procedure TDBCoolEditBtn.WMCut(var Message: TMessage);
begin
  FDataLink.Edit;
  inherited;
end;

procedure TDBCoolEditBtn.CMEnter(var Message: TCMEnter);
begin
  SetFocused(True);
  inherited;
end;

procedure TDBCoolEditBtn.CMExit(var Message: TCMExit);
begin
  try
    FDataLink.UpdateRecord;
  except
    SelectAll;
    SetFocus;
    raise;
  end;
  SetFocused(False);
  DoExit;
end;

procedure TDBCoolEditBtn.CMGetDataLink(var Message: TMessage);
begin
  Message.Result := Integer(FDataLink);
end;

procedure TDBCoolEditBtn.DataChange(Sender: TObject);
begin
  if FDataLink.Field <> nil then
  begin
    if FDataLink.Field.DataType = ftString then
      MaxLength := FDataLink.Field.Size else
      MaxLength := 0;
    if FFocused and FDataLink.CanModify then
      Text := FDataLink.Field.Text
    else
      Text := FDataLink.Field.DisplayText;
  end else
  begin
    if csDesigning in ComponentState then
      Text := Name else
      Text := '';
  end;
end;

procedure TDBCoolEditBtn.UpdateData(Sender: TObject);
begin
  FDataLink.Field.Text := Text;
end;

procedure TDBCoolEditBtn.EditingChange(Sender: TObject);
begin
  inherited ReadOnly := not FDataLink.Editing;
end;

procedure TDBCoolEditBtn.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited KeyDown(Key, Shift);
  if (Key = VK_DELETE) or ((Key = VK_INSERT) and (ssShift in Shift)) then
    FDataLink.Edit;
end;

procedure TDBCoolEditBtn.KeyPress(var Key: Char);
begin
  inherited KeyPress(Key);
  if (Key in [#32..#255]) and (FDataLink.Field <> nil) and
    not FDataLink.Field.IsValidChar(Key) then
  begin
    MessageBeep(0);
    Key := #0;
  end;
  case Key of
    ^H, ^V, ^X, #32..#255:
      FDataLink.Edit;
    #27:
      begin
        FDataLink.Reset;
        SelectAll;
        Key := #0;
      end;
  end;
end;

{TDBCoolMemo}
constructor TDBCoolMemo.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  inherited ReadOnly := True;
  ControlStyle := ControlStyle + [csReplicatable];
  FAutoDisplay := True;
  FDataLink := TFieldDataLink.Create;
  FDataLink.Control := Self;
  FDataLink.OnDataChange := DataChange;
  FDataLink.OnEditingChange := EditingChange;
  FDataLink.OnUpdateData := UpdateData;
end;

destructor TDBCoolMemo.Destroy;
begin
  FDataLink.Free;
  FDataLink := nil;
  inherited Destroy;
end;

procedure TDBCoolMemo.Loaded;
begin
  inherited Loaded;
  if (csDesigning in ComponentState) then DataChange(Self);
end;

procedure TDBCoolMemo.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and (FDataLink <> nil) and
    (AComponent = DataSource) then DataSource := nil;
end;

procedure TDBCoolMemo.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited KeyDown(Key, Shift);
  if FMemoLoaded then
  begin
    if (Key = VK_DELETE) or ((Key = VK_INSERT) and (ssShift in Shift)) then
      FDataLink.Edit;
  end;
end;

procedure TDBCoolMemo.KeyPress(var Key: Char);
begin
  inherited KeyPress(Key);
  if FMemoLoaded then
  begin
    if (Key in [#32..#255]) and (FDataLink.Field <> nil) and
      not FDataLink.Field.IsValidChar(Key) then
    begin
      MessageBeep(0);
      Key := #0;
    end;
    case Key of
      ^H, ^I, ^J, ^M, ^V, ^X, #32..#255:
        FDataLink.Edit;
      #27:
        FDataLink.Reset;
    end;
  end else
  begin
    if Key = #13 then LoadMemo;
    Key := #0;
  end;
end;

procedure TDBCoolMemo.Change;
begin
  if FMemoLoaded then FDataLink.Modified;
  FMemoLoaded := True;
  inherited Change;
end;

function TDBCoolMemo.GetDataSource: TDataSource;
begin
  Result := FDataLink.DataSource;
end;

procedure TDBCoolMemo.SetDataSource(Value: TDataSource);
begin
  if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then
    FDataLink.DataSource := Value;
  if Value <> nil then Value.FreeNotification(Self);
end;

function TDBCoolMemo.GetDataField: string;
begin
  Result := FDataLink.FieldName;
end;

procedure TDBCoolMemo.SetDataField(const Value: string);
begin
  FDataLink.FieldName := Value;
end;

function TDBCoolMemo.GetReadOnly: Boolean;
begin
  Result := FDataLink.ReadOnly;
end;

procedure TDBCoolMemo.SetReadOnly(Value: Boolean);
begin
  FDataLink.ReadOnly := Value;
end;

function TDBCoolMemo.GetField: TField;
begin
  Result := FDataLink.Field;
end;

procedure TDBCoolMemo.LoadMemo;
begin
  if not FMemoLoaded and Assigned(FDataLink.Field) {$IFDEF DELPHI4_OR_ABOVE} and FDataLink.Field.IsBlob {$ENDIF} then
  begin
    try
      Lines.Text := FDataLink.Field.AsString;
      FMemoLoaded := True;
    except
      { Memo too large }
      on E:EInvalidOperation do
        Lines.Text := Format('(%s)', [E.Message]);
    end;
    EditingChange(Self);
  end;
end;

procedure TDBCoolMemo.DataChange(Sender: TObject);
begin
  if FDataLink.Field <> nil then
    {$IFDEF DELPHI4_OR_ABOVE}
    if FDataLink.Field.IsBlob then
    {$ELSE}
    if True then
    {$ENDIF}
    begin
      if FAutoDisplay or (FDataLink.Editing and FMemoLoaded) then
      begin
        FMemoLoaded := False;
        LoadMemo;
      end else
      begin
        Text := Format('(%s)', [FDataLink.Field.DisplayLabel]);
        FMemoLoaded := False;
      end;
    end else
    begin
      if FFocused and FDataLink.CanModify then
        Text := FDataLink.Field.Text
      else
        Text := FDataLink.Field.DisplayText;
      FMemoLoaded := True;
    end
  else
  begin
    if csDesigning in ComponentState then Text := Name else Text := '';
    FMemoLoaded := False;
  end;
  if HandleAllocated then
    RedrawWindow(Handle, nil, 0, RDW_INVALIDATE or RDW_ERASE or RDW_FRAME);
end;

procedure TDBCoolMemo.EditingChange(Sender: TObject);
begin
  inherited ReadOnly := not (FDataLink.Editing and FMemoLoaded);
end;

procedure TDBCoolMemo.UpdateData(Sender: TObject);
begin
  FDataLink.Field.AsString := Text;
end;

procedure TDBCoolMemo.SetFocused(Value: Boolean);
begin
  if FFocused <> Value then
  begin
    FFocused := Value;
    if not Assigned(FDataLink.Field) {$IFDEF DELPHI4_OR_ABOVE} or not FDataLink.Field.IsBlob {$ENDIF} then
      FDataLink.Reset;
  end;
end;

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

procedure TDBCoolMemo.CMEnter(var Message: TCMEnter);
begin
  SetFocused(True);
  inherited;
  if SysLocale.FarEast and FDataLink.CanModify then
    inherited ReadOnly := False;
end;

procedure TDBCoolMemo.CMExit(var Message: TCMExit);
begin
  try
    FDataLink.UpdateRecord;
  except
    SetFocus;
    raise;
  end;
  SetFocused(False);
  inherited;
end;

procedure TDBCoolMemo.SetAutoDisplay(Value: Boolean);
begin
  if FAutoDisplay <> Value then
  begin
    FAutoDisplay := Value;
    if Value then LoadMemo;
  end;
end;

procedure TDBCoolMemo.WMLButtonDblClk(var Message: TWMLButtonDblClk);
begin
  if not FMemoLoaded then LoadMemo else inherited;
end;

procedure TDBCoolMemo.WMCut(var Message: TMessage);
begin
  FDataLink.Edit;
  inherited;
end;

procedure TDBCoolMemo.WMPaste(var Message: TMessage);
begin
  FDataLink.Edit;
  inherited;
end;

procedure TDBCoolMemo.CMGetDataLink(var Message: TMessage);
begin
  Message.Result := Integer(FDataLink);
end;

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

procedure TDBCoolMemo.WMPaint(var Message: TWMPaint);
const
  Alignments: array[TAlignment] of Word = (DT_LEFT, DT_RIGHT, DT_CENTER);
var
  S: string;
  R: TRect;
begin
  if Focused or not (csPaintCopy in ControlState) then inherited else
  begin
    if FDataLink.Field <> nil then
      {$IFDEF DELPHI4_OR_ABOVE}
      if not FDataLink.Field.IsBlob then
      {$ELSE}
      if True then
      {$ENDIF}
        S := FDataLink.Field.DisplayText else
          begin
            if FAutoDisplay then
              S := AdjustLineBreaks(FDataLink.Field.AsString) else
              S := Format('(%s)', [FDataLink.Field.DisplayLabel]);
          end;

    Perform(EM_GETRECT, 0, Integer(@R));
    SelectObject(Message.DC, Font.Handle);
    if Enabled then
      SetTextColor(Message.DC, ColorToRgb(Font.Color)) else
      SetTextColor(Message.DC, ColorToRgb(clBtnShadow));
    SetBkMode(Message.DC, Transparent);
    DrawText(Message.DC, PChar(S), Length(S), R, DT_WORDBREAK or Alignments[TextAlign]);
  end;
end;

procedure TDBCoolMemo.WMSetFocus(var Message: TWMSetFocus);
begin
  inherited;
end;

procedure TDBCoolMemo.WMKillFocus(var Message: TWMKillFocus);
begin
  inherited;
end;

{$IFDEF DELPHI4_OR_ABOVE}
function TDBCoolMemo.ExecuteAction(Action: TBasicAction): Boolean;
begin
  Result := inherited ExecuteAction(Action) or (FDataLink <> nil) and
    FDataLink.ExecuteAction(Action);
end;

function TDBCoolMemo.UpdateAction(Action: TBasicAction): Boolean;
begin
  Result := inherited UpdateAction(Action) or (FDataLink <> nil) and
    FDataLink.UpdateAction(Action);
end;
{$ENDIF}

{TDBCoolText}
constructor TDBCoolText.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := ControlStyle + [csReplicatable];
  AutoSize := False;
  ShowAccelChar := False;
  FDataLink := TFieldDataLink.Create;
  {$IFNDEF VER90}
  FDataLink.Control := Self;
  {$ELSE}
  FDataLink.Control := TWinControl(Self);  
  {$ENDIF}
  FDataLink.OnDataChange := DataChange;
end;

destructor TDBCoolText.Destroy;
begin
  FDataLink.Free;
  FDataLink := nil;
  inherited Destroy;
end;

procedure TDBCoolText.Loaded;
begin
  inherited Loaded;
  if (csDesigning in ComponentState) then DataChange(Self);
end;

procedure TDBCoolText.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and (FDataLink <> nil) and
    (AComponent = DataSource) then DataSource := nil;
end;

{$IFDEF DELPHI4_OR_ABOVE}
function TDBCoolText.UseRightToLeftAlignment: Boolean;
begin
  Result := DBUseRightToLeftAlignment(Self, Field);
end;
{$ENDIF}

procedure TDBCoolText.SetAutoSize(Value: Boolean);
begin
  if AutoSize <> Value then
  begin
    if Value and FDataLink.DataSourceFixed then DatabaseError('Can''t resize text');
    inherited SetAutoSize(Value);
  end;
end;

function TDBCoolText.GetDataSource: TDataSource;
begin
  Result := FDataLink.DataSource;
end;

procedure TDBCoolText.SetDataSource(Value: TDataSource);
begin
  if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then
    FDataLink.DataSource := Value;
  if Value <> nil then Value.FreeNotification(Self);
end;

function TDBCoolText.GetDataField: string;
begin
  Result := FDataLink.FieldName;
end;

procedure TDBCoolText.SetDataField(const Value: string);
begin
  FDataLink.FieldName := Value;
end;

function TDBCoolText.GetField: TField;
begin
  Result := FDataLink.Field;
end;

function TDBCoolText.GetFieldText: string;
begin
  if FDataLink.Field <> nil then
    Result := FDataLink.Field.DisplayText
  else
    if csDesigning in ComponentState then Result := Name else Result := '';
end;

procedure TDBCoolText.DataChange(Sender: TObject);
begin
  Caption := GetFieldText;
end;

function TDBCoolText.GetLabelText: string;
begin
  if csPaintCopy in ControlState then
    Result := GetFieldText else
    Result := Caption;
end;

procedure TDBCoolText.CMGetDataLink(var Message: TMessage);
begin
  Message.Result := Integer(FDataLink);
end;

{$IFDEF DELPHI4_OR_ABOVE}
function TDBCoolText.ExecuteAction(Action: TBasicAction): Boolean;
begin
  Result := inherited ExecuteAction(Action) or (FDataLink <> nil) and
    FDataLink.ExecuteAction(Action);
end;

function TDBCoolText.UpdateAction(Action: TBasicAction): Boolean;
begin
  Result := inherited UpdateAction(Action) or (FDataLink <> nil) and
    FDataLink.UpdateAction(Action);
end;
{$ENDIF}

{TDBCoolScrollingText}
constructor TDBCoolScrollingText.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := ControlStyle + [csReplicatable];
  ShowAccelChar := False;
  FDataLink := TFieldDataLink.Create;
  {$IFNDEF VER90}
  FDataLink.Control := Self;
  {$ELSE}
  FDataLink.Control := TWinControl(Self);  
  {$ENDIF}
  FDataLink.OnDataChange := DataChange;
end;

destructor TDBCoolScrollingText.Destroy;
begin
  FDataLink.Free;
  FDataLink := nil;
  inherited Destroy;
end;

procedure TDBCoolScrollingText.Loaded;
begin
  inherited Loaded;
  if (csDesigning in ComponentState) then DataChange(Self);
end;

procedure TDBCoolScrollingText.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and (FDataLink <> nil) and
    (AComponent = DataSource) then DataSource := nil;
end;

{$IFDEF DELPHI4_OR_ABOVE}
function TDBCoolScrollingText.UseRightToLeftAlignment: Boolean;
begin
  Result := DBUseRightToLeftAlignment(Self, Field);
end;
{$ENDIF}

function TDBCoolScrollingText.GetDataSource: TDataSource;
begin
  Result := FDataLink.DataSource;
end;

procedure TDBCoolScrollingText.SetDataSource(Value: TDataSource);
begin
  if not (FDataLink.DataSourceFixed and (csLoading in ComponentState)) then
    FDataLink.DataSource := Value;
  if Value <> nil then Value.FreeNotification(Self);
end;

function TDBCoolScrollingText.GetDataField: string;
begin
  Result := FDataLink.FieldName;
end;

procedure TDBCoolScrollingText.SetDataField(const Value: string);
begin
  FDataLink.FieldName := Value;
end;

function TDBCoolScrollingText.GetField: TField;
begin
  Result := FDataLink.Field;
end;

function TDBCoolScrollingText.GetFieldText: string;
begin
  if FDataLink.Field <> nil then
    Result := FDataLink.Field.DisplayText
  else
    if csDesigning in ComponentState then Result := Name else Result := '';
end;

procedure TDBCoolScrollingText.DataChange(Sender: TObject);
begin
  Strings.Text := GetFieldText;
end;

function TDBCoolScrollingText.GetStrings: TStrings;
begin
  Result := inherited GetStrings;
  if csPaintCopy in ControlState then
    Result.Text := GetFieldText;
end;

procedure TDBCoolScrollingText.CMGetDataLink(var Message: TMessage);
begin
  Message.Result := Integer(FDataLink);
end;

{$IFDEF DELPHI4_OR_ABOVE}
function TDBCoolScrollingText.ExecuteAction(Action: TBasicAction): Boolean;
begin
  Result := inherited ExecuteAction(Action) or (FDataLink <> nil) and
    FDataLink.ExecuteAction(Action);
end;

function TDBCoolScrollingText.UpdateAction(Action: TBasicAction): Boolean;
begin
  Result := inherited UpdateAction(Action) or (FDataLink <> nil) and
    FDataLink.UpdateAction(Action);
end;
{$ENDIF}

{TDBCoolGrid}
var
  DrawBitmap: TBitmap;
  UserCount: Integer;

procedure UsesBitmap;
begin
  if UserCount = 0 then
    DrawBitmap := TBitmap.Create;
  Inc(UserCount);
end;

procedure ReleaseBitmap;
begin
  Dec(UserCount);
  if UserCount = 0 then DrawBitmap.Free;
end;

procedure WriteText(ACanvas: TCanvas; ARect: TRect; DX, DY: Integer;
  const Text: string; Alignment: TAlignment; ARightToLeft: Boolean);
const
  AlignFlags : array [TAlignment] of Integer =
    ( DT_LEFT or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX,
      DT_RIGHT or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX,
      DT_CENTER or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX );
  RTL: array [Boolean] of Integer = (0, DT_RTLREADING);
var
  B, R: TRect;
  {$IFDEF DELPHI4_OR_ABOVE}
  Hold: Integer;
  {$ENDIF}
  Left: Integer;
  I: TColorRef;
  Rgn: HRGN;
  SaveIndex: Integer;
begin
  I := ColorToRGB(ACanvas.Brush.Color);
  if GetNearestColor(ACanvas.Handle, I) = I then
  begin                       { Use ExtTextOut for solid colors }

    {$IFDEF DELPHI4_OR_ABOVE}
    { In BiDi, because we changed the window origin, the text that does not
      change alignment, actually gets its alignment changed. }
    if (ACanvas.CanvasOrientation = coRightToLeft) and (not ARightToLeft) then
      ChangeBiDiModeAlignment(Alignment);
    {$ENDIF}

    case Alignment of
      taLeftJustify:
        Left := ARect.Left + DX;
      taRightJustify:
        Left := ARect.Right - ACanvas.TextWidth(Text) - 3;
    else { taCenter }
      Left := ARect.Left + (ARect.Right - ARect.Left) shr 1
        - (ACanvas.TextWidth(Text) shr 1);
    end;


    SaveIndex := SaveDC(ACanvas.Handle);
    try
      Rgn := CreateRectRgnIndirect(ARect);
      try
        SelectClipRgn(ACanvas.Handle, Rgn);
        try
          SetBkMode(ACanvas.Handle, TRANSPARENT);
          ACanvas.TextOut(Left, ARect.Top + DY, Text);
        finally
          SelectClipRgn(ACanvas.Handle, 0);
        end;
      finally
        DeleteObject(Rgn);
      end;
    finally
      RestoreDC(ACanvas.Handle, SaveIndex);
    end;

  end
  else begin                  { Use FillRect and Drawtext for dithered colors }
    {$IFNDEF VER90}
    DrawBitmap.Canvas.Lock;
    {$ENDIF}
    try
      with DrawBitmap, ARect do { Use offscreen bitmap to eliminate flicker and }
      begin                     { brush origin tics in painting / scrolling.    }
        Width := MaxVal(Width, Right - Left);
        Height := MaxVal(Height, Bottom - Top);
        R := Rect(DX, DY, Right - Left - 1, Bottom - Top - 1);
        B := Rect(0, 0, Right - Left, Bottom - Top);
      end;
      with DrawBitmap.Canvas do
      begin
        Font := ACanvas.Font;
        Font.Color := ACanvas.Font.Color;
        Brush := ACanvas.Brush;
        Brush.Style := bsSolid;
        FillRect(B);
        SetBkMode(Handle, TRANSPARENT);
        {$IFDEF DELPHI4_OR_ABOVE}
        if (ACanvas.CanvasOrientation = coRightToLeft) then
          ChangeBiDiModeAlignment(Alignment);
        {$ENDIF}
        DrawText(Handle, PChar(Text), Length(Text), R,
          AlignFlags[Alignment] or RTL[ARightToLeft]);
      end;
      {$IFDEF DELPHI4_OR_ABOVE}
      if (ACanvas.CanvasOrientation = coRightToLeft) then
      begin
        Hold := ARect.Left;
        ARect.Left := ARect.Right;
        ARect.Right := Hold;
      end;
      {$ENDIF}
      ACanvas.CopyRect(ARect, DrawBitmap.Canvas, B);
    finally
      {$IFNDEF VER90}
      DrawBitmap.Canvas.Unlock;
      {$ENDIF}
    end;
  end;
end;

constructor TDBCoolGrid.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  UsesBitmap;
  FCaptionColor := clInactiveCaption;
  FCaptionTextColor := clInactiveCaptionText;
  FSelColor := clHighLight;
  FExOptions := [ocNoCaption];
  ControlStyle := ControlStyle + [csSetCaption] - [csOpaque];

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

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

destructor TDBCoolGrid.Destroy;
begin
  ReleaseBitmap;
  FCoolImagesChangeLink.Free;
  if Assigned(FWallpaper) then FWallPaper.Free;
  if Assigned(FSelWallPaper) then FSelWallPaper.Free;
  if Assigned(FCaptionWallPaper) then FCaptionWallPaper.Free;
  inherited Destroy;
end;

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

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

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

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

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

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

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

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

  FCoolImages := Value;

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

  Invalidate;
end;

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

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

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

procedure TDBCoolGrid.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 TDBCoolGrid.SetCaptionColor(Value: TColor);
begin
  if FCaptionColor <> Value then
  begin
    FCaptionColor := Value;
    NCCtlChanged;
  end;
end;

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

procedure TDBCoolGrid.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 TDBCoolGrid.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 TDBCoolGrid.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 TDBCoolGrid.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 TDBCoolGrid.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;

function TDBCoolGrid.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 TDBCoolGrid.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and Assigned(FCoolImages) and (AComponent = FCoolImages) then
    CoolImages := nil;
end;

procedure TDBCoolGrid.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 TDBCoolGrid.CoolImagesChange(Sender: TObject);
begin
  NCCtlChanged;
  Invalidate;
end;

function TDBCoolGrid.TrControl: TWinControl;
var
  Index: Byte;
begin
  Result := Self;
  if FTransparencyLevel > 0 then
    for Index := 0 to Pred(FTransparencyLevel) do
      if Result.Parent <> nil then
        Result := Result.Parent else
          Break;
end;

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

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

procedure TDBCoolGrid.Scroll(Distance: Integer);
begin
  if (Distance <> 0) and (((ocPaintWallpaper in FExOptions) and IsWallpaperAssigned) or (ocPaintTransparently in FExOptions)) then
    InvalidateRectEx(Handle, ClientRect, False);
  inherited Scroll(Distance);
end;

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

function TDBCoolGrid.GetEditText(ACol, ARow: Longint): string;
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 IsWallpaperAssigned and (ocPaintWallpaper in FExOptions) then
    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
      TCoolInplaceEdit(InplaceEditor).Wallpaper.Assign(FCoolImages.Images.Items[FidWallpaper].Bitmap) else
        TCoolInplaceEdit(InplaceEditor).Wallpaper.Assign(FWallpaper);
end;

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

procedure TDBCoolGrid.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
var
  OldActive: Integer;
  Highlight: Boolean;
  Value: string;
  DrawColumn: TColumn;
begin
  if csLoading in ComponentState then
  begin
    Canvas.Brush.Color := Color;
    Canvas.FillRect(ARect);
  end else
  begin
    if ((gdFixed in AState) and (ACol - IndicatorOffset < 0)) or ((dgTitles in Options) and (ARow = 0)) then
      inherited DrawCell(ACol, ARow, ARect, AState) else
      begin
        if(dgTitles in Options) then Dec(ARow);
          Dec(ACol, IndicatorOffset);

        if (gdFixed in AState) and ([dgRowLines, dgColLines] * Options = [dgRowLines, dgColLines]) then
          InflateRect(ARect, -1, -1);

        with Canvas do
        begin
          DrawColumn := Columns[ACol];
          Font := DrawColumn.Font;

          if ((gdSelected in AState) or (gdFocused in AState)) and (Focused or (dgAlwaysShowSelection in Options))  then
          begin
            Brush.Color := FSelColor;
            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 else
          begin
            Brush.Color := Color;
            if (ocPaintTransparently in FExOptions) then
              PaintBackgroundEx(TrControl, Handle, ARect, True) else
                if (ocPaintWallpaper in FExOptions) and IsWallpaperAssigned then
                  CTLDrawWallpaperEx(Handle, ClientRect, ARect, (ocStretchWallpaper in FExOptions), SRCCOPY) else
                  begin
                    Brush.Color := DrawColumn.Color;
                    FillRect(ARect);
                  end;
          end;

          if (DataLink = nil) or not DataLink.Active then
            FillRect(ARect) else
            begin
              Value := '';
              OldActive := DataLink.ActiveRecord;
              try
                DataLink.ActiveRecord := ARow;
                if Assigned(DrawColumn.Field) then
                  Value := DrawColumn.Field.DisplayText;

                Highlight := HighlightCell(ACol, ARow, Value, AState);
                if Highlight then
                begin
                  Brush.Color := FSelColor;
                  Font.Color := clHighlightText;
                end;
                if DefaultDrawing then
                  WriteText(Canvas, ARect, 2, 2, Value, DrawColumn.Alignment,
                        {$IFDEF DELPHI4_OR_ABOVE}UseRightToLeftAlignmentForField(DrawColumn.Field, DrawColumn.Alignment){$ELSE}False{$ENDIF});

                if Columns.State = csDefault then
                  DrawDataCell(ARect, DrawColumn.Field, AState);

                DrawColumnCell(ARect, ACol, DrawColumn, AState);
              finally
                DataLink.ActiveRecord := OldActive;
              end;
              if DefaultDrawing and (gdSelected in AState)
                and ((dgAlwaysShowSelection in Options) or Focused)
                and not (csDesigning in ComponentState)
                and not (dgRowSelect in Options)
                and (UpdateLock = 0)
                and (ValidParentForm(Self).ActiveControl = Self) then
                Windows.DrawFocusRect(Handle, ARect);
            end;
        end;

        if (gdFixed in AState) and ([dgRowLines, dgColLines] * Options = [dgRowLines, dgColLines]) then
        begin
          InflateRect(ARect, 1, 1);
          DrawEdge(Canvas.Handle, ARect, BDR_RAISEDINNER, BF_BOTTOMRIGHT);
          DrawEdge(Canvas.Handle, ARect, BDR_RAISEDINNER, BF_TOPLEFT);
        end;
      end;
  end;
end;

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

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

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

procedure TDBCoolGrid.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 TDBCoolGrid.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 TDBCoolGrid.WMSetFocus(var Message: TWMSetFocus);
begin
  inherited;
  if (ocFlatBorder in FExOptions) then
    DrawFlatBorder(0, Self, True);
end;

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

procedure TDBCoolGrid.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 TDBCoolGrid.WMNCLButtonDblClk(var Message: TWMNCLButtonDblClk);
begin
  if Message.HitTest = Windows.htCaption then
    Message.HitTest := Windows.htNoWhere else
      inherited;
end;

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

procedure TDBCoolGrid.CMParentColorChanged(var Message: TMessage);
begin
  inherited;
  if ocPaintTransparently in FExOptions then
    MakeTransparency;
end;

procedure TDBCoolGrid.CMEnabledChanged(var Message: TMessage);
begin
  inherited;
  Invalidate;
end;

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

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

procedure TDBCoolGrid.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;

procedure TDBCoolGrid.MakeTransparency;
begin
  Invalidate;
end;

{$IFDEF DELPHI4_OR_ABOVE}
{TDBCoolLookupListBox}
constructor TDBCoolLookupListBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  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;

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

  FOptions := [];
  FEdgeBorders := [];

  FOptions := [ocNoCaption, ocBevelOnlyIfSel];
  ControlStyle := ControlStyle + [csSetCaption] - [csOpaque];

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

destructor TDBCoolLookupListBox.Destroy;
begin
  if Assigned(FWallpaper) then FWallPaper.Free;
  if Assigned(FSelWallPaper) then FSelWallPaper.Free;
  if Assigned(FCaptionWallPaper) then FCaptionWallPaper.Free;

  FCoolImagesChangeLink.Free;
  FSelFont.Free;
  FBorderPen.Free;
  inherited Destroy;
end;

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

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

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

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

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

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

procedure TDBCoolLookupListBox.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 TDBCoolLookupListBox.SetBevelInner(Value: TPanelBevel);
begin
  if FBevelInner <> Value then
  begin
    FBevelInner := Value;
    Invalidate;
  end;
end;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

procedure TDBCoolLookupListBox.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(FCoolImages) then
    FCoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

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

  Invalidate;
  NCCtlChanged;
end;

function TDBCoolLookupListBox.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 TDBCoolLookupListBox.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 TDBCoolLookupListBox.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 TDBCoolLookupListBox.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 TDBCoolLookupListBox.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 TDBCoolLookupListBox.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 TDBCoolLookupListBox.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 TDBCoolLookupListBox.SetTransparencyLevel(Value: Byte);
begin
  if FTransparencyLevel <> Value then
  begin
    FTransparencyLevel := Value;
    Invalidate;
  end;
end;

procedure TDBCoolLookupListBox.Loaded;
begin
  inherited Loaded;
end;

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

function VarEquals(const V1, V2: Variant): Boolean;
begin
  Result := False;
  try
    Result := V1 = V2;
  except
  end;
end;

procedure TDBCoolLookupListBox.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
  I, J, W, X, TextWidth, TextHeight, LastFieldIndex: Integer;
  S: string;
  R: TRect;
  Selected: Boolean;
  Field: TField;
  AAlignment: TAlignment;
begin
  Canvas.Font := Font;
  TextWidth := Canvas.TextWidth('0');
  TextHeight := Canvas.TextHeight('0');
  LastFieldIndex := ListFields.Count - 1;

  if ColorToRGB(Color) <> ColorToRGB(clBtnFace) then
    Canvas.Pen.Color := clBtnFace else
    Canvas.Pen.Color := clBtnShadow;

  if (ocPaintTransparently in FOptions) then
    PaintBackground(TrControl(Self, FTransparencyLevel), Canvas.Handle, True) else
      if (ocPaintWallpaper in FOptions) and IsWallpaperAssigned then
        CTLDrawWallpaper(Canvas.Handle, ClientRect, (ocStretchWallpaper in FOptions), SRCCOPY);

  for I := 0 to RowCount - 1 do
  begin
    if Enabled then
      Canvas.Font.Color := Font.Color else
      Canvas.Font.Color := clGrayText;

    Canvas.Brush.Color := Color;
    Selected := False;

    R.Top := I * TextHeight;
    R.Bottom := R.Top + TextHeight;
    if ListLink.Active then
      if I < ListLink.RecordCount then
      begin
        ListLink.ActiveRecord := I;
        if not VarIsNull(KeyValue) and VarEquals(GetFieldProperty(ListLink.DataSet, Self, KeyField).Value, KeyValue) then
        begin
          Canvas.Font.Assign(FSelFont);
          Canvas.Brush.Color := FSelColor;
          Selected := True;
        end;

        R.Right := 0;
        for J := 0 to LastFieldIndex do
        begin
          Field := ListFields[J];
          if J < LastFieldIndex then
            W := Field.DisplayWidth * TextWidth + 4 else
            W := ClientWidth - R.Right;

          S := Field.DisplayText;
          X := 2;

          AAlignment := Field.Alignment;
          if UseRightToLeftAlignment then ChangeBiDiModeAlignment(AAlignment);
          case AAlignment of
            taRightJustify: X := W - Canvas.TextWidth(S) - 3;
            taCenter: X := (W - Canvas.TextWidth(S)) div 2;
          end;

          R.Left := R.Right;
          R.Right := R.Right + W;
          if SysLocale.MiddleEast then TControlCanvas(Canvas).UpdateTextFlags;

          if Selected then
          begin
            if (ocInvertWallpaperAsSelect in FOptions) and IsWallpaperAssigned then
            begin
              Canvas.Brush.Style := bsClear;
              CTLDrawWallpaperEx(Canvas.Handle, ClientRect, R, (ocStretchWallpaper in FOptions), NOTSRCCOPY);
            end else
            if (ocPaintSelWallpaper in FOptions) and IsSelWallpaperAssigned then
            begin
              Canvas.Brush.Style := bsClear;
              CTLDrawSelWallpaperEx(Canvas.Handle, ClientRect, R, True, SRCCOPY);
            end else
            begin
              Canvas.Brush.Style := bsSolid;
            end;
          end
          else
          Canvas.Brush.Style := bsClear;
        
          Canvas.TextRect(R, R.Left + X, R.Top, S);

          {$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}
            DrawEdge(Canvas.Handle, R, FInnerEdges[FBevelInner] OR FOuterEdges[FBevelOuter], BF_RECT);

          if J < LastFieldIndex then
          begin
            Canvas.MoveTo(R.Right, R.Top);
            Canvas.LineTo(R.Right, R.Bottom);
            Inc(R.Right);
            if R.Right >= ClientWidth then Break;
          end;
        end;
      end;

    R.Left := 0;
    R.Right := ClientWidth;

    if ListLink.Active and (I >= ListLink.RecordCount) then Canvas.FillRect(R);

    if Selected and (HasFocus or FPopup) then
      Canvas.DrawFocusRect(R);
  end;
  if ListLink.Active and (ListLink.RecordCount <> 0) then ListLink.ActiveRecord := ListLink.ActiveRecord;
end;

procedure TDBCoolLookupListBox.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 ocSmallCaption in FOptions then
      ExStyle := ExStyle or WS_EX_TOOLWINDOW else
        ExStyle := ExStyle and not WS_EX_TOOLWINDOW;
  end;
end;

type
  TCustomCtl = class(TCustomControl);

procedure TDBCoolLookupListBox.MouseDown(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
begin
  if Button = mbLeft then
  begin
    SearchText := '';
    if not FPopup then
    begin
      SetFocus;
      if not HasFocus then Exit;
    end;
    if CanModify then
      if ssDouble in Shift then
      begin
        if Assigned(ListLink) then
          if ListLink.ActiveRecord = Y div GetTextHeight then
            DblClick;
      end else
      begin
        MouseCapture := True;
        SelectItemAt(X, Y);
      end;
  end;
  if Assigned(OnMouseDown) then OnMouseDown(Self, Button, Shift, X, Y);
end;

procedure TDBCoolLookupListBox.SelectItemAt(X, Y: Integer);
var
  Delta: Integer;
begin
  if Assigned(ListLink) and (KeyField <> '') then
  begin
    if Y < 0 then Y := 0;
    if Y >= ClientHeight then Y := ClientHeight - 1;
    Delta := Y div GetTextHeight - ListLink.ActiveRecord;
    ListLink.DataSet.MoveBy(Delta);
    SelectKeyValue(GetFieldProperty(ListLink.DataSet, Self, KeyField).Value);;
  end;
end;

procedure TDBCoolLookupListBox.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 TDBCoolLookupListBox.WMPaint(var Message: TWMPaint);
begin
  inherited;

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

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

procedure TDBCoolLookupListBox.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 TDBCoolLookupListBox.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 TDBCoolLookupListBox.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 TDBCoolLookupListBox.WMSetFocus(var Message: TWMSetFocus);
begin
  inherited;

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

procedure TDBCoolLookupListBox.WMKillFocus(var Message: TWMKillFocus);
begin
  inherited;

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

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

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

procedure TDBCoolLookupListBox.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 TDBCoolLookupListBox.WMSetText(var Message: TMessage);
begin
  inherited;
  NCCtlChanged;
end;

{TPopupDataList}
constructor TPopupDataList.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := ControlStyle + [csNoDesignVisible, csReplicatable];
  FPopup := True;
end;

procedure TPopupDataList.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do
  begin
    Style := WS_POPUP or WS_BORDER;
    ExStyle := WS_EX_TOOLWINDOW;
    AddBiDiModeExStyle(ExStyle);
    WindowClass.Style := CS_SAVEBITS;
  end;
end;

procedure TPopupDataList.WMMouseActivate(var Message: TMessage);
begin
  Message.Result := MA_NOACTIVATE;
end;

{TDBCoolLookupComboBox}
constructor TDBCoolLookupComboBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := ControlStyle + [csReplicatable];
  Width := 145;
  Height := 0;

  FDataList := TPopupDataList.Create(Self);
  FDataList.Visible := False;
  FDataList.Parent := Self;
  FDataList.OnMouseUp := ListMouseUp;

  FButtonWidth := GetSystemMetrics(SM_CXVSCROLL);
  FDropDownRows := 7;

  FCoolImagesChangeLink := TCoolChangeLink.Create;
  FCoolImagesChangeLink.OnChange := CoolImagesChange;
  FSelColor := clHighlight;
  FSelFont := TFont.Create;
  FSelFont.Color := clHighlightText;
  FSelFont.OnChange := SelFontChange;

  FBevelInner := bvNone;
  FBevelOuter := bvNone;

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

  FOptions := [];
  FEdgeBorders := [];

  FOptions := [ocNoCaption, ocBevelOnlyIfSel];

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

destructor TDBCoolLookupComboBox.Destroy;
begin
  if Assigned(FWallpaper) then FWallPaper.Free;
  if Assigned(FSelWallPaper) then FSelWallPaper.Free;

  FCoolImagesChangeLink.Free;
  FSelFont.Free;
  FBorderPen.Free;
  inherited Destroy;
end;

procedure TDBCoolLookupComboBox.CloseUp(Accept: Boolean);
var
  ListValue: Variant;
begin
  if FListVisible then
  begin
    if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
    ListValue := FDataList.KeyValue;
    SetWindowPos(FDataList.Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
      SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
    FListVisible := False;
    FDataList.ListSource := nil;
    Invalidate;
    SearchText := '';
    if Accept and CanModify then SelectKeyValue(ListValue);
    if Assigned(FOnCloseUp) then FOnCloseUp(Self);
  end;
end;

procedure TDBCoolLookupComboBox.CMBiDiModeChanged(var Message: TMessage);
begin
  inherited;
  FDataList.BiDiMode := BiDiMode;
end;

procedure TDBCoolLookupComboBox.CMDialogKey(var Message: TCMDialogKey);
begin
  if (Message.CharCode in [VK_RETURN, VK_ESCAPE]) and FListVisible then
  begin
    CloseUp(Message.CharCode = VK_RETURN);
    Message.Result := 1;
  end else
    inherited;
end;

procedure TDBCoolLookupComboBox.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do
    if FBorderStyle = bsNone then
      Style := Style and not WS_BORDER
    else
      if NewStyleControls and Ctl3D then
        ExStyle := ExStyle or WS_EX_CLIENTEDGE
      else
        Style := Style or WS_BORDER;
end;

procedure TDBCoolLookupComboBox.DropDown;
var
  P: TPoint;
  I, Y: Integer;
  S: string;
  ADropDownAlign: TDropDownAlign;
  FListField: TField;
begin
  if not FListVisible and ListActive then
  begin
    if Assigned(FOnDropDown) then FOnDropDown(Self);
    FDataList.Color := Color;
    FDataList.Font := Font;
    if FDropDownWidth > 0 then
      FDataList.Width := FDropDownWidth else
      FDataList.Width := Width;
    FDataList.ReadOnly := not CanModify;
    if (ListLink.DataSet.RecordCount > 0) and
       (FDropDownRows > ListLink.DataSet.RecordCount) then
      FDataList.RowCount := ListLink.DataSet.RecordCount else
      FDataList.RowCount := FDropDownRows;
      FDataList.KeyField := KeyField;
    for I := 0 to ListFields.Count - 1 do
      S := S + TField(ListFields[I]).FieldName + ';';
    FDataList.ListField := S;

    if ListFields.Count = 0 then ListFields.Add(GetFieldProperty(ListLink.DataSet, Self, KeyField));
    if (ListFieldIndex >= 0) and (ListFieldIndex < ListFields.Count) then
      FListField := ListFields[ListFieldIndex] else
        FListField := ListFields[0];

    FDataList.ListFieldIndex := ListFields.IndexOf(FListField);
    FDataList.ListSource := ListLink.DataSource;
    FDataList.KeyValue := KeyValue;
    P := Parent.ClientToScreen(Point(Left, Top));
    Y := P.Y + Height;
    if Y + FDataList.Height > Screen.Height then Y := P.Y - FDataList.Height;
    ADropDownAlign := FDropDownAlign;
    { This alignment is for the ListField, not the control }
    if DBUseRightToLeftAlignment(Self, FListField) then
    begin
      if ADropDownAlign = daLeft then
        ADropDownAlign := daRight
      else if ADropDownAlign = daRight then
        ADropDownAlign := daLeft;
    end;
    case ADropDownAlign of
      daRight: Dec(P.X, FDataList.Width - Width);
      daCenter: Dec(P.X, (FDataList.Width - Width) div 2);
    end;

    /// cool begin ///
    FDataList.BevelInner := FBevelInner;
    FDataList.BevelOuter := FBevelOuter;
    FDataList.BorderPen := FBorderPen;
    FDataList.CoolImages := FCoolImages;
    FDataList.EdgeBorders := FEdgeBorders;
    FDataList.idSelWallpaper := FidSelWallpaper;
    FDataList.idWallpaper := FidWallpaper;
    FDataList.Options := FOptions;
    FDataList.SelWallpaper := FSelWallpaper;
    FDataList.SelColor := FSelColor;
    FDataList.SelFont := FSelFont;
    FDataList.TransparencyLevel := FTransparencyLevel;
    FDataList.Wallpaper := FWallpaper;
    /// cool end ///

    SetWindowPos(FDataList.Handle, HWND_TOP, P.X, Y, 0, 0,
      SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW);
    FListVisible := True;
    Repaint;
  end;
end;

procedure TDBCoolLookupComboBox.KeyDown(var Key: Word; Shift: TShiftState);
var
  Delta: Integer;
begin
  inherited KeyDown(Key, Shift);
  if ListActive and ((Key = VK_UP) or (Key = VK_DOWN)) then
    if ssAlt in Shift then
    begin
      if FListVisible then CloseUp(True) else DropDown;
      Key := 0;
    end else
      if not FListVisible then
      begin
        if not LocateKey then
          ListLink.DataSet.First
        else
        begin
          if Key = VK_UP then Delta := -1 else Delta := 1;
          ListLink.DataSet.MoveBy(Delta);
        end;
        SelectKeyValue(GetFieldProperty(ListLink.DataSet, Self, KeyField).Value);
        Key := 0;
      end;
  if (Key <> 0) and FListVisible then FDataList.KeyDown(Key, Shift);
end;

procedure TDBCoolLookupComboBox.KeyPress(var Key: Char);
begin
  inherited KeyPress(Key);
  if FListVisible then
    if Key in [#13, #27] then
      CloseUp(Key = #13)
    else
      FDataList.KeyPress(Key)
  else
    ProcessSearchKey(Key);
end;

procedure TDBCoolLookupComboBox.KeyValueChanged;
var
  FListField: TField;
begin
  if FLookupMode then
  begin
    FText := GetFieldProperty(ListLink.DataSet, Self, DataField).DisplayText;
    FAlignment := GetFieldProperty(ListLink.DataSet, Self, DataField).Alignment;
  end else
  if ListActive and LocateKey then
  begin
    if ListFields.Count = 0 then ListFields.Add(GetFieldProperty(ListLink.DataSet, Self, KeyField));
    if (ListFieldIndex >= 0) and (ListFieldIndex < ListFields.Count) then
      FListField := ListFields[ListFieldIndex] else
        FListField := ListFields[0];

    FText := FListField.DisplayText;
    FAlignment := FListField.Alignment;
  end else
  begin
    FText := '';
    FAlignment := taLeftJustify;
  end;
  Invalidate;
end;

procedure TDBCoolLookupComboBox.UpdateListFields;
begin
  inherited;
  KeyValueChanged;
end;

procedure TDBCoolLookupComboBox.ListMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbLeft then
    CloseUp(PtInRect(FDataList.ClientRect, Point(X, Y)));
end;

procedure TDBCoolLookupComboBox.MouseDown(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
begin
  if Button = mbLeft then
  begin
    if CanFocus then
      SetFocus;

    if not HasFocus then
      Exit;

    if FListVisible then CloseUp(False) else
      if ListActive then
      begin
        MouseCapture := True;
        FTracking := True;
        TrackButton(X, Y);
        DropDown;
      end;
  end;
  inherited MouseDown(Button, Shift, X, Y);
end;

procedure TDBCoolLookupComboBox.MouseMove(Shift: TShiftState; X, Y: Integer);
var
  ListPos: TPoint;
  MousePos: TSmallPoint;
begin
  if FTracking then
  begin
    TrackButton(X, Y);
    if FListVisible then
    begin
      ListPos := FDataList.ScreenToClient(ClientToScreen(Point(X, Y)));
      if PtInRect(FDataList.ClientRect, ListPos) then
      begin
        StopTracking;
        MousePos := PointToSmallPoint(ListPos);
        SendMessage(FDataList.Handle, WM_LBUTTONDOWN, 0, Integer(MousePos));
        Exit;
      end;
    end;
  end;
  inherited MouseMove(Shift, X, Y);
end;

procedure TDBCoolLookupComboBox.MouseUp(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
begin
  StopTracking;
  inherited MouseUp(Button, Shift, X, Y);
end;

procedure TDBCoolLookupComboBox.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
  W, X, Flags: Integer;
  Text: string;
  AAlignment: TAlignment;
  Selected: Boolean;
  R: TRect;
  FDataField: TField;
begin
  Canvas.Font := Font;
  Canvas.Brush.Color := Color;
  Selected := HasFocus and not FListVisible and
    not (csPaintCopy in ControlState);

  if (ocPaintTransparently in FOptions) then
    PaintBackground(TrControl(Self, FTransparencyLevel), Canvas.Handle, True) else
      if (ocPaintWallpaper in FOptions) and IsWallpaperAssigned then
        CTLDrawWallpaper(Canvas.Handle, ClientRect, (ocStretchWallpaper in FOptions), SRCCOPY);

  if Enabled then
    Canvas.Font.Color := Font.Color
  else
    Canvas.Font.Color := clGrayText;

  if Selected and Focused then
  begin
    Canvas.Font.Color := clHighlightText;
    Canvas.Brush.Color := clHighlight;
  end;

  FDataField := nil;
  if ListLink.Active and (DataField <> '') then
    FDataField := GetFieldProperty(ListLink.DataSet, Self, DataField);

  if (csPaintCopy in ControlState) and (FDataField <> nil) and
    (FDataField.Lookup) then
  begin
    Text := FDataField.DisplayText;
    AAlignment := FDataField.Alignment;
  end else
  begin
    if (csDesigning in ComponentState) and (FDataField = nil) then
      Text := Name else
      Text := FText;
    AAlignment := FAlignment;
  end;
  if UseRightToLeftAlignment then ChangeBiDiModeAlignment(AAlignment);
  W := ClientWidth - FButtonWidth;
  X := 2;
  case AAlignment of
    taRightJustify: X := W - Canvas.TextWidth(Text) - 3;
    taCenter: X := (W - Canvas.TextWidth(Text)) div 2;
  end;
  SetRect(R, 1, 1, W - 1, ClientHeight - 1);
  if (SysLocale.MiddleEast) and (BiDiMode = bdRightToLeft) then
  begin
    Inc(X, FButtonWidth);
    Inc(R.Left, FButtonWidth);
    R.Right := ClientWidth;
  end;
  if SysLocale.MiddleEast then TControlCanvas(Canvas).UpdateTextFlags;

  if Selected then
  begin
    if (ocInvertWallpaperAsSelect in FOptions) and IsWallpaperAssigned then
    begin
      Canvas.Brush.Style := bsClear;
      CTLDrawWallpaperEx(Canvas.Handle, ClientRect, R, (ocStretchWallpaper in FOptions), NOTSRCCOPY);
    end else
    if (ocPaintSelWallpaper in FOptions) and IsSelWallpaperAssigned then
    begin
      Canvas.Brush.Style := bsClear;
      CTLDrawSelWallpaperEx(Canvas.Handle, ClientRect, R, True, SRCCOPY);
    end else
    begin
      Canvas.Brush.Style := bsSolid;
    end;
  end
  else
  Canvas.Brush.Style := bsClear;

  Canvas.TextRect(R, X, 2, Text);

  {$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}
    DrawEdge(Canvas.Handle, R, FInnerEdges[FBevelInner] OR FOuterEdges[FBevelOuter], BF_RECT);

  if Selected then Canvas.DrawFocusRect(R);
  SetRect(R, W, 0, ClientWidth, ClientHeight);
  if (SysLocale.MiddleEast) and (BiDiMode = bdRightToLeft) then
  begin
    R.Left := 0;
    R.Right:= FButtonWidth;
  end;
  if not ListActive then
    Flags := DFCS_SCROLLCOMBOBOX or DFCS_INACTIVE
  else if FPressed then
    Flags := DFCS_SCROLLCOMBOBOX or DFCS_FLAT or DFCS_PUSHED
  else
    Flags := DFCS_SCROLLCOMBOBOX;
  DrawFrameControl(Canvas.Handle, R, DFC_SCROLL, Flags);
end;

procedure TDBCoolLookupComboBox.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
  inherited SetBounds(ALeft, ATop, AWidth, GetTextHeight + GetBorderSize + 4);
end;

function TDBCoolLookupComboBox.UseRightToLeftAlignment: Boolean;
begin
  Result := DBUseRightToLeftAlignment(Self, Field);
end;

procedure TDBCoolLookupComboBox.StopTracking;
begin
  if FTracking then
  begin
    TrackButton(-1, -1);
    FTracking := False;
    MouseCapture := False;
  end;
end;

procedure TDBCoolLookupComboBox.TrackButton(X, Y: Integer);
var
  NewState: Boolean;
begin
  NewState := PtInRect(Rect(ClientWidth - FButtonWidth, 0, ClientWidth,
    ClientHeight), Point(X, Y));
  if FPressed <> NewState then
  begin
    FPressed := NewState;
    Repaint;
  end;
end;

procedure TDBCoolLookupComboBox.CMCancelMode(var Message: TCMCancelMode);
begin
  if (Message.Sender <> Self) and (Message.Sender <> FDataList) then
    CloseUp(False);
end;

procedure TDBCoolLookupComboBox.CMCtl3DChanged(var Message: TMessage);
begin
  if NewStyleControls then
  begin
    RecreateWnd;
    Height := 0;
  end;
  inherited;
end;

procedure TDBCoolLookupComboBox.CMFontChanged(var Message: TMessage);
begin
  inherited;
  Height := 0;
end;

procedure TDBCoolLookupComboBox.CMGetDataLink(var Message: TMessage);
begin
  inherited;
end;

procedure TDBCoolLookupComboBox.WMCancelMode(var Message: TMessage);
begin
  StopTracking;
  inherited;
end;

procedure TDBCoolLookupComboBox.WMKillFocus(var Message: TWMKillFocus);
begin
  inherited;
  CloseUp(False);

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

function TDBCoolLookupComboBox.ExecuteAction(Action: TBasicAction): Boolean;
begin
  Result := inherited ExecuteAction(Action);
end;

function TDBCoolLookupComboBox.UpdateAction(Action: TBasicAction): Boolean;
begin
  Result := inherited UpdateAction(Action);
end;

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

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

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

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

procedure TDBCoolLookupComboBox.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 TDBCoolLookupComboBox.SetBevelInner(Value: TPanelBevel);
begin
  if FBevelInner <> Value then
  begin
    FBevelInner := Value;
    Invalidate;
  end;
end;

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

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

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

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

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

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

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

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

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

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

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

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

procedure TDBCoolLookupComboBox.SetCoolImages(Value: TCoolImages);
begin
  if Assigned(FCoolImages) then
    FCoolImages.UnRegisterChanges(FCoolImagesChangeLink);

  FCoolImages := Value;

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

  Invalidate;
end;

function TDBCoolLookupComboBox.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 TDBCoolLookupComboBox.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 TDBCoolLookupComboBox.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 TDBCoolLookupComboBox.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 TDBCoolLookupComboBox.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 TDBCoolLookupComboBox.SetTransparencyLevel(Value: Byte);
begin
  if FTransparencyLevel <> Value then
  begin
    FTransparencyLevel := Value;
    Invalidate;
  end;
end;

procedure TDBCoolLookupComboBox.Loaded;
begin
  inherited Loaded;
end;

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

procedure TDBCoolLookupComboBox.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 TDBCoolLookupComboBox.WMPaint(var Message: TWMPaint);
var
  Canvas: TControlCanvas;
  R: TRect;
begin
  inherited;

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

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

procedure TDBCoolLookupComboBox.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 TDBCoolLookupComboBox.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 TDBCoolLookupComboBox.WMSetFocus(var Message: TWMSetFocus);
begin
  inherited;

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

procedure TDBCoolLookupComboBox.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 TDBCoolLookupComboBox.WMSetText(var Message: TMessage);
begin
  inherited;
end;
{$ENDIF}

end.
