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

Delphi控件源码

开发平台:

Delphi

  1. unit fcStatusBar;
  2. {
  3. //
  4. // Components : TfcStatusBar
  5. //
  6. // Copyright (c) 1999 by Woll2Woll Software
  7. }
  8. // 10/12/98 - Handle disabling of images for the glyphs style
  9. // 10/12/98 - Occasional flicker as time changes.
  10. // 4/17/99 - Renamed imagelist to images
  11. // 4/26/99 - PYW - Only shrink width if last panel and sizegrip is true.
  12. // 4/26/99 - PYW - Show sizegrip only if sizeable window.
  13. // 4/27/99 - PYW - Update Timer for time styles to 1000.
  14. // 5/06/99 - PYW - Added StatusBarText property.
  15. // 5/27/99 - RSW - Don't use StatusBar Canvas, but use StatusPanel Canvas
  16. // 7/11/99 - Clear StatusBars static variable so that if referenced for
  17. //           some reason later in in destructor it would not cause an exception
  18. // 8/14/2000 - PYW - Don't change the parents for richedit controls.
  19. // 5/22/2000 - PYW - Added code to make statusbar respect active container.
  20. interface
  21. {$i fcIfDef.pas}
  22. uses
  23.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  24.   CommCtrl, Menus, Richedit, StdCtrls, fcCollection,
  25.   fcCommon, fcText, ComCtrls{$ifdef fcDelphi4Up}, ImgList{$endif};
  26. const
  27.   TIMER_ID = 200;
  28.   HINT_TIMER_ID = 300;
  29.   RICHEDIT_TIMER_ID = 400;
  30. type
  31.   TfcCustomStatusBar = class;
  32.   // 5/06/99 - PYW - Added StatusBarText property.
  33.   TfcStatusBarText = class(TPersistent)
  34.   private
  35.      FOwner : TfcCustomStatusBar;
  36.      FCapsLock: string;
  37.      FOverwrite: string;
  38.      FNumLock: string;
  39.      FScrollLock: string;
  40.      procedure SetCapsLock(Value:String);
  41.      procedure SetOverwrite(Value:String);
  42.      procedure SetNumLock(Value:String);
  43.      procedure SetScrollLock(Value:String);
  44.   public
  45.      constructor Create(AOwner: TfcCustomStatusBar);
  46.   published
  47.      property CapsLock: string read FCapsLock write SetCapsLock;
  48.      property Overwrite: string read FOverwrite write SetOverwrite;
  49.      property NumLock: string read FNumLock write SetNumLock;
  50.      property ScrollLock: string read FScrollLock write SetScrollLock;
  51.   end;
  52.   TfcStatusPanels = class;
  53.   TfcStatusPanel = class;
  54.   TfcCustomStatusBarClass = class of TfcCustomStatusBar;
  55.   TfcStatusPanelsClass = class of TfcStatusPanels;
  56.   TfcStatusPanelClass = class of TfcStatusPanel;
  57.   TfcStatusPanelStyle = (psTextOnly, psControl, psOverWrite, psCapsLock,
  58.                          psNumLock, psDateTime, psDate, psTime, psGlyph,
  59.                          psRichEditStatus, psHint, psUserName, psComputerName, psScrollLock, psHintContainerOnly);
  60.   TfcStatusPanelBevel = (pbNone, pbLowered, pbRaised);
  61.   TfcPanelTextChangedEvent = procedure(Sender: TObject; const Text: string) of object;
  62.   TfcDrawTextEvent = procedure(Panel: TfcStatusPanel; var Text: string; var Enabled:Boolean) of object;
  63.   {
  64.   // TfcStatusPanel
  65.   // Properties:
  66.   // (Public)
  67.   // - Col:        Returns the current Col in the TCustomMemo. (Only
  68.   //               applicable if Control is a TCustomMemo)  For use
  69.   //               when customizing the line and Col text.
  70.   //
  71.   // - Row:        Returns the current Row in the TCustomMemo.  See
  72.   //               the Col property for details.
  73.   //
  74.   // (Published)
  75.   // - Alignment:  Determines the alignment of the text in the Panel.
  76.   //
  77.   // - Bevel:      Determines the type of Bevel the panel has.
  78.   //
  79.   // - Color:      Determines the color of the panel.
  80.   //
  81.   // - Control:    When the style property is set to psControl then this
  82.   //               is the control that gets displayed.  Setting this
  83.   //               property to a non-nil value will set the style property
  84.   //               to psControl.
  85.   //
  86.   // - Enabled:    When False, text appears disabled (grayed-out).  Setting
  87.   //               this will also set the Control's enabled property if the
  88.   //               Control property is assigned.
  89.   //
  90.   // - Font:       The font that the text uses to display itself.
  91.   //
  92.   // - Hint:       The hint that gets displayed when the mouse cursor
  93.   //               remains over the panel for a short period of time.
  94.   //
  95.   // - ImageIndex: The index within the StatusBar's Imagelist to display.
  96.   //               Setting this property to a value other than -1 will
  97.   //               set the style property to psGlyph.
  98.   //
  99.   // - Indent:     When the Style property is set to psTextOnly, this property
  100.   //               specifies how much from the border the text is spaced
  101.   //               away.  When the Alignment property is taLeftJustify,
  102.   //               the Indent property pertains to the left border.
  103.   //
  104.   // - Margin:     This property specifies how far the edges of text and
  105.   //               controls are from the edge of the panel.
  106.   //
  107.   // - Name:       Used with the PanelByName method of the TfcStatusPanels.
  108.   //
  109.   // - PopupMenu:  The associated popupmenu of the panel.
  110.   //
  111.   // - Style:      Determines what kind of information the panel displays.
  112.   //
  113.   // - Text:       Determines what text the panel displays.
  114.   //
  115.   // - Width:      Determines how wide the panel is.  This value is a string but
  116.   //               but can be only one of two types of values.
  117.   //               - It can be an integer (i.e. 5, 25, 30, etc.)
  118.   //               - It can be a percentage (i.e. 5%, 50%, 66%, etc.)
  119.   //
  120.   // Methods:
  121.   // - GetRect:    Returns the rectangle of the panel.
  122.   //
  123.   // Events:
  124.   // - OnClick, OnDblClick, OnMouseDown, OnMouseUp, OnMouseMove:
  125.   //               Standard mouse events equivalent to that of TControl.
  126.   //
  127.   // - OnDrawText: Event occurs immediately prior to drawing text onto the
  128.   //               panel.  The supplied Text variable can change to change
  129.   //               the text that gets drawn.
  130.   //
  131.   // - OnTextChanged: Occurs immediately after the text for the panel
  132.   //               changes.
  133.   //
  134.   }
  135.   TfcStatusPanel = class(TfcCollectionItem)
  136.   private
  137.     // Property Storage Variables
  138.     FCanvas: TCanvas;               // Protected
  139.     FCol: Integer;                  // Public
  140.     FRow: Integer;
  141.     FBevel: TfcStatusPanelBevel;
  142.     FColor: TColor;
  143.     FComponent: TComponent;
  144.     FEnabled: Boolean;
  145.     FDrawTextEnabled: Boolean;
  146.     FInDrawText:Boolean;
  147.     FFont: TFont;
  148.     FHint: String;
  149.     FImageIndex: Integer;
  150.     FIndent: Integer;
  151.     FMargin: Integer;
  152.     FName: string;
  153.     FPaintWidth: Integer;
  154.     FPopupMenu: TPopupMenu;
  155.     FStyle: TfcStatusPanelStyle;
  156.     FText: string;
  157.     FCurDateTime: TDateTime;
  158.     FTextOptions: TfcCaptionText;
  159.     FWidth: string;
  160.     FOnClick: TNotifyEvent;         // Events
  161.     FOnDblClick: TNotifyEvent;
  162.     FOnDrawText: TfcDrawTextEvent;
  163.     FOnMouseDown: TMouseEvent;
  164.     FOnMouseMove: TMouseMoveEvent;
  165.     FOnMouseUp: TMouseEvent;
  166.     FOnSetName: TNotifyEvent;
  167.     FOnTextChanged: TfcPanelTextChangedEvent;
  168.     FRect: TRect;
  169.     // Property Access Methods
  170.     function GetControl: TControl;
  171.     procedure SetBevel(Value: TfcStatusPanelBevel);
  172.     procedure SetColor(Value: TColor);
  173.     procedure SetComponent(Value: TComponent);
  174.     procedure SetEnabled(Value: Boolean);
  175.     procedure SetFont(Value:TFont);
  176.     procedure SetHint(Value:String);
  177.     procedure SetImageIndex(Value: Integer);
  178.     procedure SetIndent(Value:Integer);
  179.     procedure SetMargin(Value: Integer);
  180.     procedure SetName(const Value: string);
  181.     procedure SetStyle(Value: TfcStatusPanelStyle);
  182.     procedure SetText(const Value: string);
  183.     procedure SetWidth(Value: string);
  184.   protected
  185.     function GenerateName: string; virtual;
  186.     function GetDisplayName: string; override;
  187.     function GetStatusBar: TfcCustomStatusBar; virtual;
  188.     function StoreWidth: Boolean; virtual;
  189.     procedure FontChanged(Sender: TObject); virtual;
  190.     procedure Notification(AComponent: TComponent; Operation: TOperation); virtual;
  191. //    procedure ParentWndProc(var Message: TMessage); virtual;
  192.     // IfcTextControl
  193.     function GetTextEnabled: Boolean; virtual;
  194.     procedure AdjustBounds; virtual;
  195.     // Draw methods
  196.     function DoDrawDateTime: Boolean; virtual;
  197.     procedure Draw(ACanvas: TCanvas; ARect: TRect); virtual;
  198.     procedure DrawControl; virtual;
  199.     procedure DrawGlyph; virtual;
  200.     procedure DrawKeyboardState; virtual;
  201.     procedure DrawHint; virtual;
  202.     procedure DrawUserName; virtual;
  203.     procedure DrawComputerName; virtual;
  204.     procedure DrawRichEditStatus; virtual;
  205.     procedure DrawText(AText: string; ARect: TRect; AEnabled:Boolean); virtual;
  206.     // Overriden methods
  207.     procedure AssignTo(Dest: TPersistent); override;
  208.     // Event wrappers
  209.     procedure Click; dynamic;
  210.     procedure DblClick; dynamic;
  211.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  212.       X, Y: Integer); dynamic;
  213.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); dynamic;
  214.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
  215.       X, Y: Integer); dynamic;
  216.     procedure PanelTextChanged(Const Text:String); dynamic;
  217.     // Protected Properties
  218.     property Canvas: TCanvas read FCanvas;
  219.     property DrawTextEnabled: Boolean read FDrawTextEnabled write FDrawTextEnabled;
  220.   public
  221.     Patch: Variant;
  222.     constructor Create(Collection: TCollection); override;
  223.     destructor Destroy; override;
  224.     function ClientToScreen(p: TPoint): TPoint; virtual;
  225.     function GetRect: TRect; virtual;
  226.     procedure Invalidate; virtual;
  227.     // Public Properties
  228.     property Col: Integer read FCol;
  229.     property Control: TControl read GetControl;
  230.     property PaintWidth: Integer read FPaintWidth write FPaintWidth;
  231.     property Row: Integer read FRow;
  232.     property StatusBar: TfcCustomStatusBar read GetStatusBar;
  233.     property OnSetName: TNotifyEvent read FOnSetName write FOnSetName;
  234.   published
  235.     // Published Properties
  236.     property Bevel: TfcStatusPanelBevel read FBevel write SetBevel default pbLowered;
  237.     property Color: TColor read FColor write SetColor default clBtnFace;
  238.     property Component: TComponent read FComponent write SetComponent;
  239.     property Enabled: Boolean read FEnabled write SetEnabled default True;
  240.     property Font: TFont read FFont write SetFont;
  241.     property Hint : string read FHint write SetHint;
  242.     property ImageIndex: Integer read FImageIndex write SetImageIndex default 0;
  243.     property Indent : Integer read FIndent write SetIndent default 0;
  244.     property Margin: Integer read FMargin write SetMargin default 0;
  245.     property Name: string read FName write SetName;
  246.     property PopupMenu: TPopupMenu read FPopupMenu write FPopupMenu;
  247.     property Style: TfcStatusPanelStyle read FStyle write SetStyle default psTextOnly;
  248.     property Tag;
  249.     property Text : string read FText write SetText;
  250.     property TextOptions: TfcCaptionText read FTextOptions write FTextOptions;
  251.     property Width: string read FWidth write SetWidth stored StoreWidth;
  252.     property OnClick: TNotifyEvent read FOnClick write FOnClick;
  253.     property OnDblClick: TNotifyEvent read FOnDblClick write FOnDblClick;
  254.     property OnDrawText: TfcDrawTextEvent read FOnDrawText write FOnDrawText;
  255.     property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;
  256.     property OnMouseMove: TMouseMoveEvent read FOnMouseMove write FOnMouseMove;
  257.     property OnMouseUp: TMouseEvent read FOnMouseUp write FOnMouseUp;
  258.     property OnTextChanged: TfcPanelTextChangedEvent read FOnTextChanged write FOnTextChanged;
  259.   end;
  260.   {
  261.   // TfcStatusPanels
  262.   // Properties:
  263.   // - Items: Array property to retrieve a TfcStatusPanel.
  264.   //
  265.   // Methods:
  266.   // - Add:          Method to add a new panel.  Returns the newly created
  267.   //                 panel.
  268.   //
  269.   // - PanelByName:  Returns the panel with the name that matches in the
  270.   //                 name that was passed in.  Returns nil if no panels
  271.   //                 with that name are found.
  272.   //
  273.   }
  274.   TfcStatusPanels = class(TfcCollection)
  275.   private
  276.     FStatusBar: TfcCustomStatusBar;
  277.     // Property Access Methods
  278.     function GetItem(Index: Integer): TfcStatusPanel;
  279.     procedure SetItem(Index: Integer; Value: TfcStatusPanel);
  280.   protected
  281.     procedure RedrawIfNeeded(StyleToCheck: TfcStatusPanelStyle); virtual;
  282.     // Overriden Methods
  283.     function GetOwner: TPersistent; override;
  284.     procedure Update(Item: TCollectionItem); override;
  285.     // Protected Properties
  286.     property StatusBar: TfcCustomStatusBar read FStatusBar;
  287.   public
  288.     constructor Create(StatusBar: TfcCustomStatusBar; AStatusPanelClass: TfcStatusPanelClass);
  289.     function Add: TfcStatusPanel;
  290.     function PanelByName(AName: string): TfcStatusPanel;
  291.     // Public Properties
  292.     property Items[Index: Integer]: TfcStatusPanel read GetItem write SetItem; default;
  293.   end;
  294.   TDrawPanelEvent = procedure(StatusBar: TfcCustomStatusBar; Panel: TfcStatusPanel;
  295.     const Rect: TRect) of object;
  296.   TDrawKeyboardStateEvent = procedure(StatusBar: TfcCustomStatusBar; StatusPanel: TfcStatusPanel;
  297.     KeyIsOn: Boolean; Rect: TRect; var AText: string) of object;
  298.   {
  299.   // TfcCustomStatusBar
  300.   // Properties:
  301.   // - ImageList:   The ImageList that panels whose style is set to psGlyph
  302.   //                uses to render the image.
  303.   //
  304.   // - Panels:      The instance of TfcStatusPanels that contains the panels
  305.   //                of the status bar.
  306.   //
  307.   // - SimplePanel: Same as TStatusBar.SimplePanel
  308.   //
  309.   // - SimpleText:  Same as TStatusBar.SimpleText
  310.   //
  311.   // - SizeGrip:    Same as TStatusBar.SizeGrip
  312.   //
  313.   // Methods:
  314.   // - GetPanelFromPt: Returns the TfcStatusPanel located at the specified
  315.   //                x and y coordinates.
  316.   //
  317.   // Events:
  318.   // - OnDrawKeyboardState: Event occurs before drawing the text for a
  319.   //                panel whose style property is set to psOverwrite,
  320.   //                psCapsLock, psScrollLock, or psNumLock.  Used to customize
  321.   //                the text that is displayed.
  322.   //
  323.   // - OnDrawPanel: Same as TStatusBar.OnDrawPanel
  324.   //
  325.   }
  326.   TfcCustomStatusBar = class(TWinControl)
  327.   private
  328.     // Property Storage Variables
  329.     FCanvas: TCanvas;             // Protected
  330.     FLastSize: TSize;
  331.     FImageList: TCustomImageList;       // Published
  332.     FPanels: TfcStatusPanels;
  333.     FSimplePanel: Boolean;
  334.     FSimpleText: string;
  335.     FSizeGrip: Boolean;
  336.     FSizing: Boolean;
  337.     {$ifdef fcDelphi3}
  338.     FOnResize: TNotifyEvent;
  339.     {$endif}
  340.     FOnDrawKeyboardState: TDrawKeyboardStateEvent;  // Events
  341.     FOnDrawPanel: TDrawPanelEvent;
  342.     FStatusBarText: TfcStatusBarText;  // 5/06/99 - PYW - Added StatusBarText property.
  343.     FDisableThemes: boolean;
  344.     // Property Access Methods
  345.     procedure SetPanels(Value: TfcStatusPanels);
  346.     procedure SetSimplePanel(Value: Boolean);
  347.     procedure SetSimpleText(const Value: string);
  348.     procedure SetSizeGrip(Value: Boolean);
  349.     function GetSizeGrip: boolean;
  350.     // Message Handlers
  351.     procedure CMShowingChanged(var Message: TMessage); message CM_SHOWINGCHANGED;
  352.     procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
  353.     procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
  354.     procedure WMSize(var Message: TWMSize); message WM_SIZE;
  355.     procedure WMTimer(var Message: TWMTimer); message WM_TIMER;
  356.   protected
  357.     function GetCollectionClass: TfcStatusPanelsClass; virtual;
  358.     procedure DrawPanel(Panel: TfcStatusPanel; Rect: TRect); dynamic;
  359.     procedure Resize; {$ifdef fcDelphi3}virtual;{$else}override;{$endif}
  360.     procedure UpdatePanel(Index: Integer; DoInvalidate: Boolean);
  361.     procedure UpdatePanels; virtual;
  362.     // Overriden methods
  363.     procedure Click; override;
  364.     procedure CreateParams(var Params: TCreateParams); override;
  365.     procedure CreateWnd; override;
  366.     procedure DblClick; override;
  367.     procedure DestroyWnd; override;
  368.     procedure Loaded; override;
  369.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  370.       X, Y: Integer); override;
  371.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  372.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
  373.       X, Y: Integer); override;
  374.     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  375.     procedure WndProc(var Message: TMessage); override;
  376.     property Canvas: TCanvas read FCanvas;
  377.   public
  378.     Patch: Variant;
  379.     constructor Create(AOwner: TComponent); override;
  380.     destructor Destroy; override;
  381. //    function GetPriorityPanel(APriority: Integer): TfcStatusPanel;
  382. //    function GetOpenPriority: Integer;
  383.     procedure Invalidate; override;
  384.     function GetPanelFromPt(x, y: Integer): TfcStatusPanel; virtual;
  385.     procedure ComponentExclusive(Value: TComponent; Panel: TfcStatusPanel; ThisStatusBarOnly: Boolean);
  386.     // Public Properties
  387.     property Images: TCustomImageList read FImageList write FImageList;
  388.     property Panels: TfcStatusPanels read FPanels write SetPanels;
  389.     property SimplePanel: Boolean read FSimplePanel write SetSimplePanel;
  390.     property SimpleText: string read FSimpleText write SetSimpleText;
  391.     property SizeGrip: Boolean read GetSizeGrip write SetSizeGrip default True;
  392.     property OnDrawKeyboardState: TDrawKeyboardStateEvent read FOnDrawKeyboardState write FOnDrawKeyboardState;
  393.     property OnDrawPanel: TDrawPanelEvent read FOnDrawPanel write FOnDrawPanel;
  394.     {$ifdef fcDelphi3}
  395.     property OnResize: TNotifyEvent read FOnResize write FOnResize;
  396.     {$endif}
  397.     property StatusBarText: TfcStatusBarText read FStatusBarText write FStatusBarText;
  398.     property DisableThemes : boolean read FDisableThemes write FDisableThemes default False;
  399.   end;
  400.   TfcStatusBar = class(TfcCustomStatusBar)
  401.   published
  402.     property DisableThemes;
  403.     
  404.     {$ifdef fcDelphi4Up}
  405.     property Anchors;
  406.     property Constraints;
  407.     {$endif}
  408.     property Align default alBottom;
  409.     property DragCursor;
  410.     property DragMode;
  411.     property Enabled;
  412.     property Font;
  413.     property Images;
  414.     property Panels;
  415.     property ParentFont;
  416.     property ParentShowHint;
  417.     property PopupMenu;
  418.     property ShowHint;
  419.     property SimplePanel;
  420.     property SimpleText;
  421.     property SizeGrip;
  422.     property StatusBarText;
  423.     property Visible;
  424.     property OnClick;
  425.     property OnDblClick;
  426.     property OnDragDrop;
  427.     property OnDragOver;
  428.     property OnEndDrag;
  429.     property OnMouseDown;
  430.     property OnMouseMove;
  431.     property OnMouseUp;
  432.     property OnDrawKeyboardState;
  433.     property OnDrawPanel;
  434.     property OnResize;
  435.     property OnStartDrag;
  436.   end;
  437. implementation
  438. {$ifdef fcDelphi7Up}
  439. uses themes;
  440. {$endif}
  441. {$ifdef ThemeManager}
  442. uses thememgr, themesrv, uxtheme;
  443. {$endif}
  444. var StatusBars: TList;
  445. function fcCanGetHint(StatusBar:TfcCustomStatusBar):boolean;
  446. var InFrame:Boolean;
  447.     cmp:TComponent;
  448.     r:TRect;
  449. begin
  450.   result := False;
  451.   //First check to see if the form for the statusbar is active.
  452.   if (GetParentForm(StatusBar)<>nil) and (not GetParentForm(StatusBar).Active) then exit;
  453.   //First check to see if the StatusBar is in a Frame.
  454.   InFrame := False;
  455.   cmp := StatusBar.GetParentComponent as TComponent;
  456.   while (cmp <> nil) and (not(cmp is TCustomForm)) do begin
  457.     if (cmp is TFrame) then begin
  458.        InFrame := True;
  459.        break;
  460.     end;
  461.     cmp := cmp.GetParentComponent as TComponent;
  462.   end;
  463.   //If statusbar is in frame then check if mouse is over this frame, otherwise check if mouse is over the form.
  464.   if InFrame then begin
  465.     if (cmp<>nil) and (cmp is TFrame) then begin
  466.        r:= TFrame(cmp).ClientRect;
  467.        MapWindowPoints(TFrame(cmp).handle, 0, R, 2);
  468.        if not ptinrect(r,Mouse.CursorPos) then exit;
  469.     end;
  470.   end
  471.   else if not ptinrect(getParentform(StatusBar).BoundsRect,Mouse.CursorPos) then exit;
  472.   //If we got this far, then it is valid to show this hint.
  473.   result := True;
  474. end;
  475. function fcGetComputerName : string;
  476. var ComputerName:String;
  477.     nsize:{$ifdef fcDelphi4up}Cardinal{$else}Dword{$endif};
  478. begin
  479.   nsize := 25;
  480.   SetLength(ComputerName,nsize);
  481.   if GetComputerName(PChar(ComputerName),nsize) then
  482.   begin
  483.      SetLength(ComputerName,nsize);
  484.      result := ComputerName;
  485.   end
  486.   else result := '';
  487. end;
  488. { TfcStatusBarText }
  489. // 5/06/99 - PYW - Added StatusBarText property.
  490. constructor TfcStatusBarText.Create(AOwner: TfcCustomStatusBar);
  491. begin
  492.   inherited Create;
  493.   FOwner := AOwner;
  494. end;
  495. procedure TfcStatusBarText.SetCapsLock(Value: String);
  496. begin
  497.   if FCapsLock <> Value then
  498.   begin
  499.     FCapsLock := Value;
  500.     FOwner.Invalidate;
  501.   end;
  502. end;
  503. procedure TfcStatusBarText.SetOverwrite(Value: String);
  504. begin
  505.   if FOverwrite <> Value then
  506.   begin
  507.     FOverwrite := Value;
  508.     FOwner.Invalidate;
  509.   end;
  510. end;
  511. procedure TfcStatusBarText.SetNumLock(Value: String);
  512. begin
  513.   if FNumLock <> Value then
  514.   begin
  515.     FNumLock := Value;
  516.     FOwner.Invalidate;
  517.   end;
  518. end;
  519. procedure TfcStatusBarText.SetScrollLock(Value: String);
  520. begin
  521.   if FScrollLock <> Value then
  522.   begin
  523.     FScrollLock := Value;
  524.     FOwner.Invalidate;
  525.   end;
  526. end;
  527. { TfcStatusPanel }
  528. constructor TfcStatusPanel.Create(Collection: TCollection);
  529. begin
  530.   Collection.BeginUpdate;
  531.   inherited Create(Collection);
  532.   FWidth := '50';
  533.   FPaintWidth := StrtoInt(FWidth);
  534.   FBevel := pbLowered;
  535.   FEnabled := True;
  536.   FColor := clBtnFace;
  537.   FName := GenerateName;
  538.   FFont := TFont.Create;
  539.   FFont.OnChange := FontChanged;
  540.   FFont.Assign(StatusBar.Font);
  541.   FTextOptions := TfcCaptionText.Create(MakeCallbacks(Invalidate, AdjustBounds, GetTextEnabled),
  542.     FCanvas, FFont);
  543.   FTextOptions.VAlignment := vaVCenter;
  544.   FIndent := 0;
  545.   OnSetName := SetButtonName;
  546.   Collection.EndUpdate;
  547. end;
  548. destructor TfcStatusPanel.Destroy;
  549. begin
  550.   FTextOptions.Free;
  551.   FFont.OnChange := FontChanged;
  552.   FFont.Free;
  553.   FFont:= nil;
  554.   inherited;
  555. end;
  556. function TfcStatusPanel.GenerateName: string;
  557. var i:integer;
  558. begin
  559.   i := 0;
  560.   repeat
  561.     result := 'Panel' + IntToStr(i);
  562.     inc(i);
  563.   until StatusBar.Panels.PanelByName(result) = nil;
  564. end;
  565. procedure TfcStatusPanel.FontChanged(Sender: TObject);
  566. begin
  567.    inherited;
  568.    Changed(False);
  569. end;
  570. procedure TfcStatusPanel.AssignTo(Dest: TPersistent);
  571. begin
  572.   if Dest is TfcStatusPanel then
  573.     with TfcStatusPanel(Dest) do
  574.     begin
  575.       FBevel := self.Bevel;
  576.       FColor := self.Color;
  577.       // 4/16/03 - Don't set component if in ancestor
  578.       if (StatusBar=nil) or
  579.          not (csUpdating in StatusBar.ComponentState) then
  580.          FComponent := self.Component;
  581.       FEnabled := self.Enabled;
  582.       FFont.Assign(self.Font);
  583.       FHint := self.Hint;
  584.       FImageIndex := self.ImageIndex;
  585.       FIndent := self.Indent;
  586.       FMargin := self.Margin;
  587.       FPopupMenu := self.PopupMenu;
  588.       FStyle := self.Style;
  589.       FText := self.Text;
  590.       FWidth := self.Width;
  591.       FTextOptions.Assign(self.TextOptions);
  592.       FOnClick := self.OnClick;
  593.       FOnDblClick := self.OnDblClick;
  594.       FOnDrawText := self.OnDrawText;
  595.       FOnMouseDown := self.OnMouseDown;
  596.       FOnMouseMove := self.OnMouseMove;
  597.       FOnMouseUp := self.OnMouseUp;
  598.       FOnTextChanged := self.OnTextChanged;
  599. //      FComponent := self.Component;
  600.     end
  601.   else inherited AssignTo(Dest);
  602. end;
  603. procedure TfcStatusPanel.Notification(AComponent: TComponent; Operation: TOperation);
  604. begin
  605.   if (Operation = opRemove) and (AComponent = FComponent) then
  606.     Component := nil;
  607.   if (Operation = opRemove) and (AComponent = FPopupMenu) then
  608.     PopupMenu := nil;
  609. end;
  610. procedure TfcStatusPanel.Click;
  611. begin
  612.   if Assigned(FOnClick) then FOnClick(Self);
  613. end;
  614. procedure TfcStatusPanel.DblClick;
  615. var   KeyBuffer:TKeyboardState;
  616.       TmpScan:Integer;
  617.       KeyCode: Integer;
  618. begin
  619.   if Assigned(FOnDblClick) then FOnDblClick(Self);
  620.   KeyCode := -1;
  621.   case FStyle of
  622.     psNumLock: KeyCode := VK_NUMLOCK;
  623.     psCapsLock: KeyCode := VK_CAPITAL;
  624.     psOverWrite: KeyCode := VK_INSERT;
  625.     psScrollLock: KeyCode := VK_SCROLL;
  626.   end;
  627.   if KeyCode <> -1 then
  628.   begin
  629.     GetKeyboardState(KeyBuffer);
  630.     TmpScan := MapVirtualKey(KeyCode,0);
  631.     Keybd_event(KeyCode, TmpScan, 0, 0);
  632.     Keybd_event(KeyCode, TmpScan, KEYEVENTF_KEYUP, 0);
  633.     SetKeyboardState(KeyBuffer);
  634.   end
  635. end;
  636. function TfcStatusPanel.GetStatusBar: TfcCustomStatusBar;
  637. begin
  638.   result := TfcStatusPanels(Collection).FStatusBar;
  639. end;
  640. function TfcStatusPanel.StoreWidth: Boolean;
  641. begin
  642.   result := Width <> '0';
  643. end;
  644. procedure TfcStatusPanel.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  645. begin
  646.   if Assigned(FOnMouseUp) then FOnMouseUp(Self, Button, Shift, X, Y);
  647. end;
  648. procedure TfcStatusPanel.MouseMove(Shift: TShiftState; X, Y: Integer);
  649. begin
  650.   if Assigned(FOnMouseMove) then FOnMouseMove(Self,Shift,X,Y);
  651.   if StatusBar.Hint <> Hint then
  652.   begin
  653.     Application.CancelHint;
  654.     StatusBar.Hint := Hint;
  655.   end;
  656. end;
  657. procedure TfcStatusPanel.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  658. var p: TPoint;
  659. begin
  660.   if Assigned(FOnMouseDown) then FOnMouseDown(Self, Button, Shift, X, Y);
  661.   if Button = mbRight then
  662.   begin
  663.     //3/5/99 -PYW- Use the StatusBar's ClientToScreen conversion.
  664.     p := StatusBar.ClientToScreen(Point(x,y));
  665.     if PopupMenu <> nil then PopupMenu.Popup(p.x, p.y);
  666.   end;
  667. end;
  668. procedure TfcStatusPanel.PanelTextChanged(const Text:String);
  669. begin
  670.   if Assigned(FOnTextChanged) then FOnTextChanged(Self, Text);
  671. end;
  672. function TfcStatusPanel.ClientToScreen(p: TPoint): TPoint;
  673. var r: TRect;
  674. begin
  675.   r := GetRect;
  676.   result := Point(p.x + r.Left, p.y + r.Top);
  677.   result := StatusBar.ClientToScreen(result);
  678. end;
  679. procedure TfcStatusPanel.Draw(ACanvas: TCanvas; ARect: TRect);
  680. var RealCanvas: TCanvas;
  681.     RealRect: TRect;
  682.     {$ifdef fcUseThemeManager}
  683.     Details: TThemedElementDetails;
  684.     {$endif}
  685. begin
  686.   RealCanvas := FCanvas;
  687.   RealRect := FRect;
  688.   FCanvas := ACanvas;
  689.   FRect := ARect;
  690.   if ((FStyle in [psDate, psDateTime, psTime]) and DoDrawDateTime) or (FStyle <> psControl) then
  691.   begin
  692.     FCanvas.Brush.Color := FColor;
  693.     FCanvas.FillRect(FRect);
  694.   end;
  695.   {$ifdef fcUseThemeManager}
  696.   if fcUseThemes(StatusBar) then
  697. //  if ThemeServices.ThemesEnabled then
  698.   begin
  699.      Details := ThemeServices.GetElementDetails(tsPane);
  700.      ThemeServices.DrawElement(FCanvas.Handle, Details, FRect);
  701.   end;
  702.   {$endif}
  703.   case FStyle of
  704.     psTextOnly, psDate, psTime, psDateTime: DrawText(FText, FRect, Enabled);
  705.     psControl: DrawControl;
  706.     psOverWrite, psCapsLock, psNumLock, psScrollLock: DrawKeyboardState;
  707.     psGlyph: DrawGlyph;
  708.     psRichEditStatus: DrawRichEditStatus;
  709.     psHint,psHintContainerOnly: DrawHint;
  710.     psUserName: DrawUserName;
  711.     psComputerName: DrawComputerName;
  712.   end;
  713.   FCanvas := RealCanvas;
  714.   FRect := RealRect;
  715. end;
  716. procedure TfcStatusPanel.DrawText(AText: string; ARect: TRect; AEnabled:Boolean);
  717. const
  718.   Alignments: array[TAlignment] of Integer = (DT_LEFT, DT_RIGHT, DT_CENTER);
  719. begin
  720.   InflateRect(ARect, -2, 0);
  721.   inc(ARect.Left, Indent);
  722.   if FFont = nil then FCanvas.Font.Assign(StatusBar.Font) else FCanvas.Font.Assign(Font);
  723.   FTextOptions.Canvas := FCanvas;
  724.   FTextOptions.TextRect := ARect;
  725.   if FinDrawText then exit;
  726.   try
  727.     FInDrawText := True;
  728.     //3/11/99-PYW-Allow TextOptions to change in DrawText event without invalidating.
  729.     //4/7/99 - ksw - Fix bug that didn't reassign the invalidate callback
  730.     with FTextOptions,CallBacks do
  731.     begin
  732.       CallBacks := MakeCallBacks(nil,AdjustBounds,GetTextEnabled);
  733.       try
  734.         if Assigned(FOnDrawText) then FOnDrawText(self, AText, AEnabled);
  735.       finally
  736.         CallBacks := MakeCallBacks(self.Invalidate, self.AdjustBounds, self.GetTextEnabled);
  737.       end;
  738.     end;
  739.     FTextOptions.Canvas := FCanvas;
  740.     FTextOptions.Text := AText;
  741.     if AEnabled then FDrawTextEnabled := True
  742.     else FDrawTextEnabled := False;
  743.     FCanvas.Brush.Style := bsClear;
  744.     FTextOptions.Draw;
  745.   finally
  746.     FInDrawText := False;
  747.   end;
  748.   if AText <> FText then
  749.      PanelTextChanged(AText);
  750. end;
  751. procedure TfcStatusPanel.DrawControl;
  752. var r: TRect;
  753.   procedure InvalidateChildren(Control: TWinControl);
  754.   var i: integer;
  755.   begin
  756.     if fcUseThemes(StatusBar) then exit;  // 4/3/03 - Otherwise code below causes flicker
  757.                                      // Code below seems uncessary, but we leave it for now
  758.                                      // to be safe and not break any backwards functionality.
  759.                                      // Can later consider removing this.
  760.     Control.Invalidate;
  761.     for i := 0 to Control.ControlCount - 1 do
  762.        if Control.Controls[i] is TWinControl then
  763.           InvalidateChildren(Control.Controls[i] as TWinControl);
  764.   end;
  765. begin
  766.   if (Control = nil) or ((Statusbar <> nil) and (csLoading in StatusBar.ComponentState)) then
  767.     Exit;
  768.   if Control.Parent <> StatusBar then
  769.     Control.Parent := StatusBar;
  770.   DrawText(Text, FRect, Enabled);
  771.   r := FRect;
  772.   if Text <> '' then
  773.   begin
  774.     if TextOptions.Alignment = taLeftJustify then r.Left := TextOptions.TextRect.Right + 2  // !! Hard Code?
  775.     else if TextOptions.Alignment = taRightJustify then r.Right := TextOptions.TextRect.Left - 2;
  776.   end;
  777.   //3/5/99-PYW-Resize to Margin.
  778.   InflateRect(r,-Margin,-Margin);
  779.   if (fcRectWidth(r) > 0) and (fcRectHeight(r) > 0) then
  780.     Control.BoundsRect := r;
  781. {  with Control.BoundsRect do
  782.     if (Left <> r.Left) or (Right <> r.right) or
  783.        (Top <> r.top) or (Bottom <> r.Bottom) then
  784.       Control.BoundsRect := r;}
  785.   if (Control is TWinControl) then InvalidateChildren(Control as TWinControl);
  786. end;
  787. procedure TfcStatusPanel.DrawKeyboardState;
  788. var
  789.   Key: Integer;
  790.   AText: string;
  791. begin
  792.   Key := 0;
  793.   //3/11/99-PYW-Force TextChanged in DrawText to get called by making
  794.   //            sure FText<>AText
  795.   AText := FText;
  796.   FText := '';
  797.   case FStyle of
  798.     psOverwrite:  begin
  799.                     Key := VK_INSERT;
  800.                     AText := StatusBar.StatusBarText.Overwrite;
  801.                   end;
  802.     psCapsLock:   begin
  803.                     Key := VK_CAPITAL;
  804.                     AText := StatusBar.StatusBarText.CapsLock;
  805.                   end;
  806.     psNumLock:    begin
  807.                     Key := VK_NUMLOCK;
  808.                     AText := StatusBar.StatusBarText.NumLock;
  809.                   end;
  810.     psScrollLock: begin
  811.                     Key := VK_SCROLL;
  812.                     AText := StatusBar.StatusBarText.ScrollLock;
  813.                   end;
  814.   end;
  815. //  FEnabled := System.Odd(GetKeyState(Key));
  816.   if Assigned(StatusBar.FOnDrawKeyboardState) then
  817.      StatusBar.FOnDrawKeyboardState(StatusBar, self, System.Odd(GetKeyState(Key)), FRect, AText);
  818.   DrawText(AText,FRect, System.Odd(GetKeyState(Key)));
  819. end;
  820. procedure TfcStatusPanel.DrawHint;
  821. begin
  822.   if Style = psHintContainerOnly then
  823.     if not fcCanGetHint(StatusBar) then exit;
  824.   DrawText(Application.Hint, FRect, Enabled);
  825. //  Text := Application.Hint;
  826. end;
  827. procedure TfcStatusPanel.DrawUserName;
  828. var nsize:{$ifdef fcDelphi4up}Cardinal{$else}DWord{$endif};
  829.     UserName:String;
  830. begin
  831.   nsize := 25;
  832.   SetLength(UserName,nsize);
  833.   if GetUserName(PChar(UserName), nsize) then
  834.   begin
  835.      SetLength(UserName,nsize-1);
  836.      DrawText(UserName,FRect,Enabled);
  837.   end;
  838. end;
  839. procedure TfcStatusPanel.DrawComputerName;
  840. begin
  841.   DrawText(fcGetComputerName,FRect,Enabled);
  842. end;
  843. function TfcStatusPanel.DoDrawDateTime: Boolean;
  844. var AText: string;
  845. begin
  846.   AText := '';
  847.   //3/11/99-PYW-Make sure short date and short time formats are respected.
  848.   case FStyle of
  849.     psDate: begin
  850.               AText := DateToStr(Date);
  851.               FCurDateTime := Trunc(Date);
  852.             end;
  853.     psTime: begin
  854. //              AText := TimeToStr(Time);
  855.               DateTimeToString(AText,ShortTimeFormat,Now);
  856.               FCurDateTime := Frac(Time);
  857.             end;
  858.     psDateTime:
  859.             begin
  860. //              AText := DateTimeToStr(Now);
  861.               DateTimeToString(AText,ShortDateFormat+' ' + ShortTimeFormat,Now);
  862.               FCurDateTime := Now;
  863.             end;
  864.   end;
  865.   result := False;
  866.   if FText <> AText then
  867.   begin
  868.     FText := AText;
  869.     result := True;
  870.     PanelTextChanged(AText);
  871.   end;
  872. end;
  873. procedure TfcStatusPanel.DrawRichEditStatus;
  874. var AText: string;
  875. begin
  876.   AText := 'Ln: ' + IntToStr(FRow+1) + ', Col: ' + IntToStr(FCol+1);
  877.   DrawText(AText,FRect,Enabled);
  878. end;
  879. procedure TfcStatusPanel.DrawGlyph;
  880. var aLeft,aTop:Integer;
  881. begin
  882.   if (StatusBar.Images <> nil) and
  883.   (FImageIndex >= 0) and (FImageIndex < StatusBar.Images.Count) then
  884.   begin
  885.     ALeft := FRect.Left+FMargin;
  886.     ATop := FRect.Top+(((FRect.Bottom-FRect.Top)-TImageList(StatusBar.Images).height)div 2);
  887.     { RSW - 5/27/99 - Don't use StatusBar Canvas, but use StatusPanel Canvas }
  888.     fcImageListDraw(StatusBar.Images,FImageIndex,{StatusBar.}Canvas,ALeft,ATop,ILD_NORMAL,FEnabled);
  889.     FRect := Rect(FRect.Left+TImageList(StatusBar.Images).Width+5,FRect.Top,FRect.Right,FRect.Bottom);
  890.   end;
  891.   DrawText(FText,FRect,Enabled);
  892. end;
  893. function TfcStatusPanel.GetControl: TControl;
  894. begin
  895.   result := nil;
  896.   if Component is TControl then result := Component as TControl;
  897. end;
  898. function TfcStatusPanel.GetDisplayName: string;
  899. begin
  900.   Result := Name;
  901.   if Result = '' then Result := inherited GetDisplayName;
  902. end;
  903. {
  904. procedure TfcStatusPanel.SetPriority(Value: Integer);
  905. var APanel: TfcStatusPanel;
  906. begin
  907.   if Value < 1 then Value := 1;
  908.   if Value > StatusBar.Panels.Count then Value := StatusBar.Panels.Count;
  909.   if FPriority <> Value then
  910.   begin
  911.     StatusBar.Panels.BeginUpdate;
  912.     APanel := StatusBar.GetPriorityPanel(Value);
  913.     FPriority := Value;
  914.     if APanel <> nil then APanel.Priority := Value + 1;
  915.     StatusBar.Panels.EndUpdate;
  916.     Changed(True);
  917.   end;
  918. end;
  919. }
  920. procedure TfcStatusPanel.SetBevel(Value: TfcStatusPanelBevel);
  921. begin
  922.   if FBevel <> Value then
  923.   begin
  924.     FBevel := Value;
  925.     Changed(False);
  926.   end;
  927. end;
  928. procedure TfcStatusPanel.SetColor(Value: TColor);
  929. begin
  930.   if FColor <> Value then
  931.   begin
  932.     FColor := Value;
  933.     Changed(False);
  934.   end;
  935. end;
  936. procedure TfcStatusPanel.SetComponent(Value: TComponent);
  937. begin
  938.   if (Value = nil) and (Component = nil) then Exit;
  939.   if (Value = StatusBar) then
  940.     raise EInvalidOperation.Create('Control cannot equal parent StatusBar');
  941.   //8/14/2000 - PYW - Don't change the parents for richedit controls.
  942.   if (Control <> nil) and not (csDestroying in Control.ComponentState) and
  943.      (Style <> psRichEditStatus) then
  944.     if GetParentForm(StatusBar)<>nil then // 1/24/01 - RSW
  945.        Control.Parent := GetParentForm(StatusBar);
  946.   FComponent := Value;
  947.   if FComponent = nil then FStyle := psTextOnly
  948.   else if (FComponent is TCustomRichEdit) then
  949.   begin
  950.     Style := psRichEditStatus;
  951.   end else if (FComponent is TControl) then begin
  952.     if (Control <> Value) and (StatusBar <> nil) then
  953.       Control.Parent := StatusBar.Parent;
  954.     Style := psControl;
  955.   end;
  956.   Changed(False);
  957. end;
  958. procedure TfcStatusPanel.SetEnabled(Value: Boolean);
  959. begin
  960.   if FEnabled <> Value then
  961.   begin
  962.     FEnabled := Value;
  963.     if (FStyle = psControl) and (Control <> nil) then
  964.       Control.Enabled := Value;
  965.     Changed(False);
  966.   end;
  967. end;
  968. procedure TfcStatusPanel.SetImageIndex(Value: Integer);
  969. begin
  970.   if FImageIndex <> Value then
  971.   begin
  972.     FImageIndex := Value;
  973.     Changed(False);
  974.   end;
  975. end;
  976. procedure TfcStatusPanel.SetMargin(Value: Integer);
  977. begin
  978.   if FMargin <> Value then
  979.   begin
  980.     FMargin := Value;
  981.     Changed(False);
  982.   end;
  983. end;
  984. procedure TfcStatusPanel.SetIndent(Value: Integer);
  985. begin
  986.   if FIndent <> Value then
  987.   begin
  988.     FIndent := Value;
  989.     Changed(False);
  990.   end;
  991. end;
  992. procedure TfcStatusPanel.SetStyle(Value: TfcStatusPanelStyle);
  993. var i:integer;
  994.     TimerNeeded:Boolean;
  995. begin
  996.   if FStyle <> Value then
  997.   begin
  998.     //3/11/99 - Only kill richedit timer if no longer needed.
  999.     if (StatusBar.HandleAllocated) and (FStyle = psRichEditStatus) then
  1000.     begin
  1001.        TimerNeeded := False;
  1002.        for i:= 0 to StatusBar.Panels.Count-1 do
  1003.           if (StatusBar.Panels[i]<>Self) and
  1004.              (StatusBar.Panels[i].Style = psRichEditStatus) then
  1005.                 TimerNeeded := True;
  1006.        if not TimerNeeded then KillTimer(StatusBar.Handle, RICHEDIT_TIMER_ID);
  1007.     end;
  1008.     //3/11/99 - Only kill hint timer if no longer needed.
  1009.     if (StatusBar.HandleAllocated) and ((FStyle = psHint) or (FStyle=psHintContainerOnly)) then
  1010.     begin
  1011.        TimerNeeded := False;
  1012.        for i:= 0 to StatusBar.Panels.Count-1 do
  1013.           if (StatusBar.Panels[i]<>Self) and
  1014.              ((StatusBar.Panels[i].Style = psHint) or (StatusBar.Panels[i].Style=psHintContainerOnly))then
  1015.                 TimerNeeded := True;
  1016.        if not TimerNeeded then KillTimer(StatusBar.Handle, HINT_TIMER_ID);
  1017.     end;
  1018.     //3/11/99 -PYW- Only kill date/time timer if no longer needed.
  1019.     if (StatusBar.HandleAllocated) and (FStyle in [psDate,psTime,psDateTime]) then
  1020.     begin
  1021.        TimerNeeded := False;
  1022.        for i:= 0 to StatusBar.Panels.Count-1 do
  1023.           if (StatusBar.Panels[i]<>Self) and
  1024.              (StatusBar.Panels[i].Style in [psDate,psTime,psDateTime]) then
  1025.                 TimerNeeded := True;
  1026.        if not TimerNeeded then KillTimer(StatusBar.Handle, TIMER_ID);
  1027.     end;
  1028.     FStyle := Value;
  1029.     case FStyle of
  1030.       psOverwrite:; //FText := 'Overwrite';  //3/11/99 -PYW- No longer needed. Handled in DrawKeyboardState
  1031.       psCapslock:; //FText := 'Caps';
  1032.       psNumlock:; //FText := 'Num';
  1033.       psScrollLock:; //FText := 'Scroll';
  1034.       psControl: StatusBar.ComponentExclusive(FComponent, self, False);
  1035.       psHint,psHintContainerOnly: if StatusBar.HandleAllocated and not (csDesigning in StatusBar.ComponentState) then
  1036.         SetTimer(StatusBar.Handle, HINT_TIMER_ID, 100, nil);
  1037.       psDate,psTime,psDateTime: if StatusBar.HandleAllocated and not (csDesigning in StatusBar.ComponentState) then
  1038.         SetTimer(StatusBar.Handle, TIMER_ID, 1000, nil);
  1039.       psRichEditStatus:
  1040.         if StatusBar.HandleAllocated and not (csDesigning in StatusBar.ComponentState) then
  1041.            SetTimer(StatusBar.Handle, RICHEDIT_TIMER_ID, 100, nil);
  1042.     end;
  1043.     Changed(False);
  1044.   end;
  1045. end;
  1046. (*procedure TfcStatusPanel.ParentWndProc(var Message: TMessage);
  1047. //var MenuItem: TMenuItem;
  1048. begin
  1049.   { RSW - 2/1/99 }
  1050.   if (csDestroying in TfcStatusPanels(Collection).StatusBar.ComponentState) then exit;
  1051.   case Message.Msg of
  1052.     WM_NOTIFY: if Component is TCustomRichEdit then
  1053.       with TWMNotify(Message).NMHdr^,
  1054.            (Control as TCustomRichEdit) do
  1055.         if (Code = EN_SELCHANGE) and
  1056.            (HwndFrom = Handle) then
  1057.         begin
  1058.           FRow := SendMessage(Handle, EM_LINEFROMCHAR, SelStart, 0);
  1059.           FCol := SelStart - SendMessage(Handle, EM_LINEINDEX, FRow, 0);
  1060.           self.Invalidate;
  1061.         end;
  1062. {    WM_MENUSELECT: if (Style = psMenu) and (Component is TMainMenu) then
  1063.       with TWMMenuSelect(Message) do
  1064.     begin
  1065.       if ((MenuFlag and $FFFF) = $FFFF) and (Menu = 0) then Text := ''
  1066.       else begin
  1067.         if not ((MenuFlag and MF_POPUP) = MF_POPUP) then MenuItem := (FComponent as TMainMenu).FindItem(IDItem, fkCommand)
  1068.         else begin
  1069.           if (FComponent as TMainMenu).Handle = Menu then MenuItem := (FComponent as TMainMenu).Items
  1070.           else MenuItem := (FComponent as TMainMenu).FindItem(Menu, fkHandle);
  1071.           if MenuItem <> nil then MenuItem := MenuItem.Items[IDItem];
  1072.         end;
  1073.         if MenuItem <> nil then Text := GetLongHint(MenuItem.Hint);
  1074.       end;
  1075.     end;}
  1076.   end;
  1077. end;
  1078. *)
  1079. function TfcStatusPanel.GetTextEnabled: Boolean;
  1080. begin
  1081.   result := FDrawTextEnabled;
  1082. end;
  1083. procedure TfcStatusPanel.AdjustBounds;
  1084. begin
  1085. end;
  1086. procedure TfcStatusPanel.SetName(const Value: string);
  1087. begin
  1088.   if FName <> Value then
  1089.   begin
  1090.     if (StatusBar.Panels.PanelByName(Value) <> nil) then
  1091.       raise EInvalidOperation.CreateFmt('A panel named %s already exists.', [Value]);
  1092.     FName := Value;
  1093.     Changed(False);
  1094.     if Assigned(FOnSetName) then FOnSetName(self);
  1095.   end;
  1096. end;
  1097. procedure TfcStatusPanel.SetText(const Value: string);
  1098. begin
  1099.   if FText <> Value then
  1100.   begin
  1101.     FText := Value;
  1102.     PanelTextChanged(Value);
  1103.     Invalidate;
  1104.   end;
  1105. end;
  1106. procedure TfcStatusPanel.SetFont(Value: TFont);
  1107. begin
  1108.   if FFont <> Value then
  1109.   begin
  1110.     FFont.Assign(Value);
  1111.     //3/5/99 -PYW - Also set the Control's Font property.
  1112.     if (FStyle = psControl) and (Control <> nil) then
  1113.        TEdit(Control).Font.Assign(Value);
  1114.     Changed(False);
  1115.   end;
  1116. end;
  1117. procedure TfcStatusPanel.SetHint(Value: String);
  1118. begin
  1119.   if FHint <> Value then
  1120.   begin
  1121.     FHint := Value;
  1122.     //3/5/99 -PYW - Also set the Control's Hint property.
  1123.     if (FStyle = psControl) and (Control <> nil) then
  1124.        Control.Hint := Value;
  1125.     Changed(False);
  1126.   end;
  1127. end;
  1128. procedure TfcStatusPanel.SetWidth(Value: string);
  1129. var AWidth: Integer;
  1130. begin
  1131.   if FWidth <> Value then
  1132.   begin
  1133.     // Validate Width
  1134.     AWidth := StrToIntDef(Value, -1);
  1135.     if AWidth = -1 then
  1136.     begin
  1137.       AWidth := StrToIntDef(Copy(Value, 1, Length(Value) - 1), -1);
  1138.       if (AWidth = -1) or (Copy(Value, Length(Value), 1) <> '%') then
  1139.         raise EInvalidOperation.Create('Width must be a valid, positive integer, or must be an integer followed by a "%" sign.');
  1140.     end;
  1141.     FWidth := Value;
  1142.     PaintWidth := StrToIntDef(Value, 0);
  1143.     StatusBar.Resize;
  1144.     Changed(True);
  1145.   end;
  1146. end;
  1147. function TfcStatusPanel.GetRect: TRect;
  1148. begin
  1149.   SendMessage(StatusBar.Handle, SB_GETRECT, Index, LPARAM(@result));
  1150. end;
  1151. procedure TfcStatusPanel.Invalidate;
  1152. var r: TRect;
  1153.     DrawBitmap: TBitmap;
  1154.     ACanvas: TCanvas;
  1155.     TempWidth: Integer;
  1156. begin
  1157.   if csLoading in StatusBar.ComponentState then Exit;
  1158.   r := GetRect;
  1159.   if not StatusBar.FSizing then if Style in [psDate, psDateTime, psTime] then
  1160.     case FStyle of
  1161.       psDate: if Trunc(Date) = FCurDateTime then Exit;
  1162.       psTime: if Frac(Date) = FCurDateTime then Exit;
  1163.       psDateTime: if Now = FCurDateTime then Exit;
  1164.     end;
  1165.   DrawBitmap := TBitmap.Create;
  1166.   ACanvas := TCanvas.Create;
  1167.   try
  1168.     //3/5/99-Need to get the system metrics for the scrollbar thumb.
  1169.     //4/26/99 - Only shrink width if last panel and sizegrip is true.
  1170.     if StatusBar.SizeGrip and (StatusBar.Panels[StatusBar.Panels.Count-1]=self) then
  1171.        TempWidth := fcRectWidth(FRect) - fcMin(23,GetSystemMetrics(SM_CXVSCROLL)+1)
  1172.     else TempWidth := fcRectWidth(FRect);
  1173.     if TempWidth > 0 then DrawBitmap.Width := TempWidth else Exit;
  1174.     DrawBitmap.Height := fcRectHeight(FRect);
  1175.     Draw(DrawBitmap.Canvas, Rect(0, 0, DrawBitmap.Width, DrawBitmap.Height));
  1176.     ACanvas.Handle := GetDC(StatusBar.Handle);
  1177.     ACanvas.Draw(FRect.Left, FRect.Top, DrawBitmap);
  1178.     ReleaseDC(StatusBar.Handle, ACanvas.Handle);
  1179.   finally
  1180.     ACanvas.Free;
  1181.     DrawBitmap.Free;
  1182.   end;
  1183. end;
  1184. { TfcStatusPanels }
  1185. constructor TfcStatusPanels.Create(StatusBar: TfcCustomStatusBar; AStatusPanelClass: TfcStatusPanelClass);
  1186. begin
  1187.   inherited Create(AStatusPanelClass);
  1188.   FStatusBar := StatusBar;
  1189. end;
  1190. procedure TfcStatusPanels.RedrawIfNeeded(StyleToCheck: TfcStatusPanelStyle);
  1191. var i: integer;
  1192. begin
  1193.   for i := 0 to Count - 1 do
  1194.     if Items[i].FStyle = StyleToCheck then
  1195.       Items[i].Invalidate;
  1196. end;
  1197. function TfcStatusPanels.PanelByName(AName:String): TfcStatusPanel;
  1198. var i: Integer;
  1199. begin
  1200.   result := nil;
  1201.   for i := 0 to Count - 1 do
  1202.     if Items[i].Name = AName then
  1203.       result := Items[i];
  1204. end;
  1205. function TfcStatusPanels.Add: TfcStatusPanel;
  1206. begin
  1207.   result := TfcStatusPanel(inherited Add);
  1208. end;
  1209. function TfcStatusPanels.GetItem(Index: Integer): TfcStatusPanel;
  1210. begin
  1211.   result := TfcStatusPanel(inherited GetItem(Index));
  1212. end;
  1213. function TfcStatusPanels.GetOwner: TPersistent;
  1214. begin
  1215.   result := FStatusBar;
  1216. end;
  1217. procedure TfcStatusPanels.SetItem(Index: Integer; Value: TfcStatusPanel);
  1218. begin
  1219.   inherited SetItem(Index, Value);
  1220. end;
  1221. procedure TfcStatusPanels.Update(Item: TCollectionItem);
  1222. begin
  1223.   if Item <> nil then
  1224.     FStatusBar.UpdatePanel(Item.Index, True) else
  1225.     FStatusBar.UpdatePanels;
  1226. end;
  1227. { TfcCustomStatusBar }
  1228. constructor TfcCustomStatusBar.Create(AOwner: TComponent);
  1229. begin
  1230.   inherited Create(AOwner);
  1231.   ControlStyle := [csCaptureMouse, csClickEvents, csDoubleClicks, csOpaque];
  1232.   // 5/06/99 - PYW - Added StatusBarText property.
  1233.   FStatusBarText:= TfcStatusBarText.Create(Self);
  1234.   with FStatusBarText do
  1235.   begin
  1236.      CapsLock := 'Caps';
  1237.      Overwrite := 'Overwrite';
  1238.      NumLock := 'Num';
  1239.      ScrollLock := 'Scroll';
  1240.   end;
  1241.   Color := clBtnFace;
  1242.   Height := 20;
  1243.   Align := alBottom;
  1244.   FPanels := GetCollectionClass.Create(self, TfcStatusPanel);
  1245.   FCanvas := TControlCanvas.Create;
  1246.   TControlCanvas(FCanvas).Control := Self;
  1247.   FSizeGrip := True;
  1248.   StatusBars.Add(self);
  1249. end;
  1250. destructor TfcCustomStatusBar.Destroy;
  1251. begin
  1252.   if StatusBars<>nil then { 7/11/99 }
  1253.      StatusBars.Delete(StatusBars.IndexOf(self));
  1254.   FPanels.Free;
  1255.   FCanvas.Free;
  1256.   // 5/06/99 - PYW - Added StatusBarText property.
  1257.   FStatusBarText.Free;
  1258.   inherited Destroy;
  1259. end;
  1260. function InitCommonControl(CC: Integer): Boolean;
  1261. var
  1262.   ICC: TInitCommonControlsEx;
  1263. begin
  1264.   ICC.dwSize := SizeOf(TInitCommonControlsEx);
  1265.   ICC.dwICC := CC;
  1266.   Result := InitCommonControlsEx(ICC);
  1267.   if not Result then InitCommonControls;
  1268. end;
  1269. procedure TfcCustomStatusBar.CreateParams(var Params: TCreateParams);
  1270. const
  1271.   GripStyles: array[Boolean] of DWORD = (CCS_TOP, SBARS_SIZEGRIP);
  1272. begin
  1273.   InitCommonControl(ICC_BAR_CLASSES);
  1274.   inherited CreateParams(Params);
  1275.   CreateSubClass(Params, STATUSCLASSNAME);
  1276.   with Params do
  1277.   begin
  1278.     //4/26/99 - PYW - Show sizegrip only if sizeable window.
  1279.     Style := Style or GripStyles[FSizeGrip and (Parent is TCustomForm) and
  1280.              (TForm(Parent).BorderStyle in [bsSizeable, bsSizeToolWin])];
  1281. {    if FSizeGrip then
  1282.       Style := Style or SBARS_SIZEGRIP else
  1283.       Style := Style or CCS_TOP;}
  1284.     if fcUseThemes(self) then //ThemeServices.ThemesEnabled then
  1285.       WindowClass.style := WindowClass.style or CS_HREDRAW or CS_VREDRAW
  1286.     else
  1287.       WindowClass.style := WindowClass.style and not CS_HREDRAW;
  1288.   end;
  1289. end;
  1290. procedure TfcCustomStatusBar.Loaded;
  1291. begin
  1292.   inherited;
  1293.   Resize;
  1294. end;
  1295. procedure TfcCustomStatusBar.DestroyWnd;
  1296. begin
  1297.   SendMessage(Handle, SB_SETTEXT, 0, Integer(PChar('')));
  1298.   KillTimer(Handle, TIMER_ID);
  1299.   KillTimer(Handle, HINT_TIMER_ID);
  1300.   KillTimer(Handle, RICHEDIT_TIMER_ID);
  1301.   inherited DestroyWnd;
  1302. end;
  1303. procedure TfcCustomStatusBar.CreateWnd;
  1304. var i: Integer;
  1305.     FoundDate, FoundHint, FoundRichEdit: boolean;
  1306. begin
  1307.   inherited CreateWnd;
  1308.   UpdatePanels;
  1309.   if FSimpleText <> '' then SendMessage(Handle, SB_SETTEXT, 255, Integer(PChar(FSimpleText)));
  1310.   if FSimplePanel then SendMessage(Handle, SB_SIMPLE, 1, 0);
  1311.   FoundRichEdit:= False;
  1312.   FoundHint:= False;
  1313.   FoundDate:= False; { 4/27/99 - RSW (Fix bug where only one timer was set }
  1314.   if not (csDesigning in ComponentState) then
  1315.     for i := 0 to Panels.Count - 1 do
  1316.       if (not FoundHint) and ((Panels[i].Style = psHint)or(Panels[i].Style=psHintContainerOnly)) then
  1317.       begin
  1318.         SetTimer(Handle, HINT_TIMER_ID, 100, nil);
  1319.         FoundHint:= True;
  1320.       end //3/11/99 - PYW - Timer for datetime styles never set so set it.
  1321.       else if (not FoundDate) and (Panels[i].Style in [psDate,psTime,psDateTime]) then
  1322.       begin
  1323.         //4/27/99 - PYW - Update Timer to 1000 to be consistent.
  1324.         SetTimer(Handle, TIMER_ID, 1000, nil);
  1325.         FoundDate:= True;
  1326.       end
  1327.       else if (not FoundRichEdit) and (Panels[i].Style = psRichEditStatus) then
  1328.       begin
  1329.         SetTimer(Handle, RICHEDIT_TIMER_ID, 100, nil);
  1330.         FoundRichEdit:= True;
  1331.       end
  1332. end;
  1333. procedure TfcCustomStatusBar.DrawPanel(Panel: TfcStatusPanel; Rect: TRect);
  1334. begin
  1335.   Panel.FCanvas := Canvas;
  1336.   Panel.FRect := Rect;
  1337.   //4/26/99 - Only shrink width if last panel and sizegrip is true.
  1338.   if SizeGrip and (Panels[Panels.Count-1]=Panel) then
  1339.      Rect.Right := Rect.Right-fcMin(23,GetSystemMetrics(SM_CXVSCROLL)+1);
  1340.   Panel.Draw(Canvas, Rect);
  1341.   if Assigned(FOnDrawPanel) then FOnDrawPanel(Self, Panel, Rect);
  1342. end;
  1343. procedure TfcCustomStatusBar.Click;
  1344. var Panel: TfcStatusPanel;
  1345. begin
  1346.   Panel := GetPanelFromPt(-1, -1);
  1347.   if (Panel <> nil) then Panel.Click;
  1348.   inherited;
  1349. end;
  1350. procedure TfcCustomStatusBar.DblClick;
  1351. var Panel: TfcStatusPanel;
  1352. begin
  1353.   Panel := GetPanelFromPt(-1, -1);
  1354.   if (Panel <> nil) then Panel.DblClick;
  1355.   inherited;
  1356. end;
  1357. procedure TfcCustomStatusBar.SetPanels(Value: TfcStatusPanels);
  1358. begin
  1359.   FPanels.Assign(Value);
  1360. end;
  1361. procedure TfcCustomStatusBar.SetSimplePanel(Value: Boolean);
  1362. begin
  1363.   if FSimplePanel <> Value then
  1364.   begin
  1365.     FSimplePanel := Value;
  1366.     if HandleAllocated then
  1367.       SendMessage(Handle, SB_SIMPLE, Ord(FSimplePanel), 0);
  1368.   end;
  1369. end;
  1370. procedure TfcCustomStatusBar.SetSimpleText(const Value: string);
  1371. begin
  1372.   if FSimpleText <> Value then
  1373.   begin
  1374.     FSimpleText := Value;
  1375.     if HandleAllocated then
  1376.       SendMessage(Handle, SB_SETTEXT, 255, Integer(PChar(FSimpleText)));
  1377.   end;
  1378. end;
  1379. //4/26/99 - PYW - Show sizegrip only if sizeable window.
  1380. function TfcCustomStatusBar.GetSizeGrip:Boolean;
  1381. begin
  1382.    result := FSizeGrip and (Parent is TCustomForm) and
  1383.       (TForm(Parent).BorderStyle in [bsSizeable, bsSizeToolWin]);
  1384. end;
  1385. procedure TfcCustomStatusBar.SetSizeGrip(Value: Boolean);
  1386. begin
  1387.   if FSizeGrip <> Value then
  1388.   begin
  1389.     FSizeGrip := Value;
  1390.     {if not (csLoading in ComponentState) then }RecreateWnd;
  1391.   end;
  1392. end;
  1393. procedure TfcCustomStatusBar.UpdatePanel(Index: Integer; DoInvalidate: Boolean);
  1394. var
  1395.   Flags: Integer;
  1396.   S: string;
  1397.   r: TRect;
  1398. begin
  1399.   if HandleAllocated then
  1400.     with Panels[Index] do
  1401.     begin
  1402.       Flags := 0;
  1403.       case Bevel of
  1404.         pbNone: Flags := SBT_NOBORDERS;
  1405.         pbRaised: Flags := SBT_POPOUT;
  1406.       end;
  1407.       Flags := Flags or SBT_OWNERDRAW;
  1408.       s := Text;
  1409.       case TextOptions.Alignment of
  1410.         taCenter: s := #9 + S;
  1411.         taRightJustify: s := #9#9 + S;
  1412.       end;
  1413.       SendMessage(Handle, SB_SETTEXT, Index or Flags, Integer(PChar(S)));
  1414.       if DoInvalidate then
  1415.       begin
  1416.         r := GetRect;
  1417.         InvalidateRect(Handle, @r, True);
  1418.       end;
  1419.     end;
  1420. end;
  1421. procedure TfcCustomStatusBar.UpdatePanels;
  1422. const
  1423.   MaxPanelCount = 128;
  1424. var
  1425.   I, Count, PanelPos: Integer;
  1426.   PanelEdges: array[0..MaxPanelCount - 1] of Integer;
  1427. begin
  1428.   if HandleAllocated then
  1429.   begin
  1430.     Count := Panels.Count;
  1431.     if Count > MaxPanelCount then Count := MaxPanelCount;
  1432.     if Count = 0 then
  1433.     begin
  1434.       PanelEdges[0] := -1;
  1435.       SendMessage(Handle, SB_SETPARTS, 1, Integer(@PanelEdges));
  1436.       SendMessage(Handle, SB_SETTEXT, 0, Integer(PChar('')));
  1437.     end else
  1438.     begin
  1439.       PanelPos := 0;
  1440.       for I := 0 to Count - 2 do
  1441.       begin
  1442.         Inc(PanelPos, Panels[I].PaintWidth);
  1443.         PanelEdges[I] := PanelPos;
  1444.       end;
  1445.       PanelEdges[Count - 1] := -1;
  1446.       SendMessage(Handle, SB_SETPARTS, Count, Integer(@PanelEdges));
  1447.       for I := 0 to Count - 1 do UpdatePanel(I, False);
  1448. //      InvalidateRect(Handle, nil, True);
  1449. //      Invalidate;
  1450.     end;
  1451.   end;
  1452. end;
  1453. procedure TfcCustomStatusBar.CMShowingChanged(var Message: TMessage);
  1454. begin
  1455.   inherited;
  1456. end;
  1457. procedure TfcCustomStatusBar.CNDrawItem(var Message: TWMDrawItem);
  1458. var
  1459.   SaveIndex: Integer;
  1460.   PanelEdges: array[0..255 - 1] of Integer;
  1461.   ACount: Integer;
  1462. begin
  1463.   FillChar(PanelEdges, SizeOf(PanelEdges), 0);
  1464.   ACount := SendMessage(Handle, SB_GETPARTS, Panels.Count, Integer(@PanelEdges));
  1465.   if ACount <> Panels.Count then RecreateWnd;
  1466.   with Message.DrawItemStruct^ do
  1467.   begin
  1468.     SaveIndex := SaveDC(hDC);
  1469.     FCanvas.Handle := hDC;
  1470.     FCanvas.Font := Font;
  1471.     FCanvas.Brush.Color := clBtnFace;
  1472.     FCanvas.Brush.Style := bsSolid;
  1473.     DrawPanel(Panels[itemID], rcItem);//Rect(Left, Top - 1, Right, Bottom));
  1474.     FCanvas.Handle := 0;
  1475.     RestoreDC(hDC, SaveIndex);
  1476.   end;
  1477.   Message.Result := 1;
  1478. end;
  1479. procedure TfcCustomStatusBar.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  1480.   {$ifdef fcUseThemeManager}
  1481. var
  1482.   Details: TThemedElementDetails;
  1483.   {$endif}
  1484. begin
  1485.   {$ifdef fcUseThemeManager}
  1486.   if ThemeServices.ThemesEnabled then
  1487.   begin
  1488.     Details := ThemeServices.GetElementDetails(tsStatusRoot);
  1489.     ThemeServices.DrawElement(Message.DC, Details, ClientRect, nil);
  1490.     Message.Result := 1;
  1491.   end
  1492.   else
  1493.   {$endif}
  1494.     inherited;
  1495. end;
  1496. procedure TfcCustomStatusBar.WMSize(var Message: TWMSize);
  1497. var i: Integer;
  1498. begin
  1499.   FSizing := True;
  1500.   if (Parent = nil) or ([csLoading, csDestroying] * ComponentState <> []) then Exit;
  1501.   if not (csLoading in ComponentState) then Resize;
  1502.   for i := 0 to Panels.Count - 1 do
  1503.     if (Panels[i].Control = nil) or (Panels[i].Control is TCustomRichEdit) then
  1504.       Panels[i].Invalidate;
  1505.   FSizing := False;
  1506. //      DrawPanel(Panels[i],Panels[i].FRect);
  1507. //3/5/99-PYW-Causes a lot of unnecessary flicker.  Does not seem to be needed.
  1508. {  with FPanels do
  1509.     for i := 0 to Count - 1 do
  1510.       if (Items[i] as TfcStatusPanel).Control <> nil then
  1511.         DrawPanel(Items[i] as TfcStatusPanel,
  1512.           Rect((Items[i] as TfcStatusPanel).FRect.Left + (fpanels.items[i] as TfcStatusPanel).Margin,
  1513.                (Items[i] as TfcStatusPanel).FRect.Top + (fpanels.items[i] as TfcStatusPanel).Margin,
  1514.                (Items[i] as TfcStatusPanel).FRect.right-(fpanels.items[i] as TfcStatusPanel).Margin,
  1515.                (Items[i] as TfcStatusPanel).FRect.Bottom-(fpanels.items[i] as TfcStatusPanel).Margin));}
  1516. end;
  1517. procedure TfcCustomStatusBar.Notification(AComponent: TComponent; Operation: TOperation);
  1518. var i: Integer;
  1519. begin
  1520.   inherited Notification(AComponent, Operation);
  1521.   if AComponent <> self then
  1522.     for i := 0 to Panels.Count - 1 do Panels[i].Notification(AComponent, Operation);
  1523.   if (Operation = opRemove) and (FImageList = AComponent) then
  1524.     Images := nil;
  1525. end;
  1526. procedure TfcCustomStatusBar.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  1527. var Panel: TfcStatusPanel;
  1528. begin
  1529.   Panel := GetPanelFromPt(-1, -1);
  1530.   if (Panel <> nil) then Panel.MouseUp(Button, Shift, X, Y);
  1531.   inherited;
  1532. end;
  1533. procedure TfcCustomStatusBar.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  1534. var Panel: TfcStatusPanel;
  1535. begin
  1536.   Panel := GetPanelFromPt(-1, -1);
  1537.   if (Panel <> nil) then Panel.MouseDown(Button, Shift, X, Y);
  1538.   inherited;
  1539. end;
  1540. procedure TfcCustomStatusBar.MouseMove(Shift: TShiftState; X, Y: Integer);
  1541. var Panel: TfcStatusPanel;
  1542. begin
  1543.   Panel := GetPanelFromPt(-1, -1);
  1544.   if (Panel <> nil) then Panel.MouseMove(Shift, X, Y);
  1545.   inherited;
  1546. end;
  1547. procedure TfcCustomStatusBar.WndProc(var Message: TMessage);
  1548. begin
  1549.   if (csDesigning in ComponentState) then
  1550.     if (Message.Msg = WM_LBUTTONDOWN) then
  1551.      Invalidate;
  1552.   inherited;
  1553. end;
  1554. function TfcCustomStatusBar.GetPanelFromPt(x, y: Integer): TfcStatusPanel;
  1555. var i: integer;
  1556. begin
  1557.   result := nil;
  1558.   if (x = -1) and (y = -1) then
  1559.     with fcGetCursorPos do
  1560.       with ScreenToClient(Point(x, y)) do
  1561.         result := GetPanelFromPt(x, y)
  1562.   else for i := 0 to Panels.Count - 1 do
  1563.     if PtInRect(Panels[i].GetRect, Point(x, y)) then
  1564.     begin
  1565.       result := Panels[i];
  1566.       Break;
  1567.     end;
  1568. end;
  1569. procedure TfcCustomStatusBar.WMTimer(var Message: TWMTimer);
  1570. var i: Integer;
  1571.     RichEdit: TCustomRichEdit;
  1572.     TempRow, TempCol, TempColBasedOnRow: integer;
  1573. //    cmp:TComponent;
  1574. begin
  1575.   case Message.TimerID of
  1576.     TIMER_ID: for i := 0 to Panels.Count - 1 do
  1577.       if Panels[i].Style in [psDate, psTime, psDateTime] then
  1578.         Panels[i].Invalidate;
  1579.     RICHEDIT_TIMER_ID: for i := 0 to Panels.Count - 1 do
  1580.       if (Panels[i].Style = psRichEditStatus) and
  1581.          (Panels[i].Component is TCustomRichEdit) then
  1582.       begin
  1583.          RichEdit:= TCustomRichEdit(Panels[i].Component);
  1584.          with Panels[i] do begin
  1585.             TempRow := SendMessage(RichEdit.Handle, EM_LINEFROMCHAR, RichEdit.SelStart, 0);
  1586.             TempCol := RichEdit.SelStart - SendMessage(RichEdit.Handle, EM_LINEINDEX, -1, 0);
  1587.             { 5/7/99 - RSW - Fix bug in RichEdit control where it makes row 1 too big }
  1588.             { This can happen if you enter vk_home on a line that does not end a paragraph}
  1589.             TempColBasedOnRow := RichEdit.SelStart - SendMessage(RichEdit.Handle, EM_LINEINDEX, TempRow, 0);
  1590.             if TempCol<>TempColBasedOnRow then dec(TempRow);
  1591.             if (TempRow<>FRow) or (TempCol<>FCol) then
  1592.             begin
  1593.                FRow:= TempRow;
  1594.                FCol:= TempCol;
  1595.                Panels[i].Invalidate;
  1596.             end;
  1597.          end
  1598.       end;
  1599.     HINT_TIMER_ID:
  1600.       begin
  1601.         for i := 0 to Panels.Count - 1 do
  1602.         if (Panels[i].Style = psHint) or (Panels[i].Style=psHintContainerOnly) then
  1603.         begin
  1604.           if Panels[i].Style = psHintContainerOnly then
  1605.              if not fcCanGetHint(Self) then continue;
  1606.           Panels[i].Text := Application.Hint;
  1607.         end;
  1608.       end;
  1609.   end;
  1610. end;
  1611. function TfcCustomStatusBar.GetCollectionClass: TfcStatusPanelsClass;
  1612. begin
  1613.   result := TfcStatusPanels;
  1614. end;
  1615. procedure TfcCustomStatusBar.ComponentExclusive(Value: TComponent; Panel: TfcStatusPanel; ThisStatusBarOnly: Boolean);
  1616. var i: Integer;
  1617. begin
  1618.   // Check to see if another panel already contains this Control.  If so, then
  1619.   // Remove it from the other panel and let this procedure reassign it.
  1620.   for i := 0 to Panels.Count - 1 do
  1621.     if (Panels[i].Component = Value) and (Panels[i] <> Panel) then
  1622.       Panels[i].Component := nil;
  1623.   // Check to see if a different StatusBar Panel already contains this Control.
  1624.   // If so, then remove it from the other panel and let this procedure reassign it.
  1625.   if not ThisStatusBarOnly then for i := 0 to StatusBars.Count - 1 do
  1626.     if StatusBars[i] <> self then
  1627.       TfcStatusBar(StatusBars[i]).ComponentExclusive(Value, Panel, True);
  1628. end;
  1629. {
  1630. function TfcCustomStatusBar.GetPriorityPanel(APriority: Integer): TfcStatusPanel;
  1631. var i: Integer;
  1632. begin
  1633.   result := nil;
  1634.   for i := 0 to Panels.Count - 1 do
  1635.   begin
  1636.     if Panels[i].Priority = APriority then
  1637.     begin
  1638.       result := Panels[i];
  1639.       Break;
  1640.     end;
  1641.   end;
  1642. end;
  1643. }
  1644. procedure TfcCustomStatusBar.Resize;
  1645. var TotalWidths: Integer;
  1646.     i: Integer;
  1647.     r: TRect;
  1648.     UpdateFlag: Boolean;
  1649. begin
  1650.   {$ifdef fcDelphi3}
  1651.   if Assigned(FOnResize) then FOnResize(Self);
  1652.   {$else}
  1653.   inherited;
  1654.   {$endif}
  1655.   if (csLoading in ComponentState) or (Width = 0) then Exit;
  1656.   TotalWidths := 0;
  1657.   for i := 0 to Panels.Count - 1 do
  1658.   begin
  1659.     Panels[i].PaintWidth := fcMin(Width - TotalWidths, StrtoIntDef(Panels[i].Width, -1));
  1660.     if Panels[i].PaintWidth <> -1 then
  1661.       inc(TotalWidths, Panels[i].PaintWidth);
  1662.   end;
  1663.   for i := 0 to Panels.Count - 1 do
  1664.     if (Panels[i].PaintWidth = -1) and (Width - TotalWidths > 0) then
  1665.       Panels[i].PaintWidth := (Width - TotalWidths) * StrtoInt(Copy(Panels[i].Width, 1, Length(Panels[i].Width) - 1)) div 100;
  1666.   if fcSizeEqual(FLastSize, fcSize(0, 0)) or (FLastSize.cy <> Height) then
  1667.     Panels.Update(nil)
  1668.   else begin
  1669.     r := Rect(Width - 25, 0, Width, Height);
  1670.     if Width > FLastSize.cx then
  1671.       r.Left := FLastSize.cx - 25;
  1672.     InvalidateRect(Handle, @r, True);
  1673.   end;
  1674.   FLastSize := fcSize(Width, Height);
  1675.   UpdateFlag := False;
  1676.   for i := 0 to Panels.Count - 1 do if Pos('%', Panels[i].Width) <> 0 then UpdateFlag := True;
  1677.   if UpdateFlag then UpdatePanels;
  1678. end;
  1679. var Hook: HHOOK = 0;
  1680. function KeyboardProc(code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
  1681. var AStyle: TfcStatusPanelStyle;
  1682.     i: integer;
  1683. begin
  1684.   result := CallNextHookEx(Hook, code, wParam, lParam);
  1685.   AStyle := psTextOnly;
  1686.   case wParam of
  1687.     VK_INSERT: AStyle := psOverwrite;
  1688.     VK_CAPITAL: AStyle := psCapsLock;
  1689.     VK_NUMLOCK: AStyle := psNumLock;
  1690.     VK_SCROLL: AStyle := psScrollLock;
  1691.   end;
  1692.   if AStyle <> psTextOnly then
  1693.     for i := 0 to StatusBars.Count - 1 do
  1694.       TfcCustomStatusBar(StatusBars[i]).Panels.RedrawIfNeeded(AStyle);
  1695. end;
  1696. procedure TfcCustomStatusBar.Invalidate;
  1697. begin
  1698.   if not (csLoading in ComponentState) then inherited;
  1699. end;
  1700. initialization
  1701.   StatusBars := TList.Create;
  1702.   Hook := SetWindowsHookEx(WH_KEYBOARD, @KeyboardProc, 0, GetCurrentThreadID);
  1703. finalization
  1704.   UnhookWindowsHookEx(Hook);
  1705.   StatusBars.Free;
  1706.   StatusBars:= nil; { 7/11/99 }
  1707. end.