fccombo.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:56k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {
  2. //
  3. // Components : TfcCustomCombo
  4. //
  5. // Copyright (c) 2001 by Woll2Woll Software
  6. //
  7. // Changes:
  8. // 3/23/99 - PYW - Need to automatically set datasource when dropping control
  9. //                   in a TDBCtrlGrid.
  10. // 3/25/99 -PYW - Make sure handle is allocated when setCaret is called.
  11. // 6/6/99 - RSW - Close this modal form upon escape or return
  12. // 6/22/99 - RSW - Use HWND_TOPMOST for drop-down control only for formstyle=fsStayOnTop
  13. // 6/28/99 - Support unbound csPaintCopy
  14. // 7/4/99 - Support TCustomGrid instead of just TwwDBGrid
  15. // 9/15/99 - Make sure handle is for me in hook
  16. // 1/28/2000 - Fix bitmap glyph paint problem when flat or transparent
  17. // 8/16/2000 - Fire dropdown also if screen.activecontrol is me.  When TWebBrowser has
  18. //             focus, the dropdown button was not working.
  19. // 6/3/2001 - PYW - MDI Child forms would not get activated prior to setting focus by clicking on button.
  20. // 10/1/2001 - Added for OnMouseEnter and OnMouseLeave events. -PYW
  21. }
  22. unit fcCombo;
  23. interface
  24. {$i fcIfDef.pas}
  25. {$R-}
  26. uses
  27.   Forms, Menus, SysUtils, Windows, Graphics, Messages, Classes,
  28.   Controls, Buttons, Mask, StdCtrls, fcCommon, TypInfo, Dialogs, Grids,
  29.   DB, DBCtrls, fcframe, fccombobutton;
  30. type
  31.   TfcComboButtonStyle = (cbsEllipsis, cbsDownArrow, cbsCustom);
  32. //  TfcComboButtonStyle = (cbsEllipsis, cbsDownArrow);
  33.   TfcComboStyle = (csDropDown, csDropDownList);
  34.   TfcAlignVertical = (fcavTop, fcavCenter);
  35.   TfcComboCloseUpEvent = procedure(Sender: TObject; Select: boolean) of object;
  36.   TfcDropDownButton = class(TfcComboButton)
  37.   private
  38.     procedure CMDesignHitTest(var Message: TCMDesignHitTest); message CM_DESIGNHITTEST;
  39.   protected
  40.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  41.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  42.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  43.     procedure Paint; override;
  44.   end;
  45.   TfcCustomCombo = class(TCustomEdit)
  46.   private
  47.     FController: TComponent;
  48.     FAlignmentVertical: TfcAlignVertical;
  49.     FBtnParent: TWinControl;
  50.     FButton: TfcDropDownButton;
  51.     FDataLink: TFieldDataLink;
  52.     FDropDownCount: Integer;
  53.     FInfoPower: Boolean;
  54.     FOnCustomDlg: TNotifyevent;
  55.     FOnCloseUp: TfcComboCloseUpEvent;
  56.     FOnDropDown: TNotifyEvent;
  57.     FOnAfterDropDown: TNotifyEvent;
  58.     FButtonStyle: TfcComboButtonStyle;
  59. //    FButtonGlyph: TBitmap;
  60.     FButtonWidth: integer;
  61.     FCanvas, FPaintCanvas: TControlCanvas;
  62.     FStyle: TfcComboStyle;
  63.     FReadOnly: boolean;
  64.     FAllowClearKey: boolean;
  65.     FOnMouseEnter: TNotifyEvent;
  66.     FOnMouseLeave: TNotifyEvent;
  67.     FFrame: TfcEditFrame;
  68.     FButtonEffects: TfcButtonEffects;
  69.     FSavedCursor: TCursor;
  70.     FIgnoreCursorChange: Boolean;
  71.     skipUpdate: boolean;
  72.     FMouseInButtonControl: boolean;
  73.     FDisableThemes: boolean;
  74.     // Message Handlers
  75.     procedure WMSetFont(var Message: TWMSetFont); message WM_SETFONT;
  76.     procedure CMCancelMode(var Message: TCMCancelMode); message CM_CANCELMODE;
  77.     procedure CMCursorChanged(var Message: TMessage); message CM_CURSORCHANGED;
  78.     procedure CMEnter(var Message: TCMEnter); message CM_ENTER;
  79.     procedure CMExit(var Message: TCMExit); message CM_EXIT;
  80.     procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
  81.     procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
  82.     procedure CMGetDataLink(var Message: TMessage); message CM_GETDATALINK;
  83.     procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
  84.     procedure CNKeyDown(var Message: TWMKeyDown); message CN_KEYDOWN;
  85.     procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
  86.     procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
  87.     procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  88.     procedure WMSize(var Message: TWMSize); message WM_SIZE;
  89.     procedure WMCut(var Message: TMessage); message WM_CUT;
  90.     procedure WMPaste(var Message: TMessage); message WM_PASTE;
  91.     procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBkgnd;
  92.     procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
  93.     procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  94.     // Property Access Methods
  95.     procedure SetController(Value: TComponent);
  96.     function GetDataField: string;
  97.     function GetDataSource: TDataSource;
  98.     function GetReadOnly: Boolean;
  99.     procedure SetButtonStyle(Value: TfcComboButtonStyle);
  100.     Function GetButtonGlyph: TBitmap;
  101.     procedure SetButtonGlyph(Value: TBitmap);
  102.     Procedure SetButtonWidth(val: integer);
  103.     function GetButtonWidth: integer;
  104.     procedure SetDataField(Value: string);
  105.     procedure SetDataSource(Value: TDataSource);
  106.     procedure SetReadOnly(Value: Boolean);
  107.     procedure SetStyle(Value: TfcComboStyle);
  108.     procedure SetAlignmentVertical(Value: TfcAlignVertical);
  109.     procedure SetFocused(Value: Boolean);
  110.   protected
  111.     FFocused: Boolean;
  112. //    Function LoadComboGlyph: HBitmap; virtual;
  113.     Procedure UpdateButtonGlyph;
  114.     procedure SetDropDownCount(Value: Integer); virtual;
  115.     function GetDropDownControl: TWinControl; virtual; abstract;
  116.     function GetDropDownContainer: TWinControl; virtual; abstract;
  117.     function GetItemCount: Integer; virtual; abstract;
  118.     function GetItemSize: TSize; virtual; abstract;
  119.     function GetLeftIndent: Integer; virtual;
  120.     procedure BtnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
  121.       X, Y: Integer); virtual;
  122.     procedure DrawButton(Canvas: TCanvas; R: TRect; State: TButtonState;
  123.     ControlState: TControlState; var DefaultPaint:boolean); virtual;
  124.     procedure HideCaret; virtual;
  125.     procedure Paint; virtual;
  126.     procedure ShowCaret; virtual;
  127. //    procedure GlyphChanged(Sender: TObject); virtual;
  128.     // Virtual Property Access Methods
  129.     function GetShowButton: Boolean; virtual;
  130.     procedure SetModified(Value: Boolean); virtual;
  131.     procedure SetShowButton(Value: Boolean);
  132.     // Virtual Methods
  133.     function Editable: Boolean; virtual;
  134.     function EditCanModify: Boolean; virtual;
  135.     function GetClientEditRect: TRect; virtual;
  136.     function GetEditRect: TRect; virtual;
  137.     function GetIconIndent: Integer; virtual;
  138.     function GetIconLeft: Integer; virtual;
  139.     procedure DoDropDown; virtual;
  140.     procedure DoAfterDropDown; virtual;
  141.     procedure CloseUp(Accept: Boolean); virtual;
  142.     procedure DataChange(Sender: TObject); virtual;
  143.     procedure EditingChange(Sender: TObject); virtual;
  144.     procedure HandleDropDownKeys(var Key: Word; Shift: TShiftState); virtual;
  145.     procedure HandleGridKeys(var Key: Word; Shift: TShiftState); virtual;
  146.     procedure Reset; virtual;
  147.     procedure SetEditRect; virtual;
  148.     procedure UpdateButtonPosition; virtual;
  149.     procedure UpdateData(Sender: TObject); virtual;
  150.     function EffectiveReadOnly: Boolean; virtual;
  151.     procedure DoCloseUp(Accept: boolean); virtual;
  152.     procedure DoEnter; override;
  153.     function SkipInheritedPaint : boolean; virtual;
  154.     function GetRightIndent(Rect:TRect): Integer; virtual;
  155.     function GetTopIndent: Integer; virtual;
  156.     // Overridden Methods
  157.     procedure Change; override;
  158.     procedure CreateParams(var Params: TCreateParams); override;
  159.     procedure CreateWnd; override;
  160.     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  161.     procedure KeyPress(var Key: Char); override;
  162.     procedure Loaded; override;
  163.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  164.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  165.     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  166.     procedure WndProc(var Message: TMessage); override;
  167.     procedure PaintToCanvas(Canvas: TCanvas; Rect: TRect; Highlight, GridPaint: Boolean;
  168.       Text: string); virtual; abstract;
  169.     procedure DrawFrame(Canvas: TCanvas); virtual;
  170.     function IsCustom: Boolean; virtual;
  171.     procedure InvalidateTransparentButton;
  172.     procedure DoMouseEnter; virtual;
  173.     procedure DoMouseLeave; virtual;
  174.     property Canvas: TControlCanvas read FCanvas;
  175.     property DataLink: TFieldDataLink read FDataLink;
  176.     property DropDownContainer: TWinControl read GetDropDownContainer;
  177.     property BtnParent: TWinControl read FBtnParent;
  178.   public
  179.     ComboPatch: Variant;
  180.     property Controller : TComponent read FController write SetController;
  181.     constructor Create(AOwner:tcomponent); override;
  182.     destructor Destroy; override;
  183.     function isTransparentEffective: boolean;
  184.     procedure SelectAll; virtual;
  185.     function IsDataBound: Boolean; virtual;
  186.     function IsDroppedDown: Boolean; virtual;
  187.     procedure CheckCancelMode; virtual;
  188.     procedure DrawInGridCell(ACanvas: TCanvas; Rect: TRect;
  189.       State: TGridDrawState); virtual;
  190.     procedure DropDown; virtual;
  191.     property AlignmentVertical: TfcAlignVertical read FAlignmentVertical write SetAlignmentVertical default fcavTop;
  192.     property AllowClearKey: boolean read FAllowClearKey write FAllowClearKey default False;
  193.     property Button: TfcDropDownButton read FButton;
  194.     property ButtonStyle: TfcComboButtonStyle read FButtonStyle write SetButtonStyle;
  195.     property ButtonGlyph: TBitmap read GetButtonGlyph write SetButtonGlyph stored IsCustom;
  196.     property ButtonWidth: integer read GetButtonWidth write SetButtonWidth default 0;
  197.     property DataField: string read GetDataField write SetDataField;
  198.     property DataSource: TDataSource read GetDataSource write SetDataSource;
  199.     property DropDownCount: Integer read FDropDownCount write SetDropDownCount;
  200.     property DropDownControl: TWinControl read GetDropDownControl;
  201.     property InfoPower: Boolean read FInfoPower;
  202.     property ItemCount: Integer read GetItemCount;
  203.     property ItemSize: TSize read GetItemSize;
  204.     property ReadOnly: Boolean read GetReadOnly write SetReadOnly;
  205.     property ShowButton: boolean read GetShowButton write SetShowButton default True;
  206.     property Style: TfcComboStyle read FStyle write SetStyle;
  207.     property OnCustomDlg: TNotifyevent read FOnCustomDlg write FOnCustomDlg;
  208.     property OnCloseUp: TfcComboCloseUpEvent read FOnCloseUp write FOnCloseUp;
  209.     property OnDropDown: TNotifyEvent read FOnDropDown write FOnDropDown;
  210.     property OnAfterDropDown: TNotifyEvent read FOnAfterDropDown write FOnAfterDropDown;
  211.     property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
  212.     property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  213.     property Frame: TfcEditFrame read FFrame write FFrame;
  214.     property ButtonEffects: TfcButtonEffects read FButtonEffects write FButtonEffects;
  215.     property DisableThemes : boolean read FDisableThemes write FDisableThemes default False;
  216.   end;
  217.   function fcGetControlInGrid(Form: TComponent; Grid: TComponent; FieldName: string): TfcCustomCombo;
  218. implementation
  219. //uses uxtheme, tmschema;
  220.   {$ifdef fcDelphi7Up}
  221.   uses Themes;
  222.   {$endif}
  223.   {$ifdef ThemeManager}
  224.   uses thememgr, themesrv, uxtheme;
  225.   {$endif}
  226. type
  227.   TCheatGridCast = class(TCustomGrid);
  228.   TBtnWinControl = class(TWinControl)
  229.   private
  230.     EditControl: TfcCustomCombo;
  231.     procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBkgnd;
  232.     procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  233.   public
  234.     constructor Create(AOwner: TComponent); override;
  235.   end;
  236. var fcCOMBOHOOK: HHOOK = 0;
  237.     WM_FC_CALLDROPDOWN: UINT = 0;
  238. {$ifndef fcDelphi4Up}
  239. function fcIsInwwObjectView(control: TWinControl):boolean;
  240. begin
  241.   result := False;
  242. end;
  243. function fcIsInwwObjectViewPaint(control: TWinControl):boolean;
  244. begin
  245.   result := False;
  246. end;
  247. {$endif}
  248. function fcGetControlInGrid(Form: TComponent; Grid: TComponent; FieldName: string): TfcCustomCombo;
  249. var i: Integer;
  250.     ControlType: TStrings;
  251.     AComponent: TComponent;
  252. begin
  253.   if not Boolean(fcGetOrdProp(Grid, 'ControlInfoInDataSet')) then
  254.     ControlType := TStrings(fcGetOrdProp(Grid, 'ControlType'))
  255.   else ControlType := TStrings(fcGetOrdProp(TDataSource(fcGetOrdProp(Grid, 'DataSource')).DataSet, 'ControlType'));
  256.   result := nil;
  257.   for i := 0 to ControlType.Count - 1 do
  258.   begin
  259.     if (fcGetToken(ControlType[i], ';', 0) = FieldName) then
  260.     begin
  261.       AComponent := Form.FindComponent(fcGetToken(ControlType[i], ';', 2));
  262.       if AComponent is TfcCustomCombo then
  263.          result := AComponent as TfcCustomCombo;
  264.       Break;
  265.     end;
  266.   end;
  267. end;
  268. { 9/28/99 - Change made 9/15/99 causes side effect of combo not clsing when dragging form's caption }
  269. { Logic changed }
  270. function fcComboHookProc(nCode: Integer; wParam: Integer; lParam: Integer): LResult; stdcall;
  271. var r1, r2: TRect;
  272.     CurHandle: HWND;
  273.     parentForm: TCustomForm;
  274. begin
  275.   result := CallNextHookEx(fcCOMBOHOOK, nCode, wParam, lParam);
  276.   with PMouseHookStruct(lParam)^ do
  277.   begin
  278.     case wParam of
  279.       WM_LBUTTONDOWN, WM_NCLBUTTONDOWN, WM_MOUSEMOVE, WM_LBUTTONUP:
  280.       begin
  281.         if (Screen.ActiveControl <> nil) and (Screen.ActiveControl is TfcCustomCombo) then
  282.           with (Screen.ActiveControl as TfcCustomCombo) do
  283.         begin
  284.           // Auto-closeup if clicked outside of drop-down area
  285.           // 9/15/99 - Make sure handle is for me }
  286.           if IsDroppedDown {and (hwnd = DropDownControl.Handle) }then
  287.           begin
  288.             GetWindowRect(DropDownControl.Handle, r1);
  289.             if (wParam = WM_LBUTTONDOWN) or (wParam = WM_NCLBUTTONDOWN) then
  290.             begin
  291.               GetWindowRect(Handle, r2);
  292. //              if (not PtInRect(r1, pt)) and (not PtInRect(r2, pt)) then CloseUp(False);
  293.               with r1 do
  294.               begin
  295.                 Right := Left + DropDownControl.Width;
  296.                 Bottom := Top + DropDownControl.Height;
  297.               end;
  298.               CurHandle := Handle;
  299.               if wParam = WM_LBUTTONDOWN then CurHandle := DropDownControl.Handle;
  300.               parentForm:= GetParentForm(Screen.ActiveControl);
  301.               if ((parentForm<>nil) and (parentForm.Handle=hwnd)) or
  302.                  (GetParent(hwnd)<>0) then
  303.               begin
  304.                  if not PtInRect(r1, pt) then with DropDownControl.ScreenToClient(Point(pt.x, pt.y)) do
  305.                    PostMessage(CurHandle, wParam, 0, MakeLParam(WORD(fcThisThat(x >= 0, x, -1)),WORD(fcThisThat(y >= 0, y, -1))));
  306.               end
  307.             end else if (hwnd = DropDownControl.handle) and
  308.               ((wParam = WM_MOUSEMOVE) or (wParam = WM_LBUTTONUP)) then
  309.             begin
  310.                if not PtInRect(r1, pt) then with DropDownControl.ScreenToClient(Point(pt.x, pt.y)) do
  311.                   PostMessage(DropDownControl.Handle, wParam, 0, MakeLParam(WORD(fcThisThat(x >= 0, x, -1)),WORD(fcThisThat(y >= 0, y, -1))));
  312.             end
  313.           end
  314.         end;
  315.       end;
  316.     end;
  317.   end;
  318. end;
  319. procedure TfcDropDownButton.CMDesignHitTest(var Message: TCMDesignHitTest);
  320. begin
  321.   inherited;
  322. //  Message.Result := 1;
  323. end;
  324. procedure TfcDropDownButton.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  325. begin
  326. //  TfcCustomCombo(Owner).FDroppingDown := True;
  327.   inherited;
  328. end;
  329. procedure TfcDropDownButton.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  330. begin
  331.   inherited;
  332.   TfcCustomCombo(parent.parent).InvalidateTransparentButton; { 1/28/2000 }
  333. //  TfcCustomCombo(Owner).FDroppingDown := False;
  334. end;
  335. procedure TfcDropDownButton.MouseMove(Shift: TShiftState; X, Y: Integer);
  336. begin
  337.   inherited;
  338.   if not PtInRect(Clientrect, Point(x, y)) then
  339.   begin
  340.     Perform(WM_LBUTTONUP, 0, MAKELPARAM(x, y));
  341.     ReleaseCapture;
  342.   end;
  343. end;
  344. procedure TfcDropDownButton.Paint;
  345. var R : TRect;
  346.     DefaultPaint:boolean;
  347. begin
  348.   if TfcCustomCombo(parent.parent).SkipUpdate then exit;
  349.   if (csPaintCopy in ControlState) and
  350.       not (csDesigning in ComponentState) and fcIsInGrid(parent.parent) then exit;
  351.   SetRect(R, 0, 0, ClientWidth, ClientHeight);
  352.    with TfcCustomCombo(Parent.Parent) do
  353.    begin
  354.       DefaultPaint:= True;
  355.       FMouseInButtonControl:= MouseInControl;
  356.       if (FButton.Glyph.Handle=0) or MouseInControl or
  357.          FFocused or fcisClass(Parent.classType, 'TwwDBGrid') then
  358.          if not (ButtonEffects.Transparent and (ButtonStyle=cbsDownArrow)) then
  359.            if not fcUseThemes(self.parent.parent) then
  360.            begin
  361.               DrawButton(self.Canvas, R, FState, ControlState, DefaultPaint);
  362.            end;
  363. {           if not ThemeServices.ThemesEnabled then
  364.            begin
  365.               DrawButton(self.Canvas, R, FState, ControlState, DefaultPaint);
  366.            end;
  367. }
  368.       if DefaultPaint then begin
  369.          Ellipsis:= ButtonStyle = cbsEllipsis;
  370.          inherited Paint;
  371.       end;
  372.       { Draw edges if Default Paint }
  373.       if MouseInControl or (not ButtonEffects.Flat) or //FButton.Flat) or
  374.          FFocused or fcisClass(Parent.classType, 'TwwDBGrid') then
  375.       begin
  376.          if not fcUseThemes(self.parent.parent) then
  377. //         if not ThemeServices.ThemesEnabled then
  378.          begin
  379.             if FState=bsDown then
  380.                DrawEdge(self.Canvas.Handle, R, EDGE_SUNKEN, BF_RECT)
  381.             else
  382.                DrawEdge(self.Canvas.Handle, R, EDGE_RAISED, BF_RECT)
  383.          end;
  384.       end
  385.    end
  386. end;
  387. type
  388. TfcComboButtonEffects = class(TfcButtonEffects)
  389.    protected
  390.       procedure Refresh; override;
  391. end;
  392. Procedure TfcComboButtonEffects.Refresh;
  393. begin
  394.    (Control as TfcCustomCombo).Updatebuttonglyph;
  395. end;
  396. constructor TfcCustomCombo.Create;
  397. begin
  398.   inherited Create(AOwner);
  399.   ControlStyle := ControlStyle + [csReplicatable];
  400.   FCanvas := TControlCanvas.Create;
  401.   FCanvas.Control := self;
  402.   FAlignmentVertical := fcavTop;
  403.   FButtonStyle := cbsDownArrow;
  404.   FDropDownCount := 8;
  405.   FBtnParent := TBtnWinControl.Create (Self);
  406.   with FBtnParent do
  407.   begin
  408.     ControlStyle := ControlStyle + [csReplicatable];
  409.     Width := fcMax(GetSystemMetrics(SM_CXVSCROLL) + 4, 17);
  410.     Height := 17;
  411.     Visible := True;
  412.     Parent := Self;
  413.   end;
  414.   FButton := TfcDropDownButton.Create(self);
  415.   with FButton do
  416.   begin
  417.     ControlStyle := ControlStyle + [csReplicatable];
  418.     SetBounds (0, 0, FBtnParent.Width, FBtnParent.Height);
  419.     Width := fcMax(GetSystemMetrics(SM_CXVSCROLL), 15);
  420.     Parent := FBtnParent;
  421.     OnMouseDown := BtnMouseDown;
  422.   end;
  423.   FDataLink := TFieldDataLink.Create;
  424.   FDataLink.Control := self;
  425.   FDataLink.OnDataChange := DataChange;
  426.   FDataLink.OnEditingChange := EditingChange;
  427.   FDataLink.OnUpdateData := UpdateData;
  428.   FSavedCursor := crIBeam;
  429.   FFrame:= TfcEditFrame.create(self);
  430.   FButtonEffects:= TfcComboButtonEffects.create(self, FButton);
  431. //  FButton.Glyph.Handle:= LoadComboGlyph;  { Do after button effects is assigned }
  432. //
  433. //  FButtonGlyph := TBitmap.Create;
  434. //  FButtonGlyph.OnChange := GlyphChanged;
  435. end;
  436. destructor TfcCustomCombo.Destroy;
  437. begin
  438.   if fcCOMBOHOOK <> 0 then
  439.   begin
  440.     UnhookWindowsHookEx(fcCOMBOHOOK);
  441.     fcCOMBOHOOK := 0;
  442.   end;
  443.   FCanvas.Free;
  444.   FPaintCanvas.Free;
  445.   FDataLink.Free;
  446.   FDataLink:= Nil;
  447.   FFrame.Free;
  448.   FButtonEffects.Free;
  449. //  FButtonGlyph.Free;
  450.   inherited Destroy;
  451. end;
  452. function TfcCustomCombo.isTransparentEffective: boolean;
  453. begin
  454.    result:= Frame.Transparent and Frame.IsFrameEffective
  455.      and not fcIsDesigning(self)
  456. end;
  457. function TfcCustomCombo.GetIconIndent: Integer;
  458. begin
  459.   result:= FBtnParent.Width;
  460. end;
  461. function TfcCustomCombo.GetIconLeft: Integer;
  462. begin
  463.   result:= FBtnParent.Left - 1;
  464. end;
  465. function TfcCustomCombo.GetShowButton: Boolean;
  466. begin
  467.   result:= FBtnParent.Visible;
  468. end;
  469. procedure TfcCustomCombo.SetShowButton(Value: Boolean);
  470. begin
  471.   if (FBtnParent.Visible <> Value) then
  472.   begin
  473.     FBtnParent.Visible := Value;
  474.     UpdateButtonPosition;
  475.     if not (csLoading in Owner.ComponentState) then SetEditRect;
  476.     Invalidate;
  477.   end
  478. end;
  479. procedure TfcCustomCombo.DrawButton(Canvas: TCanvas; R: TRect; State: TButtonState;
  480.     ControlState: TControlState; var DefaultPaint:boolean);
  481. var Transparent: boolean;
  482. begin
  483.    if ButtonStyle=cbsCustom then exit;
  484.    DefaultPaint:= False;
  485.    Transparent:=  FButton.Flat and
  486.       (not FMouseInButtonControl) and not (FFocused);
  487.    if ButtonStyle=cbsDownArrow then
  488.       fcDrawDropDownArrow(Canvas, R, State, Enabled, ControlState)
  489.    else begin
  490.       fcDrawEllipsis(Canvas, R, State, Enabled, Transparent,
  491.          ButtonEffects.Transparent {and ButtonEffects.Flat},
  492.          ControlState)
  493.    end
  494. end;
  495. procedure TfcCustomCombo.CreateParams(var Params: TCreateParams);
  496. begin
  497.   inherited CreateParams(Params);
  498.   with Params do
  499.     Style := Style and not (ES_AUTOVSCROLL or ES_WANTRETURN) or
  500.       WS_CLIPCHILDREN or ES_MULTILINE;
  501.   if IsTransparentEffective and Frame.CreateTransparent then
  502.   begin
  503.      Params.ExStyle := Params.ExStyle or WS_EX_TRANSPARENT;
  504.   end;
  505. end;
  506. procedure TfcCustomCombo.CreateWnd;
  507. begin
  508.   inherited;
  509.   if (BorderStyle=bsNone) and AutoSize and
  510.      not (parent is TCustomGrid) then Frame.AdjustHeight;
  511.   SetEditRect;
  512.   if IsTransparentEffective then
  513.   begin
  514.     fcDisableParentClipping(Parent);
  515.   end
  516. end;
  517. function TfcCustomCombo.GetEditRect: TRect;
  518. begin
  519.   result.Bottom := ClientHeight + 1;
  520.   if ShowButton then result.Right := FBtnParent.Left - 2   //10/4/2001 - Changed from -1 to -2
  521.   else result.Right := ClientWidth - 2;
  522.   { RSW - 3/27/99 }
  523.   Result.Top := GetTopIndent;
  524.   if fcIsInwwObjectView(Self) then
  525.   begin
  526.     Result.Top:= 1;
  527.     Result.Left:=1;
  528.   end
  529.   else if (Frame.IsFrameEffective) then
  530.   begin
  531.      Frame.GetEditRectForFrame(Result);
  532.   end
  533.   else if (BorderStyle = bsNone) and fcIsInwwGrid(Self) then begin
  534.      Result.Left := 2;
  535.   end
  536.   else if (BorderStyle = bsNone) then
  537.   begin
  538.      Result.Left := 1;
  539.   end
  540.   else begin
  541.      Result.Left := 0;
  542.   end;
  543. //  if not Frame.isFrameEffective then { 11/22/99 - Don't do for frame }
  544.      inc(result.Left, GetLeftIndent);
  545. end;
  546. procedure TfcCustomCombo.SetEditRect;
  547. var r: TRect;
  548. begin
  549.   Canvas.font:= Font; { 4/14/99 }
  550.   r := GetEditRect;
  551.   SendMessage(Handle, EM_SETRECTNP, 0, LPARAM(@r));
  552. end;
  553. procedure TfcCustomCombo.UpdateButtonPosition;
  554. var offset: integer;
  555. begin
  556.   if Frame.IsFrameEffective then
  557.   begin
  558.      offset:= 2
  559.   end
  560.   else offset:= 0;
  561.   if (not NewStyleControls) or (BorderStyle = bsNone) or (not Ctl3d) then
  562.      FBtnParent.SetBounds (Width - FButton.Width - offset, offset, FButton.Width, ClientHeight-offset*2)
  563.   else
  564.      FBtnParent.SetBounds (Width - FButton.Width - 4, offset, FButton.Width, ClientHeight-offset);
  565. //  if (not NewStyleControls) or (BorderStyle = bsNone) or (not Ctl3d) then
  566. //    FBtnParent.SetBounds(Width - FButton.Width, 0, FButton.Width, ClientHeight)
  567. //  else
  568. //    FBtnParent.SetBounds(Width - FButton.Width - 4, 0, FButton.Width, ClientHeight);
  569.   if not FBtnParent.Visible and (csDesigning in ComponentState) then
  570.     FBtnParent.Left := BoundsRect.Right;
  571.   if BorderStyle = bsNone then
  572.   begin
  573.     FButton.Top := -1;
  574.     FButton.Height := FBtnParent.Height+1;
  575.   end else begin
  576.     FButton.Top:= 0;
  577.     FButton.Height := FBtnParent.Height;
  578.   end;
  579.   SetEditRect;
  580. end;
  581. function TfcCustomCombo.IsDataBound: Boolean;
  582. begin
  583.   result := (DataSource <> nil) and (DataSource.DataSet <> nil) and (DataField <> '');
  584. end;
  585. procedure TfcCustomCombo.CheckCancelMode;
  586. var p, p2: TPoint;
  587.     wndRect: TRect;
  588. begin
  589.   GetCursorPos(p);
  590.   p2 := DropDownControl.ClientToScreen(Point(0, 0));
  591.   GetWindowRect(Handle, wndRect);
  592.   with p2 do
  593.   begin
  594.     if (not PtInRect(Rect(x, y, x + DropDownControl.Width, y + DropDownControl.Height), p)) and
  595.        (not PtInRect(wndRect, p)) then CloseUp(False);
  596.   end;
  597. end;
  598. procedure TfcCustomCombo.DoCloseUp(Accept: boolean);
  599. begin
  600.    if Assigned(FOnCloseUp) then FOnCloseUp(self, Accept);
  601. end;
  602. procedure TfcCustomCombo.CloseUp(Accept: boolean);
  603. //var i: Integer;
  604. begin
  605. //  i := GetCapture; { RSW }
  606. //  if Accept then Modified := True; { RSW - Rely on parent class to set modified as we don't really know }
  607. //  if i <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
  608.   { RSW - comment out as this causes problem with button not getting mouse up }
  609.   try
  610.     SelectAll;
  611.     if IsDroppedDown then
  612.     begin
  613.       SetWindowPos(DropDownContainer.Handle, 0, 0, 0, 0, 0, SWP_NOZORDER or
  614.         SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_HIDEWINDOW);
  615.       DropDownContainer.Visible := False;
  616.       Invalidate;
  617.       if DropDownControl.Focused then SetFocus;
  618.      { RSW - Let parent class call CloseUP so that its fired after things are updated (i.e. modified flag )}
  619. //    if Assigned(FOnCloseUp) then FOnCloseUp(self, Accept);
  620.     end;
  621.     if Style = csDropDownList then HideCaret;
  622.   finally
  623.     if fcCOMBOHOOK <> 0 then
  624.     begin
  625.       UnhookWindowsHookEx(fcCOMBOHOOK);
  626.       fcCOMBOHOOK := 0;
  627.     end;
  628.   end;
  629. end;
  630. procedure TfcCustomCombo.DataChange(Sender: TObject);
  631. begin
  632.   if FDataLink.Field <> nil then
  633.   begin
  634.     if not (csDesigning in ComponentState) then
  635.     begin
  636.       if (FDataLink.Field.DataType = ftString) and (MaxLength = 0) then
  637.         MaxLength := FDataLink.Field.Size;
  638.     end;
  639.     if Focused and FDataLink.CanModify then
  640.       Text := FDataLink.Field.Text
  641.     else begin
  642.       Text := FDataLink.Field.DisplayText;
  643. { 7/31/00 - Remove setting modified as this oode sets it to true even when the control does
  644.  not have focus }
  645. //      if FDataLink.Editing then
  646. //        Modified := True;
  647.     end;
  648.   end else
  649.   begin
  650.     if csDesigning in ComponentState then
  651.       Text := Name else
  652.       Text := '';
  653.   end;
  654. end;
  655. procedure TfcCustomCombo.EditingChange(Sender: TObject);
  656. begin
  657.   inherited ReadOnly := not FDataLink.Editing;  // RSW use inherited ReadOnly
  658. end;
  659. procedure TfcCustomCombo.UpdateData(Sender: TObject);
  660. begin
  661.   if FDataLink.Field.Text <> Text then
  662.     FDataLink.Field.Text := Text;
  663. end;
  664. procedure TfcCustomCombo.DrawInGridCell(ACanvas: TCanvas; Rect: TRect;
  665.   State: TGridDrawState);
  666. begin
  667. end;
  668. procedure TfcCustomCombo.DoDropDown;
  669. begin
  670.   if Assigned(FOnDropDown) then FOnDropDown(self);
  671. end;
  672. procedure TfcCustomCombo.DoAfterDropDown;
  673. begin
  674.   if Assigned(FOnAfterDropDown) then FOnAfterDropDown(self);
  675. end;
  676. procedure TfcCustomCombo.DropDown;
  677. var p: TPoint;
  678.     NewControlSize: TSize;
  679.     Border: Integer;
  680. begin
  681.   if fcCOMBOHOOK = 0 then fcCOMBOHOOK := SetWindowsHookEx(WH_MOUSE, @fcComboHookProc, HINSTANCE, GetCurrentThreadID);
  682.   DoDropDown;
  683.   p := Parent.ClientToScreen(Point(Left, Top));
  684.   // 2/25/99 - Handle Grid Paint bug when closing up in grid
  685.   if fcIsInwwGrid(Self) then inc(p.y);
  686.   // Initialize size of DropDownControl
  687.   Border := 2 * GetSystemMetrics(SM_CYBORDER);
  688.   NewControlSize := ItemSize;
  689.   if ItemCount > 0 then NewControlSize.cy :=
  690.     fcMin(DropDownCount, ItemCount) * NewControlSize.cy
  691.   else NewControlSize.cy := Height;
  692.   inc(NewControlSize.cy, Border);
  693.   DropDownContainer.Height := NewControlSize.cy;
  694.   // 2/8/01 - Color combo too wide before
  695.   if NewControlSize.cx=0 then
  696.      NewControlSize.cx:= Width
  697.   else
  698.      NewControlSize.cx := fcMax(Width, NewControlSize.cx + Border + 2 * GetSystemMetrics(SM_CXVSCROLL));
  699.   // Adjust if near right edge of screen
  700.   if p.x > Screen.Width - NewControlSize.cx then p.x := (p.x + Width) - NewControlSize.cx;
  701.   // Adjust if near bottom of screen
  702.   if p.y + Height + NewControlSize.cy > Screen.Height{GetSystemMetrics(SM_CYFULLSCREEN)} then p.y := (p.y - Height) - NewControlSize.cy;
  703.   TEdit(DropDownContainer).Color := TEdit(DropDownControl).Color;
  704.   { 6/22/99 - Use HWND_TOPMOST only for formstyle=fsStayOnTop }
  705.   if TForm(GetParentForm(self)).formstyle = fsStayOnTop then
  706.     SetWindowPos(DropDownContainer.Handle, HWND_TOPMOST, p.x, p.y + Height, NewControlSize.cx, NewControlSize.cy,
  707.       SWP_NOACTIVATE or SWP_SHOWWINDOW)
  708.   else
  709.     SetWindowPos(DropDownContainer.Handle, HWND_TOP, p.x, p.y + Height, NewControlSize.cx, NewControlSize.cy,
  710.       SWP_NOACTIVATE or SWP_SHOWWINDOW);
  711.   DoAfterDropDown;
  712.   DropDownContainer.Visible := True;
  713.   DropDownControl.Update;
  714.   //2/25/99 - Let inherited classes do the selectall.
  715.   //  SelectAll;
  716.   ShowCaret;
  717. end;
  718. { return true if allowed to type text into control }
  719. function TfcCustomCombo.Editable: boolean;
  720. begin
  721.   result := true;
  722. //  Result := IsDroppedDown;
  723. end;
  724. procedure TfcCustomCombo.HandleDropDownKeys(var Key: Word; Shift: TShiftState);
  725. begin
  726.   case Key of
  727.     VK_F4: // Support F4 for dropping-down
  728.       if not (ssAlt in Shift) then begin
  729.         if isDroppedDown then CloseUp(True)
  730.         else DropDown;
  731.         Key := 0;
  732.       end;
  733.     VK_UP, VK_DOWN:
  734.       if ssAlt in Shift then
  735.       begin
  736.         if IsDroppedDown then CloseUp(True)
  737.         else DropDown;
  738.         Key := 0;
  739.       end;
  740.     VK_RETURN, VK_ESCAPE:
  741.       if IsDroppedDown and not (ssAlt in Shift) then
  742.       begin
  743.         CloseUp(Key = VK_RETURN);
  744.         Key := 0;
  745.       end
  746.   end;
  747. end;
  748. procedure TfcCustomCombo.Change;
  749. begin
  750.   if ((DataLink<>Nil) and (FDataLink.Field=Nil)) then Modified:= True;
  751. {  if (DataLink<>Nil) and
  752.      ((FDataLink.Field=Nil) or
  753.       (DataSource.dataset.state in [dsEdit, dsInsert])) then
  754.   begin
  755.      FDataLink.Modified;
  756.      Modified:= True;
  757.   end;}
  758.   inherited;
  759. end;
  760. function TfcCustomCombo.EditCanModify: Boolean;
  761. begin
  762.   result:= False;
  763.   if EffectiveReadOnly then exit; { RSW - otherwise CloseUP still goes into edit mode}
  764.   // Respect autoedit
  765.   if (DataSource<>Nil) and (not DataSource.autoEdit) then
  766.      if (not (DataSource.state in [dsEdit, dsInsert])) then exit;
  767.   if FDatalink.Field <> nil then result := FDataLink.Edit
  768.   else result := True;
  769. end;
  770. procedure TfcCustomCombo.HandleGridKeys(var Key: Word; Shift: TShiftState);
  771. type
  772.   TSelection = record
  773.     StartPos, EndPos: Integer;
  774.   end;
  775. var SkipGridCode: boolean;
  776.   procedure SendToObjectView;
  777.   begin
  778.      TCheatGridCast(Parent).KeyDown(Key, Shift);
  779.   end;
  780.   procedure SendToParent;
  781.   begin
  782.     Parent.setFocus;
  783.     if Parent.focused then
  784.        SendMessage(Parent.handle,wm_keydown,key,0);
  785.     Key := 0;
  786.   end;
  787.   procedure ParentEvent;
  788.   var GridKeyDown: TKeyEvent;
  789.   begin
  790.     { 1/25/99 - RSW Prevent grid's OnKeyDown from firing twice when encounter tab or cr }
  791.     if (Screen.ActiveControl<>self) and ((key=13) or (key=9)) then exit;
  792.     GridKeyDown := TEdit(Parent).OnKeyDown;
  793.     if Assigned(GridKeyDown) then GridKeyDown(Parent, Key, Shift);
  794.   end;
  795.   function Alt: Boolean;
  796.   begin
  797.     Result := ssAlt in Shift;
  798.   end;
  799.   function Ctrl: Boolean;
  800.   begin
  801.     Result := ssCtrl in Shift;
  802.   end;
  803. {  procedure Deselect;
  804.   begin
  805.     Exit;
  806.     SendMessage(Handle, EM_SETSEL, -1, 0);
  807.     selLength := 0;
  808.   end;}
  809.   function ForwardMovement: Boolean;
  810.   begin
  811.      Result := (dgAlwaysShowEditor in fcGetGridOptions(self));
  812.   end;
  813.   function Selection: TSelection;
  814.   begin
  815.     SendMessage(Handle, EM_GETSEL, Longint(@Result.StartPos), Longint(@Result.EndPos));
  816.   end;
  817.   function LeftSide: Boolean;
  818.   begin
  819. //    result := ((SelStart = 0) and (SelLength <> GetTextLen)) or (Style = csDropDownList)
  820.     with Selection do
  821.       Result := (StartPos = 0) and
  822.       ((EndPos = 0) or (EndPos = GetTextLen));
  823.   end;
  824.   function RightSide: Boolean;
  825.   begin
  826.     with Selection do
  827.       Result := ((StartPos = 0) or (EndPos = StartPos)) and
  828.         (EndPos = GetTextLen);
  829.    end;
  830.   procedure Deselect; {!!! Don't do for Treecombo}
  831.   begin
  832.     SendMessage(Handle, EM_SETSEL, -1, 0);
  833.     selLength:= 0;
  834.   end;
  835. begin
  836.   if (Key in [vk_next, vk_prior, vk_up, vk_down, vk_home, vk_end, vk_right, vk_left]) and
  837.      (IsDroppedDown) then skipGridCode:= True
  838.   else SkipGridCode:= False;
  839.   if (fcIsInwwGrid(Self)) and (not SkipGridCode) then begin
  840.     case Key of
  841.       VK_ESCAPE: if not Modified then SendToParent;
  842.       VK_NEXT, VK_PRIOR, VK_UP, VK_DOWN: if (not Alt) then SendToParent;
  843.        VK_LEFT: if fcIsInwwObjectView(self) then
  844.                 begin
  845. //                   if Ctrl or LeftSide then SendToObjectView
  846.                 end
  847.                 else if ForwardMovement and (Ctrl or LeftSide) then SendToParent;
  848.        VK_RIGHT: if fcIsInwwObjectView(self) then
  849.                  begin
  850. //                    if Ctrl or RightSide then SendToObjectView
  851.                  end
  852.                  else if ForwardMovement and (Ctrl or RightSide) then SendToParent;
  853. //      VK_LEFT: if fcIsInwwObjectView(self) then SendToObjectView
  854. //                else if ForwardMovement and (Ctrl or LeftSide) then SendToParent;
  855. //      VK_RIGHT: if fcIsInwwObjectView(self) then SendToObjectView
  856. //                 else if ForwardMovement and (Ctrl or RightSide) then SendToParent;
  857.       VK_HOME: if ForwardMovement and (Ctrl or LeftSide) then SendToParent;
  858.       //((SelStart = 0) and (SelLength <> GetTextLen)) or (Style = csDropDownList) then SendToParent;
  859.       VK_END: if ForwardMovement and (Ctrl or RightSide) then SendToParent;
  860.       //if (SelStart = GetTextLen) or (Style = csDropDownList) then SendToParent;
  861.       VK_INSERT: if not (ssShift in Shift) then SendToParent;
  862.       VK_DELETE: if Ctrl then SendToParent;
  863.       VK_F2:
  864.          begin
  865.            ParentEvent;
  866.            if Key = VK_F2 then
  867.            begin
  868.              if Editable and (Style=csDropDown) then Deselect;
  869.              Key:=0;
  870.            end;
  871.          end;
  872.     end;
  873.     if not (Editable and (Style=csDropDown)) and
  874.        (Key in [VK_LEFT, VK_RIGHT, VK_HOME, VK_END]) then
  875.        if not fcIsInwwObjectView(self) then SendToParent;
  876.     if Key <> 0 then ParentEvent;
  877.   end;
  878.   if Key = 0 then Exit;
  879.   if (ssCtrl in Shift) then
  880.   begin
  881.     inherited KeyDown(Key, Shift);
  882.      Exit;
  883.   end;
  884.   if fcIsInwwGrid(Self) and (Key = VK_TAB) then
  885.   begin
  886.     inherited KeyDown(Key, Shift);
  887.     Exit;
  888.   end;
  889.   inherited KeyDown(Key, Shift);
  890. end;
  891. procedure TfcCustomCombo.KeyDown(var Key: Word; Shift: TShiftState);
  892. begin
  893.   if GetKeyState(VK_MENU) < 0 then Include(Shift, ssAlt);
  894.   if modified and (not isDroppedDown) and (key=VK_ESCAPE) then
  895.   begin
  896.     Reset;
  897.     Key := 0;
  898.   end;
  899.   HandleDropDownKeys(Key, Shift);
  900.   HandleGridKeys(Key, Shift);
  901.   inherited KeyDown(Key, Shift);
  902.   if (Key = VK_DELETE) or ((Key = VK_INSERT) and (ssShift in Shift)) then
  903.     if not EditCanModify then
  904.        key:= 0;
  905. //    FDataLink.Edit;
  906. end;
  907. procedure TfcCustomCombo.KeyPress(var Key: Char);
  908. begin
  909.   inherited;
  910.   if EffectiveReadOnly then
  911.   begin
  912.      Key:= #0;
  913.      exit;
  914.   end;{ RSW }
  915.   case Key of
  916.     ^H, ^V, ^X, #32..#255:
  917. //      if (Style = csDropDown) or IsDroppedDown then
  918. //      if (Style = csDropDown) or isDroppedDown then
  919.       if Editable then
  920.       begin
  921.          if (not IsDroppedDown) then
  922.             if not EditCanModify then key:= #0
  923.             //FDataLink.Edit
  924.       end
  925.       else Key := #0;
  926.     #27:
  927.       begin
  928. //        Reset;  //12/11/1998 - Moved to OnKeyDown event.
  929.         Key := #0;
  930.       end;
  931.     #9, #13: if fcIsInwwGrid(Self) then Key:= #0;
  932.                                                          { 4/28/99 - Ignore tab and cr                            }
  933.                                                          { cr needs to be eaten so that parentgrid is not confused }
  934.                                                          { when using dgEnterToTab }
  935.   end;
  936. end;
  937. function TfcCustomCombo.GetClientEditRect: TRect;
  938. begin
  939.   result := ClientRect;
  940.   // 9/28/01 - Fix combo in grid problem where button area should still paint text
  941. //  if not fcIsInwwObjectViewPaint(self) and ShowButton then
  942.   if not fcIsInwwGridPaint(self) and ShowButton then
  943.      result.Right := FBtnParent.Left;
  944. end;
  945. function TfcCustomCombo.GetDataField;
  946. begin
  947.   result := FDataLink.FieldName;
  948. end;
  949. function TfcCustomCombo.GetDataSource: TDataSource;
  950. begin
  951.   if FDataLink<>nil then
  952.      result := FDataLink.DataSource
  953.   else
  954.     result:= nil;
  955. end;
  956. function TfcCustomCombo.EffectiveReadOnly: Boolean;
  957. begin
  958.   result:= FReadOnly or FDataLink.ReadOnly or {(inherited ReadOnly) or}
  959.            ((FDataLink.Field<>nil) and (not FDataLink.Field.CanModify));
  960. end;
  961. function TfcCustomCombo.GetReadOnly: Boolean;
  962. begin
  963.   result:= FReadOnly;
  964. //  if IsDataBound then result := FDataLink.ReadOnly else result := inherited ReadOnly;
  965. end;
  966. procedure TfcCustomCombo.SetButtonStyle(Value: TfcComboButtonStyle);
  967. begin
  968.   if Value <> FButtonStyle then
  969.   begin
  970.     FButtonStyle := Value;
  971.     if HandleAllocated then RecreateWnd;
  972.     FButton.Invalidate;
  973.   end
  974. end;
  975. procedure TfcCustomCombo.SetDataField(Value: string);
  976. begin
  977.   FDataLink.FieldName := Value;
  978. end;
  979. procedure TfcCustomCombo.SetDataSource(Value: TDataSource);
  980. begin
  981.   FDataLink.DataSource := Value;
  982.   if Value <> nil then Value.FreeNotification(self);
  983. end;
  984. procedure TfcCustomCombo.SetReadOnly(Value: Boolean);
  985. begin
  986. //  FDataLink.ReadOnly:= Value;
  987.   FReadOnly:= Value;
  988. {  if Style <> csDropDownList then }inherited ReadOnly := Value;
  989. //  if IsDataBound then FDataLink.ReadOnly := Value;
  990. //{  if Style <> csDropDownList then }inherited ReadOnly := Value;
  991. end;
  992. procedure TfcCustomcombo.SetStyle(Value: TfcComboStyle);
  993. begin
  994.   if FStyle <> Value then
  995.   begin
  996.     FStyle := Value;
  997.     if HandleAllocated and not (csLoading in ComponentState) then
  998.     begin
  999.       if FStyle = csDropDownList then
  1000.       begin
  1001.         inherited ReadOnly := True;  { Should be inherited Readonly, but Hidecaret already does this }
  1002.         HideCaret;
  1003.       end else begin
  1004.         ShowCaret;
  1005.       end;
  1006.     end;
  1007.   end;
  1008. end;
  1009. function TfcCustomCombo.IsDroppedDown: boolean;
  1010. begin
  1011.   result := False;
  1012. end;
  1013. procedure TfcCustomCombo.Loaded;
  1014. begin
  1015.   if FButtonWidth=0 then
  1016.      FButton.Width := fcMax(GetSystemMetrics(SM_CXVSCROLL), 15);
  1017.   if (Parent <> nil) or (Owner <> nil) then
  1018.     UpdateButtonPosition;
  1019.   inherited Loaded;
  1020. end;
  1021. procedure TfcCustomCombo.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  1022. begin
  1023.   inherited;
  1024. //  InvalidateTransparentButton;
  1025.   if Style = csDropDownList then
  1026.   begin
  1027.     if not IsDroppedDown and (Button = mbLeft) then begin
  1028.       PostMessage(Handle, WM_FC_CALLDROPDOWN, 0, 0);
  1029.       ReleaseCapture; { RSW - Capture causes cursor problems }
  1030.     end
  1031.     else CloseUp(True);
  1032.   end;
  1033. end;
  1034. procedure TfcCustomCombo.MouseMove(Shift: TShiftState; X, Y: Integer);
  1035. begin
  1036.   inherited;
  1037.   FIgnoreCursorChange := True;
  1038.   if Style = csDropDownList then {Screen.}Cursor := crArrow else Cursor := FSavedCursor;   // Change component cursor, not screen cursor. -ksw (2/12/99)
  1039.   FIgnoreCursorChange := False;
  1040. end;
  1041. procedure TfcCustomCombo.Notification(AComponent: TComponent; Operation: TOperation);
  1042. begin
  1043.   inherited;
  1044.   if (Operation = opRemove) and (AComponent = DataSource) then DataSource := nil;
  1045.   if (Operation = opRemove) and (AComponent = FController) then FController:= nil;
  1046. end;
  1047. procedure TfcCustomCombo.WndProc(var Message: TMessage);
  1048. begin
  1049.   if Message.Msg = WM_FC_CALLDROPDOWN then
  1050.     DropDown;
  1051.   case Message.Msg of
  1052.     WM_PASTE, WM_CUT, WM_KEYFIRST..WM_KEYLAST:
  1053.       if fcIsInwwGrid(self) then Change;
  1054.     WM_NCLBUTTONDOWN: CloseUp(True);
  1055.   end;
  1056.   inherited;
  1057. end;
  1058. procedure TfcCustomCombo.CMCancelMode(var Message: TCMCancelMode);
  1059. begin
  1060. //  if (Message.Sender <> Self) and (Message.Sender <> DropDownControl) then
  1061. //    CloseUp(False);
  1062. end;
  1063. procedure TfcCustomCombo.CMCursorChanged(var Message: TMessage);
  1064. begin
  1065.   inherited;
  1066.   if not FIgnoreCursorChange then FSavedCursor := Cursor;
  1067. end;
  1068. procedure TfcCustomCombo.CMEnter(var Message: TCMEnter);
  1069. var exStyle, origStyle: longint;
  1070. begin
  1071.   if AutoSelect and not (csLButtonDown in ControlState) then SelectAll;
  1072.   inherited;
  1073.   SetFocused(True);
  1074.   if ButtonEffects.Flat then FButton.invalidate;
  1075.   
  1076.   if IsTransparentEffective then begin
  1077.      Frame.CreateTransparent:= False;
  1078.      OrigStyle:= Windows.GetWindowLong(handle, GWL_EXSTYLE);
  1079.      exStyle:= OrigStyle and not WS_EX_TRANSPARENT;
  1080.      Windows.SetWindowLong(handle, GWL_EXSTYLE, exStyle);
  1081.      invalidate;
  1082.   end;
  1083.   if Frame.enabled then invalidate; { See if this causes any flicker }
  1084.   
  1085. end;
  1086. procedure TfcCustomCombo.CMEnabledChanged(var Message: TMessage);
  1087. begin
  1088.   inherited;
  1089.   FButton.Enabled := Enabled;
  1090. end;
  1091. procedure TfcCustomCombo.SetFocused(Value: Boolean);
  1092. begin
  1093.   if FFocused <> Value then
  1094.   begin
  1095.     FFocused := Value;
  1096. //    if (FAlignment <> taLeftJustify) then Invalidate;
  1097.     if FDataLink.Field<>Nil then begin
  1098.        FDataLink.Reset;
  1099.     end
  1100.   end;
  1101. end;
  1102. procedure TfcCustomCombo.CMExit(var Message: TCMExit);
  1103. var exStyle, origStyle: longint;
  1104. begin
  1105.   try
  1106.     FDataLink.UpdateRecord;
  1107.     SetFocused(False);
  1108.     if ButtonEffects.Flat then FButton.invalidate;
  1109.     if IsTransparentEffective then begin
  1110. //       Frame.CreateTransparent:= True;
  1111. //       RecreateWnd;
  1112.        { Try not recreating window by testing following code instead of IP2000 code }
  1113.        OrigStyle:= Windows.GetWindowLong(handle, GWL_EXSTYLE);
  1114.        exStyle:= OrigStyle or WS_EX_TRANSPARENT;
  1115.        Windows.SetWindowLong(handle, GWL_EXSTYLE, exStyle);
  1116.        SetEditRect;
  1117.        Frame.RefreshTransparentText(True);
  1118.     end;
  1119.     if Frame.enabled then invalidate;
  1120.   except
  1121.     SelectAll;
  1122.     SetFocus;
  1123.     raise;
  1124.   end;
  1125.   DoExit;
  1126. end;
  1127. //3/23/1999 - PYW - Need to automatically set datasource when dropping control
  1128. //                  in a TDBCtrlGrid.
  1129. procedure TfcCustomCombo.CMGetDataLink(var Message: TMessage);
  1130. begin
  1131.   Message.Result := Integer(FDataLink);
  1132. end;
  1133. procedure TfcCustomCombo.CMTextChanged(var Message: TMessage);
  1134. begin
  1135.   if IsTransparentEffective and not FFocused then
  1136.      Frame.RefreshTransparentText;
  1137.   inherited;
  1138.   if fcIsInwwGrid(self) then Change;
  1139. end;
  1140. procedure TfcCustomCombo.CMFontChanged(var Message: TMessage);
  1141. begin
  1142.   inherited;
  1143.   // This is needed only when changing font in the middle of editing
  1144.   if not (csLoading in Owner.ComponentState) then SetEditRect;
  1145. end;
  1146. procedure TfcCustomCombo.CNKeyDown(var Message: TWMKeyDown);
  1147. var ShiftState: TShiftState;
  1148. begin
  1149.   if not (csDesigning in ComponentState) then
  1150.     with Message do
  1151.     begin
  1152.        if (charcode = VK_TAB) and IsDroppedDown then Closeup(True)
  1153.        else if((charcode=vk_return) or (charcode=vk_escape)) then begin
  1154.           if IsDroppedDown then exit
  1155.           else if (not modified) or (charcode = vk_return) then { 6/6/99 - Close this modal form }
  1156.              SendMessage(GetParent(Handle), TMessage(Message).Msg,
  1157.              TMessage(Message).wParam, TMessage(Message).lParam);
  1158.        end
  1159.     end;
  1160.   if not (csDesigning in ComponentState) and fcIsInwwGrid(self) then
  1161.   begin
  1162.     with Message do
  1163.     begin
  1164.       ShiftState := KeyDataToShiftState(KeyData);
  1165.       if (charcode = VK_TAB) or (charcode = VK_RETURN) then begin
  1166.          if parent is TCustomGrid then begin
  1167.            if (charcode <> VK_TAB) or (goTabs in TCheatGridCast(parent).Options) then {7/3/97}
  1168.            begin
  1169.               parent.setFocus;
  1170.               if parent.focused then { Bug fix - Abort in validation prevents focus change }
  1171.                 TCheatGridCast(parent).KeyDown(charcode, shiftState);
  1172.               exit;
  1173.            end
  1174.          end
  1175.       end;
  1176.       if (CharCode = VK_TAB) or (CharCode = VK_RETURN) then
  1177.       begin
  1178.         if fcIsInwwGrid(self) then
  1179.         begin
  1180.           if (CharCode <> VK_TAB) or (dgTabs in (fcGetGridOptions(self))) then
  1181.           begin
  1182.             Parent.SetFocus;
  1183.             if Parent.Focused then
  1184.               SendMessage(Parent.Handle, WM_KEYDOWN, CharCode, 0);
  1185.             Exit;
  1186.           end
  1187.         end
  1188.       end
  1189.     end
  1190.   end;
  1191.   inherited;
  1192. end;
  1193. function TfcCustomCombo.SkipInheritedPaint : boolean;
  1194. begin
  1195.   result := False;
  1196. end;
  1197. procedure TfcCustomCombo.WMPaint(var Message: TWMPaint);
  1198. var r: TRect;
  1199.     DC: HDC;
  1200.     PS: TPaintStruct;
  1201.   procedure CanvasNeeded;
  1202.   begin
  1203.     if FCanvas = nil then
  1204.     begin
  1205.       FCanvas := TControlCanvas.Create;
  1206.       FCanvas.Control := Self;
  1207.     end;
  1208.   end;
  1209. begin
  1210.   if ((Frame.enabled or SkipInheritedPaint) and (not FFocused)) or
  1211.      (csPaintCopy in ControlState) then
  1212.   begin
  1213.      // 6/28/99 - Support unbound csPaintCopy }
  1214.       { if not editable with focus, need to do drawing to show proper focus }
  1215.       try
  1216.          if FPaintCanvas = nil then
  1217.          begin
  1218.             FPaintCanvas := TControlCanvas.Create;
  1219.             FPaintCanvas.Control := Self;
  1220.          end;
  1221.          CanvasNeeded;
  1222.          if Message.DC = 0 then DC := BeginPaint(Handle, PS)
  1223.          else DC:= Message.DC;
  1224.          FPaintCanvas.Handle := DC;
  1225.          if FDataLink.Field=nil then
  1226.             PaintToCanvas(FPaintCanvas, GetClientEditRect, True, False,
  1227.                Text)
  1228.          else
  1229.             PaintToCanvas(FPaintCanvas, GetClientEditRect, True, False,
  1230.                FDataLink.Field.asString);
  1231.         if Frame.IsFrameEffective then
  1232.         begin
  1233.           DrawFrame(FPaintCanvas);
  1234.         end;
  1235.       finally
  1236.          FPaintCanvas.Handle := 0;
  1237.          if Message.DC = 0 then EndPaint(Handle, PS);
  1238.       end;
  1239.   end
  1240.   else begin
  1241.      inherited;
  1242.      Paint;
  1243.      if Frame.IsFrameEffective then
  1244.      begin
  1245.        CanvasNeeded;
  1246.        FCanvas.Handle:= message.DC;
  1247.        DrawFrame(FCanvas);
  1248.        FCanvas.Handle:= 0;
  1249.      end;
  1250.   end;
  1251.   r := FBtnParent.ClientRect;
  1252.   InvalidateRect(FBtnParent.Handle, @r, False);
  1253. end;
  1254. procedure TfcCustomCombo.WMSize(var Message: TWMSize);
  1255. begin
  1256.   inherited;
  1257.   UpdateButtonPosition;
  1258.   SetEditRect;
  1259. end;
  1260. procedure TfcCustomCombo.WMKillFocus(var Message: TWMKillFocus);
  1261. begin
  1262.   inherited;
  1263.   if (DropdownContainer<>nil) and
  1264.      DropDownContainer.HandleAllocated and (Message.FocusedWnd <> DropDownContainer.Handle) then
  1265.     CloseUp(True);
  1266.   if Style = csDropDownList then Invalidate;
  1267. end;
  1268. procedure TfcCustomCombo.WMSetFocus(var Message: TWMSetFocus);
  1269. begin
  1270.   inherited;
  1271.   if Style = csDropDownList then
  1272.   begin
  1273.     Invalidate;
  1274.     ShowCaret;
  1275.     HideCaret;
  1276.   end;
  1277. end;
  1278. procedure TfcCustomCombo.SetModified(Value: Boolean);
  1279. begin
  1280.   if Value then begin
  1281.      if (DataSource<>nil) and (DataSource.State in [dsEdit, dsInsert]) then
  1282.         FDatalink.modified;
  1283.   end;
  1284.   inherited Modified := Value;
  1285. end;
  1286. procedure TfcCustomCombo.BtnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
  1287.   X, Y: Integer);
  1288. var parentForm: TCustomForm;
  1289. begin
  1290.   if Button <> mbLeft then Exit;
  1291.   if IsDroppedDown then CloseUp(True) { 2/11/99 - RSW }
  1292.   else begin
  1293.    { RSW - Kirk, what was this line for
  1294.      It causes a problem as its not ever reset.  For instance, your CMEnter code
  1295.      checks ControlState.  To see problem put control in grid and click in the control.
  1296.      Then tab to it and it does not select all }
  1297. //    ControlState := ControlState +[csLButtonDown];
  1298.     // 6/3/2001 - PYW - MDI Child forms would not get activated prior to setting focus.
  1299.     parentForm:= GetParentForm(self);
  1300.     if (parentForm<>nil) and (TForm(parentForm).formstyle = fsMDIChild) then
  1301.        if Screen.ActiveForm <> parentForm then
  1302.           SendMessage(parentform.Handle, WM_ACTIVATE, 0, 0);
  1303.     if CanFocus then
  1304.     begin
  1305.        SetFocus;
  1306.        // 6/16/01 - Fix problem when using WebBrowse and it has text selected
  1307.        if Handle<>GetFocus then
  1308.           windows.SetFocus(Handle);
  1309.     end;
  1310.     if (Screen.ActiveControl=self) or Focused then // 8/16/2000 - Fire also if screen.activecontrol is me
  1311.        PostMessage(Handle, WM_FC_CALLDROPDOWN, 0, 0);
  1312.   end
  1313. end;
  1314. procedure TfcCustomCombo.HideCaret;
  1315. begin
  1316.   Windows.HideCaret(Handle);
  1317.   inherited ReadOnly := True;
  1318. end;
  1319. procedure TfcCustomCombo.Paint;
  1320. begin
  1321. end;
  1322. procedure TfcCustomCombo.Reset;
  1323. begin
  1324.   if DataLink.Field <> nil then DataLink.Reset;
  1325.   SelectAll;
  1326.   SetModified(False);
  1327.   Paint;
  1328. end;
  1329. procedure TfcCustomCombo.SelectAll;
  1330. begin
  1331.    inherited SelectAll;
  1332. end;
  1333. procedure TfcCustomCombo.ShowCaret;
  1334. begin
  1335.   if not HandleAllocated then exit; //3/25/99-PYW - Make sure handle is allocated.
  1336.   Windows.ShowCaret(Handle);
  1337.   inherited ReadOnly := False;
  1338. end;
  1339. function TfcCustomCombo.GetLeftIndent: Integer;
  1340. begin
  1341.   result := 0;
  1342. end;
  1343. procedure TfcCustomCombo.SetDropDownCount(Value: Integer);
  1344. begin
  1345.   FDropDownCount := Value;
  1346. end;
  1347. procedure TfcCustomCombo.WMPaste(var Message: TMessage);
  1348. begin
  1349.   if (Style=csDropDown) then
  1350.   begin
  1351.      if not EditCanModify then exit
  1352.      else begin
  1353.        FDataLink.Edit;
  1354.        inherited;
  1355.        SetModified(True);
  1356.      end
  1357.   end
  1358.   else inherited;
  1359. end;
  1360. procedure TfcCustomCombo.WMCut(var Message: TMessage);
  1361. begin
  1362.   if (Style=csDropDown) then
  1363.   begin
  1364.      if not EditCanModify then exit
  1365.      else begin
  1366.        FDataLink.Edit;
  1367.        inherited;
  1368.        SetModified(True);
  1369.      end
  1370.   end
  1371.   else inherited;
  1372. end;
  1373. function TfcCustomCombo.GetRightIndent(Rect:TRect): Integer;
  1374. begin
  1375.   result:= 0;
  1376. {  result := Width-2;
  1377.   if (ColorAlignment <> taRightJustify) then exit;
  1378.   if FColorListOptions = nil then exit;
  1379.   GetColorRectInfo(Rect,AWidth,AHeight);
  1380.   if (Awidth <> 0) then
  1381.      inc(result, -AWidth);}
  1382. end;
  1383. function TfcCustomCombo.GetTopIndent: Integer;
  1384. begin
  1385.   result := 0;
  1386.   if (BorderStyle = bsNone) and fcIsInwwGrid(Self) then begin
  1387.      Result := 2;
  1388.      if fcIsClass(parent.classtype, 'TwwDBGrid') then
  1389.      begin
  1390.         if ([dgRowLines, dgRowFixedLines] * fcGetGridOptions(self) = []) then Result:=1;
  1391.      end;
  1392.   end
  1393.   else if (BorderStyle = bsNone) then
  1394.   begin
  1395.      Result := 1;
  1396.   end;
  1397.   if AlignmentVertical = fcavCenter then
  1398.   begin
  1399.      if BorderStyle=bsNone then
  1400.         inc(result,(Height - Canvas.Textheight('A')-2) div 2)
  1401.      else
  1402.         result:= (Height - Canvas.Textheight('A')-5) div 2;
  1403.   end;
  1404. end;
  1405. procedure TfcCustomCombo.SetAlignmentVertical(Value: TfcAlignVertical);
  1406. begin
  1407.   if FAlignmentVertical <> Value then begin
  1408.      FAlignmentVertical := Value;
  1409.      Invalidate;
  1410.   end;
  1411. end;
  1412. Procedure TfcCustomCombo.DoEnter;
  1413. begin
  1414.    inherited DoEnter;
  1415.    if (FDataLink.Field=Nil) then modified:= False;  { 1/21/97 - Only clear if unbound }
  1416. end;
  1417. constructor TBtnWinControl.Create(AOwner: TComponent);
  1418. begin
  1419.    inherited Create(AOwner);
  1420.    EditControl:= AOwner as TfcCustomCombo;
  1421. end;
  1422. procedure TBtnWinControl.CMMouseLeave(var Message: TMessage);
  1423. var r: TRect;
  1424.     offset: integer;
  1425. begin
  1426.   inherited;
  1427.   if not EditControl.ButtonEffects.Flat then exit;
  1428.   if EditControl.BorderStyle=bsSingle then offset:=2 else offset:= 0;
  1429.   if not EditControl.FFocused then begin
  1430.      if EditControl.IsTransparentEffective then begin
  1431.         r:= Rect(parent.left + Left + offset, parent.Top+top+offset,
  1432.                  parent.left + left + offset + Width, parent.top + offset + Top + Height);
  1433.         if fcIsTransparentParent(self) then
  1434.           fcInvalidateTransparentArea(self) // just to be safer, but probably works in both cases
  1435.         else
  1436.           InvalidateRect(parent.parent.handle, @r, True);
  1437. //        InvalidateRect(parent.parent.handle, @r, True);
  1438.         Invalidate;
  1439.      end;
  1440.      Invalidate;
  1441.   end
  1442. end;
  1443. procedure TBtnWinControl.WMEraseBkgnd(var Message: TWmEraseBkgnd);
  1444. var r: TRect;
  1445.    control: TfcCustomCombo;
  1446. begin
  1447.   control:= TfcCustomCombo(parent);
  1448.   if control.SkipUpdate then exit;
  1449.   if fcIsInwwGridPaint(parent) or
  1450.      control.isTransparentEffective  then
  1451.   begin
  1452.      { Fixes paint problem when mouse is clicked in button and moved outside
  1453.        region, but it is not released }
  1454.      if (not fcIsInwwGridPaint(parent)) and
  1455.         (control.ButtonEffects.Flat or control.ButtonEffects.Transparent) and
  1456.         (csLButtonDown in control.FButton.ControlState) then
  1457.      begin
  1458.         r:= Rect(parent.left + Left , parent.Top+top,
  1459.                  parent.left + left + Width, parent.top + Top + Height);
  1460.         InvalidateRect(parent.parent.handle, @r, False);
  1461.         control.skipupdate:= true;
  1462.         parent.parent.update;
  1463.         control.skipupdate:= False;
  1464.      end;
  1465.      Message.result:= 1;
  1466.      exit;
  1467.   end
  1468.   else inherited;
  1469. end;
  1470. procedure TfcCustomCombo.WMEraseBkgnd(var Message: TWmEraseBkgnd);
  1471. var r: TRect;
  1472. begin
  1473.   if fcIsInwwObjectViewPaint(self) or
  1474.     (IsTransparentEffective and (not FFocused)) then
  1475.   begin
  1476.      Message.result:= 1;
  1477.   end
  1478.   // 8/1/02 - Respect NonFocusColor when it does not have focus
  1479.   else if (not fcIsInwwGridPaint(self)) and
  1480.       (not FFocused) and (Frame.NonFocusColor<>clNone) then
  1481.   begin
  1482.      r:= ClientRect;
  1483.      if FCanvas<>nil then
  1484.      begin
  1485.         FCanvas.Brush.Color:= Frame.NonFocusColor;
  1486.         Windows.FillRect(message.dc, r, FCanvas.brush.handle );
  1487.      end;
  1488.      message.result:=1
  1489.   end
  1490.   else inherited;
  1491. end;
  1492. procedure TfcCustomCombo.DrawFrame(Canvas: TCanvas);
  1493. begin
  1494.     fcDrawEdge(self, Frame, Canvas, FFocused);
  1495. end;
  1496. procedure TfcCustomCombo.InvalidateTransparentButton;
  1497. var r: TRect;
  1498. begin
  1499.    if ButtonEffects.Flat or ButtonEffects.Transparent then begin
  1500.      with FBtnParent do begin
  1501.          r:= Rect(parent.left + Left, parent.Top+top,
  1502.                parent.left + left+ Width, parent.top + Top + Height);
  1503.         { Calling with True causes flicker for any control that is invalidated.
  1504.           Test with False to see if any side effects  }
  1505.          InvalidateRect(parent.parent.handle, @r, False);
  1506.          parent.parent.Update;
  1507.       end
  1508.    end;
  1509.    FButton.invalidate;
  1510. end;
  1511. Procedure TfcCustomCombo.UpdatebuttonGlyph;
  1512. begin
  1513. //   FButton.Glyph.Handle:=0;  7/28/01 - Don't clear glyph
  1514.    if (FButtonStyle<>cbsCustom) and
  1515.       (ButtonEffects.Flat or ButtonEffects.Transparent) then
  1516.    begin
  1517.       if (FButtonStyle = cbsDownArrow) then
  1518.          FButton.Glyph.Handle:= LoadBitmap(HInstance, 'FCDROPDOWN')
  1519.    end;
  1520. end;
  1521. function TfcCustomCombo.IsCustom: Boolean;
  1522. begin
  1523.   Result := ButtonStyle = cbsCustom;
  1524. end;
  1525. function TfcCustomCombo.GetButtonGlyph: TBitmap;
  1526. begin
  1527.   result:= FButton.Glyph;
  1528. end;
  1529. procedure TfcCustomCombo.SetButtonGlyph(Value: TBitmap);
  1530. begin
  1531.   FButton.Glyph.Assign(Value);
  1532. //  FButtonGlyph.Assign(Value);
  1533.   Invalidate;
  1534. end;
  1535. {
  1536. procedure TfcCustomCombo.GlyphChanged(Sender: TObject);
  1537. begin
  1538.    FButton.Glyph.Handle:= LoadComboGlyph;
  1539.    Invalidate;
  1540. end;
  1541. }
  1542. Procedure TfcCustomCombo.SetButtonWidth(val: integer);
  1543. begin
  1544.    if FButtonWidth<>val then
  1545.    begin
  1546.       FButtonWidth:= val;
  1547.       if val<>0 then Button.Width:= val
  1548.       else Button.Width:= fcmax(GetSystemMetrics(SM_CXVSCROLL), 15);
  1549.       UpdateButtonPosition;
  1550.    end
  1551. end;
  1552. function TfcCustomCombo.GetButtonWidth: integer;
  1553. begin
  1554.    result:= FButtonWidth;
  1555. end;
  1556. procedure TfcCustomCombo.CMMouseEnter(var Message: TMessage);
  1557. begin
  1558.   inherited;
  1559.   DoMouseEnter;
  1560. end;
  1561. procedure TfcCustomCombo.CMMouseLeave(var Message: TMessage);
  1562. var r:TRect;
  1563.     pt:TPoint;
  1564. begin
  1565.   GetCursorPos(pt);
  1566.   pt := ScreenToClient(pt);
  1567.   r := ClientRect;
  1568.   if (PtInRect(r,pt)) then exit;
  1569.   inherited;
  1570.   DoMouseLeave;
  1571. end;
  1572. procedure TfcCustomCombo.DoMouseEnter;
  1573. begin
  1574.   try
  1575.      If Assigned( FOnMouseEnter ) Then FOnMouseEnter( self );  //10/1/2001 - Added for OnMouseEnter and OnMouseLeave events.
  1576.   except
  1577.     exit;
  1578.   end;
  1579.   if Frame.IsFrameEffective and (not FFocused) and
  1580.      Frame.MouseEnterSameAsFocus then
  1581.      fcDrawEdge(self, Frame, FCanvas, True);
  1582. //     fcDrawEdge(self, Frame, ControlCanvas, True);
  1583. end;
  1584. procedure TfcCustomCombo.DoMouseLeave;
  1585. begin
  1586.   try
  1587.     If Assigned( FOnMouseLeave ) Then FOnMouseLeave( self ); //10/1/2001 - Added for OnMouseEnter and OnMouseLeave events.
  1588.   except
  1589.     exit;
  1590.   end;
  1591.   if Frame.IsFrameEffective and (not FFocused) and
  1592.      Frame.MouseEnterSameAsFocus then begin
  1593.      fcDrawEdge(self, Frame, FCanvas, False);
  1594.      if IsTransparentEffective then
  1595.         Frame.CreateTransparent:= True;
  1596.      RecreateWnd;
  1597.   end;
  1598. end;
  1599. // Some fonts change the margin, so let us reset back to 0 so that
  1600. // borders will be ok
  1601. procedure TfcCustomCombo.WMSetFont(var Message: TWMSetFont);
  1602. begin
  1603.   inherited;
  1604.   if Frame.Enabled and NewStyleControls then
  1605.      SendMessage(Handle, EM_SETMARGINS, EC_LEFTMARGIN or EC_RIGHTMARGIN, 0);
  1606. end;
  1607. procedure TfcCustomCombo.SetController(Value: TComponent);
  1608. var tempFrame: TfcEditFrame;
  1609. begin
  1610.    if FController<>Value then
  1611.    begin
  1612.       fcUpdateController(TComponent(FController), Value, self);
  1613.       if FController<>nil then
  1614.       begin
  1615.          tempFrame:= TfcEditFrame.Get(TControl(FController));
  1616.          FFrame.Assign(tempFrame);
  1617. //         FFrame.Assign(FController.Frame);
  1618.          if HandleAllocated then RecreateWnd;
  1619.       end
  1620.    end
  1621. end;
  1622. initialization
  1623.   WM_FC_CALLDROPDOWN := RegisterWindowMessage('FCCOMBODROPDOWNMESSAGE');
  1624. end.