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

Delphi控件源码

开发平台:

Delphi

  1. unit fcOutlookList;
  2. {
  3. //
  4. // Components : TfcOutlookList
  5. //
  6. // Copyright (c) 1999 by Woll2Woll Software
  7. // 6/18/99 - Add DitherColor property for selected item.
  8. // 7/27/99 - PYW - Added GlyphOffset and Alignment support for OutlookItems
  9. // 9/10/99 - Make certain that selected color is the same as the hottracktextcolor.
  10. // 12/6/99 - Action list support for event
  11. // 1/06/00 - Fix for outlook item focus when it opens a form over button.  PYW
  12. // 3/23/00 - Fix problem where mouse click in outlooklist buttons not detected
  13. //           if mouse is moved
  14. // 3/24/2000 - PYW - Made sure Item is visible when checking if point is in ItemRect.
  15. // 3/28/01 - RSW - Don't use inherited as it may call accelerators if capture is true
  16. // 10/10/01 - PYW - Actionlink not getting freed.
  17. // 2/7/2002 - Added to handle case where ItemClick deletes an item.
  18. // 5/10/2002- PYW - Moved before inherited.
  19. }
  20. interface
  21. {$i fcIfDef.pas}
  22. uses
  23.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  24.   ComCtrls, fcCustomDraw, fcCommon, CommCtrl, Buttons, fcCollection, fcClearPanel,
  25.   fcimager, actnlist,
  26.   {$ifdef fcDelphi7Up}
  27.   Themes,
  28.   {$endif}
  29.   {$ifdef ThemeManager}
  30.   thememgr, themesrv, uxtheme,
  31.   {$endif}
  32.   {$ifdef fcDelphi4Up}
  33.   ImgList,
  34.   {$endif}
  35.   ExtCtrls;
  36. type
  37.   TfcCustomOutlookList = class;
  38.   TfcOutlookListItem = class;
  39.   TfcScrollButtonStyle = (sbNone, sbUp, sbDown);
  40.   TfcOutlookPanel = class(TCustomControl)
  41.   private
  42.     FAnimating: Boolean;
  43.     FTransparent: Boolean;
  44.     FInEraseBkGnd: Boolean;
  45.     FOutlookPage: TPersistent;
  46.     procedure SetTransparent(Value: Boolean);
  47.     procedure CMControlListChange(var Message: TCMControlListChange); message CM_CONTROLLISTCHANGE;
  48.     procedure WMEraseBkgnd(var Message: TWMEraseBkGnd); message WM_ERASEBKGND;
  49.   protected
  50.     procedure AlignControls(AControl: TControl; var Rect: TRect); override;
  51.     procedure Paint; override;
  52.     procedure WndProc(var Message: TMessage); override;
  53.   public
  54.     FPreventUpdate: Boolean;
  55.     constructor Create(AOwner: TComponent); override;
  56.     destructor Destroy; override;
  57.     property Animating: Boolean read FAnimating write FAnimating;
  58.     property OutlookPage: TPersistent read FOutlookPage write FOutlookPage;
  59.     property Transparent: Boolean read FTransparent write SetTransparent;
  60.   end;
  61.   TfcCustomOutlookListItemEvent = procedure(OutlookList: TfcCustomOutlookList; Item: TfcOutlookListItem) of object;
  62.   TfcOutlookListDrawItemEvent = procedure(OutlookList: TfcCustomOutlookList; Item: TfcOutlookListItem;
  63.     var GlyphPos, TextPos: TPoint; var DefaultDrawing: Boolean) of object;
  64.   TfcOutlookItemActionLink = class(TActionLink)
  65.   protected
  66.     FItem: TfcOutlookListItem;
  67.     procedure AssignClient(AClient: TObject); override;
  68.     function IsCaptionLinked: Boolean; override;
  69.     function IsEnabledLinked: Boolean; override;
  70.     function IsHintLinked: Boolean; override;
  71.     function IsVisibleLinked: Boolean; override;
  72.     function IsOnExecuteLinked: Boolean; override;
  73. {    function DoShowHint(var HintStr: string): Boolean; virtual;}
  74.     procedure SetCaption(const Value: string); override;
  75.     procedure SetEnabled(Value: Boolean); override;
  76.     procedure SetHint(const Value: string); override;
  77.     procedure SetVisible(Value: Boolean); override;
  78. //    procedure SetOnExecute(Value: TNotifyEvent); override;
  79.   end;
  80.   TfcOutlookItemActionLinkClass = class of TfcOutlookItemActionLink;
  81.   TfcOutlookListItem = class(TfcCollectionItem)
  82.   private
  83.     // Property Storage Variables
  84.     FActionLink: TfcOutlookItemActionLink;
  85.     FButtonRect: TRect;
  86.     FItemRect: TRect;
  87.     FImageIndex: Integer;
  88.     FMouseDownOnItem: Boolean;
  89.     FMouseOnItem: Boolean;
  90.     FSelected: Boolean;
  91.     FSeparation: Integer;
  92.     FText: string;
  93.     {$ifdef fcDelphi4Up}
  94.     FTextAlignment: TAlignment;
  95.     FGlyphOffset: integer;
  96.     {$endif}
  97.     FOnClick: TfcCustomOutlookListItemEvent;
  98.     FEnabled: boolean;
  99.     FVisible: boolean;
  100.     FHint: string;
  101. //    FOnExecuteAction: TNotifyEvent;
  102.     // Property Access methods
  103.     function GetSelected: Boolean;
  104.     function GetOutlookList: TfcCustomOutlookList;
  105.     procedure SetImageIndex(Value: Integer);
  106.     procedure SetMouseDownOnItem(Value: Boolean);
  107.     procedure SetMouseOnItem(Value: Boolean);
  108.     procedure SetSeparation(Value: Integer);
  109.     procedure SetSelected(Value: Boolean);
  110.     procedure SetText(Value: string);
  111.     {$ifdef fcDelphi4Up}
  112.     procedure SetGlyphOffset(Value: Integer);
  113.     procedure SetTextAlignment(Value: TAlignment);
  114.     {$endif}
  115.     function GetAction: TBasicAction;
  116.     procedure SetAction(Value: TBasicAction);
  117.     procedure DoActionChange(Sender: TObject);
  118.     procedure SetEnabled(Value: boolean);
  119.     procedure SetVisible(Value: boolean);
  120.     procedure SetHint(Value: String);
  121.   protected
  122.     function GetItemSize(IncludePadding: Boolean): TSize;
  123.     function IsVisible(Completely: Boolean): Boolean; virtual;
  124.     function SpacingSize: Integer; virtual;
  125.     procedure Paint; virtual;
  126.     procedure PaintButton(IconRect: TRect); virtual;
  127.     function GetDisplayName: string; override;
  128.     property ButtonRect: TRect read FButtonRect;
  129.     property ActionLink: TfcOutlookItemActionLink read FActionLink write FActionLink;
  130.     procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); dynamic;
  131.   public
  132.     constructor Create(Collection: TCollection); override;
  133.     destructor Destroy; override;
  134.     function DisplayRect(Code: TDisplayCode; AStartPos: Integer): TRect;
  135.     function IsDown: Boolean; virtual;
  136.     procedure Invalidate(Erase: Boolean); virtual;
  137.     property ItemRect: TRect read FItemRect;
  138.     property MouseDownOnItem: Boolean read FMouseDownOnItem write SetMouseDownOnItem;
  139.     property MouseOnItem: Boolean read FMouseOnItem write SetMouseOnItem;
  140.     property OutlookList: TfcCustomOutlookList read GetOutlookList;
  141. //    property OnExecuteAction: TNotifyEvent read FOnExecuteAction write FOnExecuteAction;
  142.   published
  143.     property Action: TBasicAction read GetAction write SetAction;
  144.     property ImageIndex: Integer read FImageIndex write SetImageIndex;
  145.     property Selected: Boolean read GetSelected write SetSelected;
  146.     property Separation: Integer read FSeparation write SetSeparation;
  147.     property Tag;
  148.     property Text: string read FText write SetText;
  149.     property OnClick: TfcCustomOutlookListItemEvent read FOnClick write FOnClick;
  150.     {$ifdef fcDelphi4Up}
  151.     property TextAlignment: TAlignment read FTextAlignment write SetTextAlignment default taCenter;
  152.     property GlyphOffset: integer read FGlyphOffset write SetGlyphOffset default 0;
  153.     {$endif}
  154.     property Enabled: boolean read FEnabled write SetEnabled default True;
  155.     property Visible: boolean read FVisible write SetVisible default True;
  156.     property Hint: String read FHint write SetHint;
  157.   end;
  158.   TfcOutlookListItemClass = class of TfcOutlookListItem;
  159.   TfcOutlookListItems = class(TfcCollection)
  160.   private
  161.     FOutlookList: TfcCustomOutlookList;
  162.   protected
  163.     // Overriden methods
  164.     function GetOwner: TPersistent; override;
  165.     // Property access methods
  166.     function GetItems(Index: Integer): TfcOutlookListItem;
  167.     procedure Update(Item: TCollectionItem); override;
  168.   public
  169.     constructor Create(AOutlookList: TfcCustomOutlookList; ACollectionItemClass: TfcOutlookListItemClass); virtual;
  170.     function Add: TfcOutlookListItem;
  171.     function AddItem: TfcCollectionItem; override;
  172.     property OutlookList: TfcCustomOutlookList read FOutlookList;
  173.     property Items[Index: Integer]: TfcOutlookListItem read GetItems; default;
  174.   end;
  175.   TfcOutlookHotTrackStyle = (hsIconHilite, hsItemHilite);
  176.   TfcCustomOutlookListClickStyle = (csClick, csSelect);
  177.   TfcCustomOutlookList = class(TfcOutlookPanel)
  178.   private
  179.     // Property Storage Variables
  180.     FBorderStyle: TBorderStyle;
  181.     FClickStyle: TfcCustomOutlookListClickStyle;
  182.     FHotTrackStyle: TfcOutlookHotTrackStyle;
  183.     FHotTrackTextColor: TColor;
  184.     FItemDisabledTextColor: TColor;
  185.     FImageList: TCustomImageList;
  186.     FItemLayout: TButtonLayout;
  187.     FItemHighlightColor: TColor;
  188.     FItemHotTrackColor: TColor;
  189.     FItemShadowColor: TColor;
  190.     FItems: TfcOutlookListItems;
  191.     FItemSpacing: Integer;
  192.     FItemsWidth: Integer;
  193.     FLayout: TfcLayout;
  194.     FPaintBitmap: TBitmap;
  195.     FScrollInterval: Integer;
  196.     FOnItemClick: TfcCustomOutlookListItemEvent;
  197.     FOnItemChange: TfcCustomOutlookListItemEvent;
  198.     FOnDrawItem: TfcOutlookListDrawItemEvent;
  199.     FTopItem: TfcOutlookListItem;
  200.     FUpButtonRect, FDownButtonRect: TRect;
  201.     FScrollButtonDown: TfcScrollButtonStyle;
  202.     FScrollButtonsVisible: Boolean;
  203.     FMouseInScrollButton: TfcScrollButtonStyle;
  204.     FChangeLink: TChangeLink;
  205.     FOldCapture: HWND;
  206.     FOutlookPage: TPersistent;
  207.     {$ifdef fcDelphi4Up}
  208.     FItemSelectedDitherColor: TColor;
  209.     {$endif}
  210.     HintWindow: THintWindow;
  211.     HintTimerCount: integer;
  212.     HintTimer: TTimer;
  213.     procedure HintTimerEvent(Sender: TObject);
  214.     procedure FreeHintWindow;
  215.     // Property Access methods
  216.     function GetListItems(Index: Integer): TfcOutlookListItem;
  217.     function GetBottomItem: TfcOutlookListItem;
  218.     function GetPaintCanvas: TCanvas;
  219.     function GetSelected: TfcOutlookListItem;
  220.     function GetTopItem: TfcOutlookListItem;
  221.     procedure SetBorderStyle(Value: TBorderStyle);
  222.     procedure SetClickStyle(Value: TfcCustomOutlookListClickStyle);
  223.     procedure SetImageList(Value: TCustomImageList);
  224.     procedure SetItemHighlightColor(Value: TColor);
  225.     procedure SetItemDisabledTextColor(Value: TColor);
  226.     procedure SetItemLayout(Value: TButtonLayout);
  227.     procedure SetItemShadowColor(Value: TColor);
  228.     procedure SetItems(Value: TfcOutlookListItems);
  229.     procedure SetItemSpacing(Value: Integer);
  230.     procedure SetItemsWidth(Value: Integer);
  231.     procedure SetLayout(Value: TfcLayout);
  232.     procedure SetMouseInScrollButton(Value: TfcScrollButtonStyle);
  233.     procedure SetScrollButtonsVisible(Value: Boolean);
  234.     procedure SetTopItem(Value: TfcOutlookListItem);
  235.     Function GetImager: TfcCustomImager;
  236.     Function IsEffectiveItemHilite: boolean;
  237.     // Message Handlers
  238.     procedure CMDesignHitTest(var Message: TCMDesignHitTest); message CM_DESIGNHITTEST;
  239.     procedure WMEraseBkgnd(var Message: TWMEraseBkGnd); message WM_ERASEBKGND;
  240.     procedure WMSize(var Message: TWMSize); message WM_SIZE;
  241.     procedure WMTimer(var Message: TWMTimer); message WM_TIMER;
  242.     procedure CNChar(var Message: TWMChar); message CN_CHAR;
  243.   protected
  244.     // Overridden Methods
  245.     procedure CreateParams(var Params: TCreateParams); override;
  246.     procedure Loaded; override;
  247.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  248.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  249.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  250.     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  251.     procedure Paint; override;
  252.     procedure UpdateButtonRects; virtual;
  253.     procedure ValidateInsert(AComponent: TComponent); override;
  254.     // Virtual Methods
  255.     function ScrollButtonVisible(Button: TfcScrollButtonStyle): Boolean; virtual;
  256.     procedure DoDrawItem(Item: TfcOutlookListItem; var GlyphPos, TextPos: TPoint; var DefaultDrawing: Boolean); virtual;
  257.     procedure ImageListChange(Sender: TObject); virtual;
  258.     procedure InvalidateScrollButton(Button: TfcScrollButtonStyle); virtual;
  259.     procedure ItemClick(Item: TfcOutlookListItem); virtual;
  260.     procedure ScrollButtonClick; virtual;
  261.     procedure UpdateMouseOnItem; virtual;
  262.     procedure UpdateScrollButtonsRect; virtual;
  263.     property MouseInScrollButton: TfcScrollButtonStyle read FMouseInScrollButton write SetMouseInScrollButton;
  264.   public
  265.     Patch: Variant;
  266.     constructor Create(AOwner: TComponent); override;
  267.     destructor Destroy; override;
  268.     function GetPriorVisibleItem(item: TfcOutlookListItem): TfcOutlookListItem;
  269.     function GetNextVisibleItem(item: TfcOutlookListItem): TfcOutlookListItem;
  270.     function GetItemAt(x, y: Integer): TfcOutlookListItem; virtual;
  271.     procedure PaintScrollButton(Button: TfcScrollButtonStyle); virtual;
  272.     function GetFirstVisibleItem: TfcOutlookListItem; virtual;
  273.     property ListItems[Index: Integer]: TfcOutlookListItem read GetListItems;
  274.     property BottomItem: TfcOutlookListItem read GetBottomItem;
  275.     property Selected: TfcOutlookListItem read GetSelected;
  276.     property TopItem: TfcOutlookListItem read GetTopItem write SetTopItem;
  277.     property PaintCanvas: TCanvas read GetPaintCanvas;
  278.     property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle;
  279.     property ClickStyle: TfcCustomOutlookListClickStyle read FClickStyle write SetClickStyle;
  280.     property HotTrackStyle: TfcOutlookHotTrackStyle read FHotTrackStyle write FHotTrackStyle;
  281.     property HotTrackTextColor: TColor read FHotTrackTextColor write FHotTrackTextColor;
  282.     property ItemDisabledTextColor: TColor read FItemDisabledTextColor write SetItemDisabledTextColor default clBtnFace;
  283.     property Images: TCustomImageList read FImageList write SetImageList;
  284.     property ItemHighlightColor: TColor read FItemHighlightColor write SetItemHighlightColor;
  285.     property ItemHotTrackColor: TColor read FItemHotTrackColor write FItemHotTrackColor;
  286.     property ItemLayout: TButtonLayout read FItemLayout write SetItemLayout;
  287.     property ItemShadowColor: TColor read FItemShadowColor write SetItemShadowColor;
  288.     property Items: TfcOutlookListItems read FItems write SetItems;
  289.     property ItemSpacing: Integer read FItemSpacing write SetItemSpacing;
  290.     property ItemsWidth: Integer read FItemsWidth write SetItemsWidth;
  291.     property Layout: TfcLayout read FLayout write SetLayout;
  292.     property OutlookPage: TPersistent read FOutlookPage write FOutlookPage;
  293.     property ScrollButtonsVisible: Boolean read FScrollButtonsVisible write SetScrollButtonsVisible;
  294.     property ScrollInterval: Integer read FScrollInterval write FScrollInterval;
  295.     { RSW - 6/18/99 }
  296.     {$ifdef fcDelphi4Up}
  297.     property ItemSelectedDitherColor: TColor read FItemSelectedDitherColor write FItemSelectedDitherColor;
  298.     {$endif}
  299.     property OnDrawItem: TfcOutlookListDrawItemEvent read FOnDrawItem write FOnDrawItem;
  300.     property OnItemClick: TfcCustomOutlookListItemEvent read FOnItemClick write FOnItemClick;
  301.     property OnItemChange: TfcCustomOutlookListItemEvent read FOnItemChange write FOnItemChange;
  302.   end;
  303.   TfcOutlookList = class(TfcCustomOutlookList)
  304.   published
  305.     property Align;
  306.     property BorderStyle;
  307.     property ClickStyle;
  308.     property Color;
  309.     property DragCursor;
  310.     property DragMode;
  311.     property Font;
  312.     property HotTrackStyle;
  313.     property Images;
  314.     property ItemDisabledTextColor;
  315.     property ItemHighlightColor;
  316.     property ItemHotTrackColor;
  317.     property ItemLayout;
  318.     property ItemShadowColor;
  319.     {$ifdef fcDelphi4Up}
  320.     property ItemSelectedDitherColor;
  321.     {$endif}
  322.     property Items;
  323.     property ItemSpacing;
  324.     property ItemsWidth;
  325.     property Layout;
  326.     property PopupMenu;
  327.     property ScrollButtonsVisible;
  328.     property ScrollInterval;
  329.     property ShowHint;
  330.     property Transparent;
  331.     property OnDragDrop;
  332.     property OnDragOver;
  333.     property OnDrawItem;
  334.     property OnEndDrag;
  335.     property OnItemClick;
  336.     property OnItemChange;
  337.     property OnMouseDown;
  338.     property OnMouseUp;
  339.     property OnMouseMove;
  340.     property OnStartDrag;
  341.   end;
  342. implementation
  343. uses fcOutlookBar;
  344. const ScrollTimerID = 100;
  345. constructor TfcOutlookPanel.Create(AOwner: TComponent);
  346. begin
  347.   inherited;
  348.   ControlStyle := ControlStyle + [csAcceptsControls];
  349.   Transparent := True; { RSW - 3/19/99 (Necessary to paint imager }
  350. end;
  351. destructor TfcOutlookPanel.Destroy;
  352. begin
  353.    inherited;
  354. end;
  355. procedure TfcOutlookPanel.SetTransparent(Value: Boolean);
  356. begin
  357.   if FTransparent <> Value then
  358.   begin
  359.     FTransparent := Value;
  360.     if Parent <> nil then Parent.Invalidate;
  361.   end;
  362. end;
  363. procedure TfcOutlookPanel.WndProc(var Message: TMessage);
  364. begin
  365.   inherited;
  366. end;
  367. procedure TfcOutlookPanel.AlignControls(AControl: TControl; var Rect: TRect);
  368. //var OutlookBar: TfcCustomOutlookBar;
  369. begin
  370.   {  4/14/99 - RSW - During animating do not align controls }
  371. {  if (Parent is TfcCustomOutlookBar) then
  372.   begin
  373.      OutlookBar:=TfcCustomOutlookBar(Parent);
  374.      if OutlookBar.AnimatingControls then exit;
  375.   end;}
  376.   inherited;
  377.   if AControl is TGraphicControl then Invalidate;
  378. end;
  379. procedure TfcOutlookPanel.Paint;
  380. var FPaintImageBitmap: TBitmap;
  381.     OutlookBar: TfcCustomOutlookBar;
  382.     OffsetClipRect: TRect;
  383. //    curPanel: TfcOutlookPanel;
  384.     r, r1, ir: TRect;
  385.     j: integer;
  386. begin
  387.   { 4/10/99 - RSW - Paint imager area for ClipRect area }
  388.   if (Parent is TfcCustomOutlookBar) then
  389.   begin
  390.      OutlookBar:=TfcCustomOutlookBar(Parent);
  391.      if Transparent and (not OutlookBar.AnimatingControls) and
  392.        (OutLookBar.Imager <> nil) then
  393.      begin
  394.         FPaintImageBitmap := TBitmap.Create;
  395.         FPaintImageBitmap.Width := OutlookBar.Width;
  396.         FPaintImageBitmap.Height := OutlookBar.Height;
  397.         if OutlookBar.Imager.DrawStyle=dsTile then
  398.            OutlookBar.Imager.WorkBitmap.TileDraw(
  399.              FPaintImageBitmap.Canvas, Rect(0,0,OutlookBar.Width, OutlookBar.Height))
  400.         else
  401.           FPaintImageBitmap.Canvas.StretchDraw(
  402.              Rect(0,0,OutlookBar.Width, OutlookBar.Height),
  403.              OutlookBar.Imager.WorkBitmap);
  404.         with Canvas.ClipRect do
  405.           OffsetClipRect:= Rect(Left + BoundsRect.Left, Top + BoundsRect.Top,
  406.                                 Right+ BoundsRect.Left, Bottom+BoundsRect.Top);
  407.         Canvas.CopyRect(Canvas.ClipRect, FPaintImageBitmap.Canvas, OffsetClipRect);
  408.         FPaintImageBitmap.Free;
  409.      end;
  410.   end;
  411.   if GetWindowLong(Parent.Handle, GWL_STYLE) and WS_CLIPCHILDREN = WS_CLIPCHILDREN then
  412.   begin
  413.     SetWindowLong(Parent.Handle, GWL_STYLE,
  414.       GetWindowLong(Parent.Handle, GWL_STYLE) and not WS_CLIPCHILDREN);
  415.     Invalidate;
  416.   end;
  417.   { 4/15/99 - RSW - only invalidate controls that intersect with cliprect.
  418.     Neccesary when controls alClient }
  419.   if (Parent is TfcCustomOutlookBar) then
  420.   begin
  421.      if not TfcCustomOutlookBar(Parent).InAnimation then exit;
  422.      for j := 0 to ControlCount - 1 do if Controls[j] is TWinControl then
  423.      begin
  424.         r := Controls[j].BoundsRect;
  425.         offsetRect(r, left, top); { Adjust to outlookbar coordinates }
  426.         r1:= TfcOutlookBar(parent).canvas.cliprect;
  427.         if IntersectRect(ir, r1, r) then begin
  428.            offsetRect(r, -left, -top); { Adjust to outlookbar coordinates }
  429.            offsetRect(r, -Controls[j].BoundsRect.Left, -Controls[j].BoundsRect.top);
  430.            InvalidateRect((Controls[j] as TWinControl).Handle, @r, False);
  431.         end
  432.      end;
  433.   end;
  434. {  for i := 0 to ControlCount - 1 do
  435.     if Controls[i] is TWinControl then
  436.       InvalidateRect((Controls[i] as TWinControl).Handle, nil, False);}
  437. end;
  438. procedure TfcOutlookPanel.CMControlListChange(var Message: TCMControlListChange);
  439. begin
  440.   inherited;
  441.   if (Message.Inserting = False) and (Message.Control is TfcCustomOutlookList) then Invalidate;
  442. end;
  443. procedure TfcOutlookPanel.WMEraseBkgnd(var Message: TWMEraseBkGnd);
  444. var  j: integer;
  445. //var Rgn, TmpRgn: HRGN;
  446. begin
  447.   for j := 0 to ControlCount - 1 do // RSW - 3/19/99 - If contain outlooklist then don't erase
  448.     if Controls[j] is TfcOutlookList then
  449.       if not (Controls[j] as TfcOutlookList).Transparent then
  450.       begin
  451.         Message.result:=1;
  452.         exit;
  453.       end;
  454.   if not Transparent or not Animating and ((Parent is TfcCustomOutlookBar) and ((Parent as TfcCustomOutlookBar).Imager = nil)) then
  455.   begin
  456.     inherited;
  457.     Exit;
  458.   end;
  459.   if FInEraseBkGnd then Exit;
  460.   if not TfcOutlookPage(OutlookPage).OutlookBar.AnimatingControls then exit; { RSW }
  461. {  FInEraseBkGnd := True;
  462.   Message.result := 1;
  463.   if FPreventUpdate then Exit;
  464.   if Parent <> nil then
  465.   begin
  466.     Rgn := CreateRectRgn(0, 0, Width, Height);
  467.     TmpRgn := CreateRectRgn(0, 0, 0, 0);
  468.     fcGetChildRegions(self, True, TmpRgn, Point(0, 0), RGN_OR);
  469.     CombineRgn(Rgn, Rgn, TmpRgn, RGN_DIFF);
  470.     DeleteObject(TmpRgn);
  471.     OffsetRgn(Rgn, Left, Top);
  472.     InvalidateRgn(Parent.Handle, Rgn, False);
  473.     Parent.Update;
  474.     DeleteObject(Rgn);
  475.   end;
  476.   FInEraseBkGnd := False;}
  477. end;
  478. constructor TfcOutlookListItem.Create(Collection: TCollection);
  479. begin
  480.   inherited;
  481.   FSeparation := 10;
  482.   {$ifdef fcDelphi4Up}
  483.   FTextAlignment:= taCenter;
  484.   {$endif}
  485.   FVisible:= True;
  486.   FEnabled:= True;
  487. end;
  488. destructor TfcOutlookListItem.Destroy;
  489. begin
  490.   if OutlookList.FTopItem = self then OutlookList.TopItem := nil;
  491.   //5/10/2002-PYW-Moved before inherited.
  492.   if FActionLink <> nil then // 10/10/01 - PYW - Actionlink not getting freed so free it.
  493.   begin
  494.     FActionLink.Free;
  495.     FActionLink := nil;
  496.   end;
  497.   inherited;
  498. end;
  499. function TfcOutlookListItem.GetDisplayName: string; { 4/26/99 - RSW }
  500. begin
  501.   Result := Text;
  502.   if Result = '' then Result := inherited GetDisplayName;
  503. end;
  504. function TfcOutlookListItem.GetSelected: Boolean;
  505. begin
  506.   if OutlookList.ClickStyle = csSelect then result := FSelected else result := False;
  507. end;
  508. function TfcOutlookListItem.GetOutlookList: TfcCustomOutlookList;
  509. begin
  510.   result := (Collection as TfcOutlookListItems).OutlookList;
  511. end;
  512. procedure TfcOutlookListItem.SetImageIndex(Value: Integer);
  513. begin
  514.   if FImageIndex <> Value then
  515.   begin
  516.     FImageIndex := Value;
  517.     Invalidate(True);
  518.   end;
  519. end;
  520. procedure TfcOutlookListItem.SetEnabled(Value: boolean);
  521. begin
  522.    FEnabled:= Value;
  523.    Invalidate(True);
  524. end;
  525. procedure TfcOutlookListItem.SetVisible(Value: boolean);
  526. begin
  527.    if Value=FVisible then exit;
  528.    FVisible:= Value;
  529.    RefreshDesign;
  530.    if OutlookList.TopItem=self then
  531.    begin
  532.      if not Value then
  533.         OutlookList.TopItem := OutlookList.GetNextVisibleItem(OutlookList.TopItem)
  534. //     else
  535. //        OutlookList.TopItem := OutlookList.GetPriorVisibleItem(OutlookList.TopItem)
  536.    end;
  537. {   if OutlookList.BottomItem=self then
  538.    begin
  539.      if not Value then
  540.      begin
  541.         OutlookList.BottomItem := OutlookList.GetPriorVisibleItem(OutlookList.TopItem)
  542.      end
  543.    end;
  544. }
  545.    OutlookList.UpdateButtonRects;
  546. //   OutlookList.UpdateMouseOnItem;
  547.    OutlookList.Invalidate;
  548. end;
  549. procedure TfcOutlookListItem.SetHint(Value: String);
  550. begin
  551.    FHint:= Value;
  552. end;
  553. procedure TfcOutlookListItem.SetMouseDownOnItem(Value: Boolean);
  554. begin
  555.   if FMouseDownOnItem <> Value then
  556.   begin
  557.     FMouseDownOnItem := Value;
  558.     if not Selected then Invalidate(False);
  559.   end;
  560. end;
  561. procedure TfcCustomOutlookList.CNChar(var Message: TWMChar);
  562. begin
  563.   if not (csDesigning in ComponentState) then
  564.     with Message do
  565.     begin
  566.       if not Focused then
  567.          Result := 0  // 3/28/01 - don't use inherited as it may call accelerators if capture is true
  568.       else
  569.          inherited;
  570.     end;
  571. end;
  572. procedure TfcOutlookListItem.SetMouseOnItem(Value: Boolean);
  573. begin
  574.   if not (csDesigning in Outlooklist.ComponentState) and ((FMouseOnItem <> Value) or (Value and (GetCapture <> OutlookList.Handle))) then
  575.   begin
  576.     FMouseOnItem := Value;
  577.     if not FMouseOnItem then
  578.        MouseDownOnItem := False;
  579.     //9/10/99 - Make certain that Button is always invalidated
  580. {    if not Selected then }Invalidate(False);
  581.     if Value and (GetCapture <> OutlookList.Handle) then windows.SetCapture(OutlookList.Handle);
  582.   end;
  583. end;
  584. procedure TfcOutlookListItem.SetSelected(Value: Boolean);
  585. var i: Integer;
  586. begin
  587.   if FSelected <> Value then
  588.   begin
  589.     if Value then for i := 0 to OutlookList.Items.Count - 1 do
  590.       if OutlookList.Items[i] <> self then
  591.         OutlookList.Items[i].Selected := False;
  592.     FSelected := Value;
  593.     Invalidate(not FSelected);
  594.   end;
  595. end;
  596. procedure TfcOutlookListItem.SetSeparation(Value: Integer);
  597. begin
  598.   if FSeparation <> Value then
  599.   begin
  600.     FSeparation := Value;
  601.     Invalidate(True);
  602.   end;
  603. end;
  604. function TfcOutlookListItem.DisplayRect(Code: TDisplayCode; AStartPos: Integer): TRect;
  605. var i: Integer;
  606.     ItemSize, ItemSizeNoPad: TSize;
  607.     Offset: Integer;
  608.     TextSize: TSize;
  609.     tempRect: TRect;
  610.   function ImageListSize: TSize;
  611.   begin
  612.     result := fcSize(0, 0);
  613.     if OutlookList.Images <> nil then with TImageList(OutlookList.Images) do
  614.       result := fcSize(Width, Height);
  615.   end;
  616. begin
  617.   SetRectEmpty(result);
  618.   if IsVisible(False) then
  619.     with OutlookList do
  620.     begin
  621.       ItemSize := GetItemSize(True);
  622.       ItemSizeNoPad := GetItemSize(False);
  623.       Offset := 0;
  624.       if AStartPos = -1 then
  625.       begin
  626.         for i := TopItem.Index to BottomItem.Index do
  627.           if Index = Items[i].Index then Break else
  628.           begin
  629.              if Items[i].Visible then
  630.                 inc(Offset, Items[i].SpacingSize);
  631.           end
  632.       end else Offset := AStartPos;
  633.       if Layout = loVertical then
  634.       begin
  635.         result.Top := Offset;
  636.         result.Bottom := result.Top + ItemSize.cy;
  637.         result.Right := ClientWidth;
  638.       end else begin
  639.         inc(result.Left, Offset);
  640.         result.Right := result.Left + ItemSize.cx;
  641.         result.Bottom := ClientHeight;
  642.       end;
  643.       tempRect:= Result; { 7/9/99 - PYW -Compute height and consider carrige returns }
  644.       if (ImageListSize.cx > 0) and {7/9/99 - Adjust based on ItemLayout and glyph}
  645.          (OutlookList.ItemLayout=blglyphLeft) then
  646.          tempRect.Left := {$ifdef fcDelphi4Up}GlyphOffset+{$endif}tempRect.Left+Separation + ImageListSize.cx + 4;
  647.       TextSize.cy:= DrawText(PaintCanvas.Handle, PChar(self.Text), Length(self.Text), TempRect, DT_CALCRECT or DT_CENTER or DT_END_ELLIPSIS or DT_WORDBREAK);
  648.       TextSize.cx:= TempRect.Right-TempRect.Left;
  649.       case Code of
  650.         drBounds, drSelectBounds: ;
  651.         drIcon: begin
  652.           fcCalcButtonLayout(Point(result.Left + fcRectWidth(result) div 2, result.Top + fcRectHeight(result) div 2),
  653.             nil, @result, TextSize, ImageListSize, ItemLayout, self.Separation);
  654.           InflateRect(result, 2, 2);
  655.         end;
  656.         drLabel: begin
  657.           fcCalcButtonLayout(Point(result.Left + fcRectWidth(result) div 2, result.Top + fcRectHeight(result) div 2),
  658.             @result, nil, TextSize, ImageListSize, ItemLayout, self.Separation);
  659.         end;
  660.       end;
  661.     end;
  662. end;
  663. {$ifdef fcDelphi4Up}
  664. procedure TfcOutlookListItem.SetTextAlignment(Value: TAlignment);
  665. begin
  666.   if FTextAlignment <> Value then
  667.   begin
  668.     FTextAlignment := Value;
  669.     RefreshDesign;
  670.     Invalidate(True);
  671.   end;
  672. end;
  673. procedure TfcOutlookListItem.SetGlyphOffset(Value: integer);
  674. begin
  675.   if FGlyphOffset <> Value then
  676.   begin
  677.     FGlyphOffset := Value;
  678.     RefreshDesign;
  679.     Invalidate(True);
  680.   end;
  681. end;
  682. {$endif}
  683. procedure TfcOutlookListItem.SetText(Value: string);
  684. begin
  685.   if FText <> Value then
  686.   begin
  687.     FText := Value;
  688.     RefreshDesign;
  689.     Invalidate(True);
  690.   end;
  691. end;
  692. function TfcOutlookListItem.GetItemSize(IncludePadding: Boolean): TSize;
  693. var Padding: Integer;
  694. begin
  695.   result := OutlookList.PaintCanvas.TextExtent(Text);
  696.   Padding := 0;
  697.   if IncludePadding then inc(Padding, OutlookList.ItemSpacing);
  698.   if OutlookList.Layout = loVertical then inc(result.cy, Padding) else inc(result.cx, Padding);
  699.   if OutlookList.Images <> nil then
  700.   begin
  701.     if OutlookList.ItemLayout in [blGlyphTop, blGlyphBottom] then
  702.       inc(result.cy, TImageList(OutlookList.Images).Height + Separation)
  703.     else
  704.       {$ifdef fcDelphi4Up} //7/27/99-PYW-Added extra padding for textrect
  705.       inc(result.cx,8+GlyphOffset+TImageList(OutlookList.Images).Width + Separation);
  706.       {$else}
  707.       inc(result.cx,TImageList(OutlookList.Images).Width + Separation);
  708.       {$endif}
  709.   end;
  710.   if (OutlookList.Layout = loHorizontal) and (OutlookList.ItemsWidth > 0) then result.cx := OutlookList.ItemsWidth;
  711. end;
  712. function TfcOutlookListItem.SpacingSize: Integer;
  713. begin
  714.   if OutlookList.Layout = loVertical then result := GetItemSize(True).cy
  715.   else result := GetItemSize(True).cx;
  716. end;
  717. function TfcOutlookListItem.IsVisible(Completely: Boolean): Boolean;
  718. begin
  719.   result := False;
  720.   if OutlookList.TopItem = nil then Exit;
  721.   result := (Index >= OutlookList.TopItem.Index) and (Index <= OutlookList.BottomItem.Index) and
  722.             visible; // 5/5/03
  723.   if result and Completely then with OutlookList do
  724.     result := (ItemRect.Right <= Width) and (ItemRect.Bottom <= Height);
  725. end;
  726. procedure TfcOutlookListItem.Paint;
  727. var BoundsRect, TextRect, IconRect, TempIconRect: TRect;
  728.     StartBounds: PInteger;
  729.     DefaultDrawing: Boolean;
  730.     GlyphPos, TextPos: TPoint;
  731.     Flags: integer;
  732.     r: TRect;
  733. begin
  734.   GetUpdateRect(OutlookList.handle, r, False);
  735.   GetUpdateRect(OutlookList.parent.handle, r, False);
  736.   if OutlookList.Layout = loVertical then StartBounds := @BoundsRect.Top else StartBounds := @BoundsRect.Left;
  737.   BoundsRect := DisplayRect(drBounds, -1);
  738.   TextRect := DisplayRect(drLabel, StartBounds^);
  739.   IconRect := DisplayRect(drIcon, StartBounds^);
  740.   FItemRect := BoundsRect;
  741.   with OutlookList do
  742.   begin
  743.     PaintCanvas.Brush.Color := Color;
  744.     PaintCanvas.Font.Color := Font.Color;
  745.     if IsEffectiveItemHilite and MouseOnItem and self.Enabled then
  746.     begin
  747.         PaintCanvas.Font.Color := HotTrackTextColor
  748.     end;
  749.     //9/10/99 - Make certain that selected color is the same as the hottracktextcolor.
  750.     if self.Selected then PaintCanvas.Font.Color := HotTrackTextColor;
  751.     if IsEffectiveItemHilite and IsDown then OffsetRect(TextRect, 1, 1);
  752.   end;
  753.   DefaultDrawing := True;
  754.   GlyphPos := IconRect.TopLeft;
  755.   TextPos := TextRect.TopLeft;
  756.   {$ifdef fcDelphi4Up}
  757.   if (GlyphOffset>0) and (OutlookList.Images <> nil) then
  758.   begin //7/9/99 - PYW - Adjust based on ItemLayout
  759.      if (OutlookList.ItemLayout = blGlyphLeft) then begin
  760.         TextPos.X := FItemRect.Left+4+TImageList(OutlookList.Images).Width + GlyphOffset + Separation;
  761.         if OutlookList.IsEffectiveItemHilite and IsDown then inc(TextPos.X);
  762.         GlyphPos.X:= FItemRect.Left+GlyphOffset;
  763.      end
  764.      else if (OutlookList.ItemLayout = blGlyphRight) then begin
  765.         TextPos.X := FItemRect.Left+3;
  766.         if OutlookList.IsEffectiveItemHilite and IsDown then inc(TextPos.X);
  767.         GlyphPos.X := FItemRect.Right - TImageList(OutlookList.Images).Width - GlyphOffset - 1;
  768.      end;
  769.   end;
  770.   {$endif}
  771.   OutlookList.DoDrawItem(self, GlyphPos, TextPos, DefaultDrawing);
  772.   OffsetRect(IconRect, GlyphPos.x - IconRect.Left, GlyphPos.y - IconRect.Top);
  773.   OffsetRect(TextRect, TextPos.x - TextRect.Left, TextPos.y - TextRect.Top);
  774.   TempIconRect := IconRect;
  775.  {$ifdef fcDelphi4Up}
  776.   if OutlookList.Layout = loVertical then begin
  777.  {$endif}
  778.      if not OutlookList.IsEffectiveItemHilite then
  779.        UnionRect(FButtonRect, IconRect, TextRect);
  780.  {$ifdef fcDelphi4Up}
  781.   end;
  782.  {$endif}
  783.   if OutlookList.IsEffectiveItemHilite then FButtonRect := BoundsRect;
  784.   if DefaultDrawing then
  785.     with OutlookList do
  786.   begin
  787.     PaintButton(TempIconRect);
  788.     SetBkMode(PaintCanvas.Handle, Windows.TRANSPARENT);
  789.     SetTextColor(PaintCanvas.Handle, PaintCanvas.Font.Color);
  790.     Flags:= DT_END_ELLIPSIS or DT_WORDBREAK;
  791.     {$ifdef fcDelphi4Up}
  792.     case TextAlignment of
  793.       taLeftJustify : Flags:= Flags or DT_LEFT;
  794.       taCenter : Flags:= Flags or DT_CENTER;
  795.       taRightJustify : Flags := Flags or DT_RIGHT;
  796.     end;
  797.     //7/27/99 - PYW - Added GlyphOffset and Alignment support
  798.     if (GlyphOffset > 0) and
  799.        ((OutlookList.ItemLayout=blGlyphLeft) or (OutlookList.ItemLayout=blGlyphRight)) then begin
  800.        TextRect.Left := FItemRect.Left+3;
  801.        TextRect.Right := FItemRect.Right-4;
  802.        if (OutlookList.ItemLayout=blGlyphLeft) then begin
  803.            if (OutlookList.Images <> nil) then
  804.               TextRect.Left:= IconRect.Right+Separation;
  805.        end
  806.        else begin
  807.           if (OutlookList.Images <> nil) then
  808.              TextRect.Right := IconRect.Left-Separation;
  809.        end;
  810.        if OutlookList.IsEffectiveItemHilite and IsDown then begin
  811.           inc(TextRect.Left);
  812.           inc(TextRect.Right);
  813.        end;
  814.     end;
  815.     {$else}
  816.     Flags:= Flags or DT_CENTER;
  817.     {$endif}
  818.     //7/27/99-PYW- Moved this portion here in the Horizontal layout case, because
  819.     //             TextRect Width has changed and the ButtonRect needs to be updated
  820.     //             for the control.
  821.     {$ifdef fcDelphi4Up}
  822.     if OutlookList.Layout = loHorizontal then begin
  823.       if not OutlookList.IsEffectiveItemHilite then
  824.         UnionRect(FButtonRect, IconRect, TextRect);
  825.     end;
  826.     {$endif}
  827. // Commented as with default colors, the text blends to the background
  828. //    if not self.Enabled then
  829. //       PaintCanvas.Font.Color:= clGrayText;
  830.     if not self.Enabled then PaintCanvas.Font.Color := ItemDisabledTextColor;
  831.     DrawText(PaintCanvas.Handle, PChar(self.Text), Length(self.Text), TextRect, Flags);
  832.   end;
  833. end;
  834. function TfcOutlookListItem.IsDown: Boolean;
  835. begin
  836.   result := (MouseOnItem and MouseDownOnItem) or Selected;
  837. end;
  838. procedure TfcOutlookListItem.PaintButton(IconRect: TRect);
  839. var Down: Boolean;
  840.     Offset: TPoint;
  841.     PaintRect: TRect;
  842.   function ImageListSize: TSize;
  843.   begin
  844.     result := fcSize(0, 0);
  845.     if OutlookList.Images <> nil then with TImageList(OutlookList.Images) do
  846.       result := fcSize(Width, Height);
  847.   end;
  848. var OldBrush, OldPen: TColor;
  849. begin
  850.   with Outlooklist do
  851.   begin
  852.     Down := IsDown;
  853.     OldBrush := PaintCanvas.Brush.Color;
  854.     OldPen := PaintCanvas.Pen.Color;
  855.     if not OutlookList.IsEffectiveItemHilite then
  856.        PaintRect:= IconRect
  857.     else
  858.        PaintRect:= ButtonRect;
  859.     { 6/18/99 }
  860.     {$ifdef fcDelphi4Up}
  861.     if self.Selected and (FItemSelectedDitherColor<>clNone) then
  862.        fcDither(PaintCanvas, PaintRect, PaintCanvas.Brush.Color, FItemSelectedDitherColor)
  863.     {$else}
  864.     if self.Selected then fcDither(PaintCanvas, PaintRect, PaintCanvas.Brush.Color, clBtnHighlight)
  865.     {$endif}
  866.     else if (ItemHotTrackColor <> Color) and (ItemHotTrackColor <> clNone) and MouseOnItem and self.Enabled then
  867.     begin
  868.       PaintCanvas.Brush.Color := ItemHotTrackColor;
  869.       PaintCanvas.FillRect(PaintRect);
  870.     end;
  871.     PaintCanvas.Pen.Color := Color;
  872.     if self.Selected or (MouseOnItem and Down and self.Enabled) then
  873.        PaintCanvas.Pen.Color := FItemShadowColor
  874.     else if MouseOnItem and self.Enabled then
  875.        PaintCanvas.Pen.Color := FItemHighlightColor else PaintCanvas.Pen.Color := clNone;
  876.     if PaintCanvas.Pen.Color <> clNone then
  877.        with PaintRect do PaintCanvas.PolyLine([Point(Left, Bottom - 1), Point(Left, Top), Point(Right - 1, Top)]);
  878.     if self.Selected or (MouseOnItem and Down and self.Enabled) then
  879.        PaintCanvas.Pen.Color := FItemHighlightColor
  880.     else if MouseOnItem and self.Enabled then
  881.        PaintCanvas.Pen.Color := FItemShadowColor else PaintCanvas.Pen.Color := clNone;
  882.     if PaintCanvas.Pen.Color <> clNone then with PaintRect do
  883.        PaintCanvas.PolyLine([Point(Left, Bottom - 1), Point(Right - 1, Bottom - 1), Point(Right - 1, Top)]);
  884.     with ImageListSize do
  885.       Offset := Point(IconRect.Left + (fcRectWidth(IconRect) div 2 - cx div 2), IconRect.Top + (fcRectHeight(IconRect) div 2 - cy div 2));
  886.     if IsEffectiveItemHilite and Down then Offset := Point(Offset.x + 1, Offset.y + 1);
  887.     if Images <> nil then fcImageListDraw(Images, ImageIndex, PaintCanvas, Offset.x, Offset.y, ILD_NORMAL, True { self.enabled});
  888.     if self = TopItem then PaintScrollButton(sbUp);
  889.     if self = BottomItem then
  890.       PaintScrollButton(sbDown);
  891.     PaintCanvas.Brush.Color := OldBrush;
  892.     PaintCanvas.Pen.Color := OldPen;
  893.   end;
  894. end;
  895. procedure TfcOutlookListItem.Invalidate(Erase: Boolean);
  896. var r: TRect;
  897. begin
  898.   r := DisplayRect(drBounds, -1);
  899.   r.Top:= r.Top -1;
  900.   InvalidateRect(OutlookList.Handle, @r, Erase);
  901. end;
  902. constructor TfcOutlookListItems.Create(AOutlookList: TfcCustomOutlookList; ACollectionItemClass: TfcOutlookListItemClass);
  903. begin
  904.   inherited Create(ACollectionItemClass);
  905.   FOutlookList := AOutlookList;
  906. end;
  907. function TfcOutlookListItems.GetOwner: TPersistent;
  908. begin
  909.   result := OutlookList;
  910. end;
  911. function TfcOutlookListItems.GetItems(Index: Integer): TfcOutlookListItem;
  912. begin
  913.   result := inherited Items[Index] as TfcOutlookListItem;
  914. end;
  915. procedure TfcOutlookListItems.Update(Item: TCollectionItem);
  916. begin
  917.   OutlookList.Invalidate;
  918. end;
  919. function TfcOutlookListItems.Add: TfcOutlookListItem;
  920. begin
  921.   result := inherited Add as TfcOutlookListItem;
  922. end;
  923. function TfcOutlookListItems.AddItem: TfcCollectionItem;
  924. begin
  925.   result := Add;
  926. end;
  927. constructor TfcCustomOutlookList.Create(AOwner: TComponent);
  928. begin
  929.   inherited Create(AOwner);
  930.   ControlStyle := ControlStyle + [csReflector, csAcceptsControls] - [csCaptureMouse];
  931.   Color := clBtnShadow;
  932.   FBorderStyle := bsSingle;
  933.   FChangeLink := TChangeLink.Create;
  934.   FChangeLink.OnChange := ImageListChange;
  935.   FItems := TfcOutlookListItems.Create(self, TfcOutlookListItem);
  936.   FItemLayout := blGlyphTop;
  937.   FItemHotTrackColor := Color;
  938.   FItemDisabledTextColor:= clBtnFace;
  939.   FItemSpacing := 20;
  940.   FItemHighlightColor := clBtnFace;
  941.   FItemShadowColor := clBtnText;
  942.   FPaintBitmap := TBitmap.Create;
  943.   FPaintBitmap.Width := Width;
  944.   FPaintBitmap.Height := Height;
  945.   FScrollButtonsVisible := True;
  946.   FScrollInterval := 250;
  947.   {$ifdef fcDelphi4Up}
  948.   FItemSelectedDitherColor:= clBtnHighlight;
  949.   {$endif}
  950.   Font.Color := clWhite;
  951.   Transparent := False;
  952. end;
  953. destructor TfcCustomOutlookList.Destroy;
  954. begin
  955.   FPaintBitmap.Free;
  956.   FChangeLink.Free;
  957.   FItems.Free;
  958.   FreeHintWindow;
  959.   inherited;
  960. end;
  961. procedure TfcCustomOutlookList.CreateParams(var Params: TCreateParams);
  962. begin
  963.   inherited CreateParams(Params);
  964.   if BorderStyle = bsSingle then with Params do
  965.   begin
  966.     Style := Style and not WS_BORDER;
  967.     ExStyle := ExStyle or WS_EX_CLIENTEDGE;
  968.   end;
  969. end;
  970. procedure TfcCustomOutlookList.Loaded;
  971. begin
  972.   inherited;
  973.   ClickStyle := ClickStyle;
  974.   UpdateScrollButtonsRect;
  975. end;
  976. procedure TfcCustomOutlookList.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  977. var i: Integer;
  978.     pt: TPoint;
  979. begin
  980.   inherited;
  981.   HintWindow.Free;
  982.   HintWindow:= nil;
  983.   if Button <> mbLeft then Exit;
  984.   pt := Point(x, y);
  985.   if PtInRect(FUpButtonRect, pt) then FScrollButtonDown := sbUp
  986.   else if PtInRect(FDownButtonRect, pt) then FScrollButtonDown := sbDown
  987.   else FScrollButtonDown := sbNone;
  988.   if (FScrollButtonDown <> sbNone) and ScrollButtonVisible(FScrollButtonDown) then
  989.   begin
  990.     FOldCapture := GetCapture;
  991.     SetCapture(Handle);
  992.     InvalidateScrollButton(FScrollButtonDown);
  993.     SetTimer(Handle, ScrollTimerID, ScrollInterval, nil);
  994.   end else
  995.     if (TopItem <> nil) then for i := TopItem.Index to BottomItem.Index do
  996.     begin
  997.       if not Items[i].visible then continue; // 5/5/03
  998.       if not Items[i].Enabled then continue; // 5/5/03
  999.       if PtInRect(Items[i].ButtonRect, pt) then
  1000.       begin
  1001.         Items[i].MouseDownOnItem := True;
  1002.         Break;
  1003.       end
  1004.     end;
  1005. end;
  1006. Function TfcCustomOutlookList.GetImager: TfcCustomImager;
  1007. begin
  1008.    result:=nil;
  1009.    if OutlookPage=nil then exit;
  1010.    if TfcOutlookPage(OutlookPage).OutlookBar=nil then exit;
  1011.    result:= TfcOutlookPage(OutlookPage).OutlookBar.Imager;
  1012. end;
  1013. procedure TfcCustomOutlookList.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  1014. var OldScrollButtonDown: TfcScrollButtonStyle;
  1015.     i: Integer;
  1016.     pt: TPoint;
  1017. begin
  1018.   inherited;
  1019.   if Button <> mbLeft then Exit;
  1020.   pt := Point(x, y);
  1021.   if TopItem <> nil then
  1022.     for i := TopItem.Index to BottomItem.Index do
  1023.     begin
  1024.       if not Items[i].visible then continue; // 5/5/03
  1025.       if i>=Items.Count then break;  // 2/7/2002-Added to handle case where ItemClick deletes an item.
  1026.       if Items[i].MouseDownOnItem and PtInRect(Items[i].ButtonRect, pt) then ItemClick(Items[i]);
  1027.       Items[i].MouseDownOnItem := False;
  1028.     end;
  1029.   OldScrollButtonDown := FScrollButtonDown;
  1030.   if ScrollButtonVisible(FScrollButtonDown) then case FScrollButtonDown of
  1031.     sbUp: if PtInRect(FUpButtonRect, pt) then ScrollButtonClick;
  1032.     sbDown: if PtInRect(FDownButtonRect, pt) then ScrollButtonClick;
  1033.   end;
  1034.   if (FScrollButtonDown <> sbNone) then
  1035.   begin
  1036.     KillTimer(Handle, ScrollTimerID);
  1037.     ReleaseCapture;
  1038.     SetCapture(FOldCapture);
  1039.     FScrollButtonDown := sbNone;
  1040.     InvalidateScrollButton(OldScrollButtonDown);
  1041.   end;
  1042. end;
  1043. type
  1044.   TOutlookListHintWindow=class(THintWindow)
  1045.   public
  1046.      HintItem: TfcOutlookListItem;
  1047.      HintRect: TRect;
  1048.   end;
  1049. procedure TfcCustomOutlookList.MouseMove(Shift: TShiftState; X, Y: Integer);
  1050. var pt, cursorpt: TPoint;
  1051.     i,j: Integer;
  1052.     DoReleaseCapture: Boolean;
  1053.     TempMouseOnItem: boolean;
  1054.     OutlookBar: TfcCustomOutlookBar;
  1055.     HintRect: TRect;
  1056. begin
  1057.   inherited;
  1058.   pt := Point(x, y);
  1059.   DoReleaseCapture := True;
  1060.   if TopItem <> nil then for i := TopItem.Index to BottomItem.Index do
  1061.   begin
  1062.     if not Items[i].visible then continue; // 5/5/03
  1063.     TempMouseOnItem:= False;{ 3/23/00 - Use temporary variable as setting
  1064.       property loses capture }
  1065.     if FindVCLWindow(ClientToScreen(pt)) = self then
  1066.     begin
  1067.        if PtInRect(Items[i].ButtonRect, pt) and (pt.x < Width) and (pt.y < Height) then
  1068.           TempMouseOnItem:= True;
  1069.     end;
  1070.     if TempMouseOnItem then DoReleaseCapture := False;
  1071.     if (not Items[i].MouseOnItem) and (TempMouseOnItem) and (Items[i].Enabled) and
  1072.        not (csDestroying in ComponentState) and (Items[i].Hint<>'') then
  1073.     begin
  1074.       if HintWindow=nil then
  1075.       begin
  1076.         HintWindow:= TOutlookListHintWindow.create(parent);
  1077.       end;
  1078.       if HintTimer=nil then
  1079.       begin
  1080.         HintTimer:= TTimer.create(nil);
  1081.         HintTimer.OnTimer:=HintTimerEvent;
  1082.         HintTimer.Interval:=250;
  1083.       end;
  1084.       HintTimer.Enabled:= True;
  1085.       HintWindow.Color:= GetSysColor(COLOR_INFOBK);
  1086.       HintWindow.Canvas.Brush.Color:= GetSysColor(COLOR_INFOBK);
  1087.       HintWindow.Canvas.Font:= self.Font;
  1088.       HintWindow.Canvas.Font.Color:= GetSysColor(COLOR_INFOTEXT);
  1089.       HintWindow.Canvas.Pen.Color:= clBlack;
  1090.       HintRect.Left:= Items[i].FButtonRect.Left;
  1091.       HintRect.Top:= Items[i].FButtonRect.Top;
  1092.       cursorPt.x:= HintRect.Left;
  1093.       cursorpt.y:= HintRect.Top;
  1094.       cursorPt:= ClientToScreen(cursorPt);
  1095.       HintRect.Left:= cursorpt.X;
  1096.       HintRect.Top:= cursorpt.y;
  1097.       HintRect.Right:= HintRect.Left + HintWindow.Canvas.TextWidth(Items[i].Hint) + 8;
  1098.       HintRect.Bottom:= HintRect.Top + HintWindow.Canvas.TextHeight(Items[i].Hint) + 3;
  1099.       TOutlookListHintWindow(HintWindow).HintItem:= Items[i];
  1100.       TOutlookListHintWindow(HintWindow).HintRect:= HintRect;
  1101.     end
  1102.     else if (not Items[i].MouseOnItem) and (TempMouseOnItem) and (Items[i].Enabled) and
  1103.        not (csDestroying in ComponentState) then
  1104.     begin
  1105.        FreeHintWindow;
  1106.     end;
  1107.     Items[i].MouseOnItem:= TempMouseOnItem;
  1108.     // Important for themes so that control is invalidated
  1109.     // We do this by sending CMMouseLeave to button which
  1110.     // is responsible for invalidating control
  1111.     if TempMouseOnItem and (TfcOutlookPage(OutlookPage).OutlookBar<>nil) then
  1112.     begin
  1113.        OutlookBar:= TfcOutlookPage(OutlookPage).OutlookBar;
  1114.        with OutlookBar.OutlookItems do begin
  1115.           // Iterate through hot buttons and set Hot to false and invalidate
  1116.           // this button
  1117.           for j:= 0 to count-1 do
  1118.              if Items[j].Button.hot then
  1119.              begin
  1120.                 Items[j].Button.hot:= false;
  1121.                 Items[j].Button.Perform(CM_MOUSELEAVE, 0, 0);
  1122. //                Items[j].Button.invalidate;
  1123.              end
  1124.        end
  1125.     end
  1126.   end;
  1127.   if DoReleaseCapture and (GetCapture = Handle) then
  1128.     ReleaseCapture;
  1129.   if PtInRect(FUpButtonRect, pt) then MouseInScrollButton := sbUp
  1130.   else if PtInRect(FDownButtonRect, pt) then MouseInScrollButton := sbDown
  1131.   else MouseInScrollButton := sbNone;
  1132. end;
  1133. procedure TfcCustomOutlookList.Notification(AComponent: TComponent; Operation: TOperation);
  1134. var i: integer;
  1135. begin
  1136.   inherited;
  1137.   if (Operation = opRemove) and (AComponent = FImageList) then
  1138.   begin
  1139.     FImageList := nil; // So UnRegisterChanges in .SetImageList will not be called
  1140.     Images := nil;  // So Invalidate will be called
  1141.   end
  1142.   else if Operation = opRemove then
  1143.   begin
  1144.      if AComponent = Action then begin
  1145.         { Iterate through items and remove matching item's action property }
  1146.         for i := 0 to Items.Count - 1 do
  1147.            if AComponent = Items[i].Action then
  1148.               Items[i].Action:= nil;
  1149.      end
  1150.   end
  1151. end;
  1152. procedure TfcCustomOutlookList.CMDesignHitTest(var Message: TCMDesignHitTest);
  1153. begin
  1154.   inherited;
  1155.   if PtInRect(FUpButtonRect, SmallPointToPoint(Message.Pos)) or
  1156.      PtInRect(FDownButtonRect, SmallPointToPoint(Message.Pos)) then
  1157.     Message.Result := 1;
  1158. end;
  1159. procedure TfcCustomOutlookList.WMEraseBkgnd(var Message: TWMEraseBkGnd);
  1160. begin
  1161. //  inherited;
  1162.   Message.result := 1;  { 3/19/99 - RSW Prevents flicker when animating.  If
  1163.                           this is a problem, may want to add flag so that this
  1164.                           code will only execute during animation, and call inherited otherwise}
  1165. end;
  1166. procedure TfcCustomOutlookList.WMSize(var Message: TWMSize);
  1167. begin
  1168.   inherited;
  1169.   FPaintBitmap.Free;
  1170.   FPaintBitmap := TBitmap.Create;
  1171.   FPaintBitmap.Width := ClientWidth;
  1172.   FPaintBitmap.Height := ClientHeight;
  1173.   UpdateScrollButtonsRect;
  1174. end;
  1175. procedure TfcCustomOutlookList.WMTimer(var Message: TWMTimer);
  1176. begin
  1177.   inherited;
  1178.   if (Message.TimerID = ScrollTimerId) then
  1179.     with ScreenToClient(fcGetCursorPos) do
  1180.         if ScrollButtonVisible(FScrollButtonDown) then 
  1181.       case FScrollButtonDown of
  1182.         sbUp: if PtInRect(FUpButtonRect, Point(x, y)) then ScrollButtonClick;
  1183.         sbDown: if PtInRect(FDownButtonRect, Point(x, y)) then ScrollButtonClick;
  1184.       end;
  1185. end;
  1186. procedure TfcCustomOutlookList.DoDrawItem(Item: TfcOutlookListItem; var GlyphPos, TextPos: TPoint; var DefaultDrawing: Boolean);
  1187. begin
  1188.   if Assigned(FOnDrawItem) then FOnDrawItem(self, Item, GlyphPos, TextPos, DefaultDrawing);
  1189. end;
  1190. procedure TfcCustomOutlookList.ImageListChange(Sender: TObject);
  1191. begin
  1192.   Invalidate;
  1193. end;
  1194. procedure TfcCustomOutlookList.InvalidateScrollButton(Button: TfcScrollButtonStyle);
  1195. begin
  1196.   case Button of
  1197.     sbUp: InvalidateRect(Handle, @FUpButtonRect, False);
  1198.     sbDown: InvalidateRect(Handle, @FDownButtonRect, False);
  1199.   end;
  1200. end;
  1201. function TfcCustomOutlookList.GetBottomItem: TfcOutlookListItem;
  1202. var i: Integer;
  1203.     Total: Integer;
  1204. begin
  1205.   result := nil;
  1206.   if TopItem = nil then Exit;
  1207.   result := TopItem;
  1208.   Total := 0;
  1209.   for i := TopItem.Index to Items.Count - 1 do
  1210.   begin
  1211.     if not Items[i].visible then continue; //5/5/03
  1212.     result := Items[i];
  1213.     inc(Total, Items[i].SpacingSize);
  1214.     if ((Layout = loVertical) and (Total > ClientHeight)) or
  1215.        ((Layout = loHorizontal) and (Total > ClientWidth)) then Break;
  1216.   end;
  1217. end;
  1218. function TfcCustomOutlookList.GetPaintCanvas: TCanvas;
  1219. begin
  1220.   result := FPaintBitmap.Canvas;
  1221. end;
  1222. function TfcCustomOutlookList.GetSelected: TfcOutlookListItem;
  1223. var i: Integer;
  1224. begin
  1225.   result := nil;
  1226.   for i := 0 to Items.Count - 1 do
  1227.   begin
  1228.     if Items[i].Selected then
  1229.     begin
  1230.       result := Items[i];
  1231.       Break;
  1232.     end;
  1233.   end;
  1234. end;
  1235. function TfcCustomOutlookList.GetListItems(Index: Integer): TfcOutlookListItem;
  1236. begin
  1237.   result := Items[Index] as TfcOutlookListItem;
  1238. end;
  1239. function TfcCustomOutlookList.GetTopItem: TfcOutlookListItem;
  1240. var i: integer;
  1241. begin
  1242.   if (FTopItem = nil) and (Items.Count > 0) then // 5/5/03
  1243.   begin
  1244.      i:= 0;
  1245.      while (i<Items.count) and (not Items[i].visible) do
  1246.      begin
  1247.        inc(i);
  1248.      end;
  1249.      if i<Items.count then
  1250.         FTopItem:= Items[i];
  1251.   end;
  1252.   result := FTopItem;
  1253. end;
  1254. procedure TfcCustomOutlookList.SetBorderStyle(Value: TBorderStyle);
  1255. begin
  1256.   if FBorderStyle <> Value then
  1257.   begin
  1258.     FBorderStyle := Value;
  1259.     RecreateWnd;
  1260.   end;
  1261. end;
  1262. procedure TfcCustomOutlookList.SetClickStyle(Value: TfcCustomOutlookListClickStyle);
  1263. begin
  1264.   FClickStyle := Value;
  1265. end;
  1266. procedure TfcCustomOutlookList.SetImageList(Value: TCustomImageList);
  1267. begin
  1268.   if (FImageList <> nil) then FImageList.UnregisterChanges(FChangeLink);
  1269.   FImageList := Value;
  1270.   if Value <> nil then
  1271.   begin
  1272.     Value.FreeNotification(self);
  1273.     Value.RegisterChanges(FChangeLink);
  1274.   end;
  1275.   Invalidate;
  1276. end;
  1277. procedure TfcCustomOutlookList.SetItemLayout(Value: TButtonLayout);
  1278. begin
  1279.   if FItemLayout <> Value then
  1280.   begin
  1281.     FItemLayout := Value;
  1282.     Invalidate;
  1283.   end;
  1284. end;
  1285. procedure TfcCustomOutlookList.SetItemHighlightColor(Value: TColor);
  1286. begin
  1287.   if FItemHighlightColor <> Value then
  1288.   begin
  1289.     FItemHighlightColor := Value;
  1290.     Invalidate;
  1291.   end;
  1292. end;
  1293. procedure TfcCustomOutlookList.SetItemDisabledTextColor(Value: TColor);
  1294. begin
  1295.   if FItemDisabledTextColor <> Value then
  1296.   begin
  1297.     FItemDisabledTextColor := Value;
  1298.     Invalidate;
  1299.   end;
  1300. end;
  1301. procedure TfcCustomOutlookList.SetItemShadowColor(Value: TColor);
  1302. begin
  1303.   if FItemShadowColor <> Value then
  1304.   begin
  1305.     FItemShadowColor := Value;
  1306.     Invalidate;
  1307.   end;
  1308. end;
  1309. procedure TfcCustomOutlookList.SetItems(Value: TfcOutlookListItems);
  1310. begin
  1311.   FItems.Assign(Value);
  1312. end;
  1313. procedure TfcCustomOutlookList.SetItemSpacing(Value: Integer);
  1314. begin
  1315.   if FItemSpacing <> Value then
  1316.   begin
  1317.     FItemSpacing := Value;
  1318.     if Odd(FItemSpacing) then inc(FItemSpacing);
  1319.     Invalidate;
  1320.   end;
  1321. end;
  1322. procedure TfcCustomOutlookList.SetItemsWidth(Value: Integer);
  1323. begin
  1324.   if FItemsWidth <> Value then
  1325.   begin
  1326.     FItemsWidth := Value;
  1327.     Invalidate;
  1328.   end;
  1329. end;
  1330. procedure TfcCustomOutlookList.SetLayout(Value: TfcLayout);
  1331. begin
  1332.   if FLayout <> Value then
  1333.   begin
  1334.     FLayout := Value;
  1335.     Invalidate;
  1336.   end;
  1337. end;
  1338. procedure TfcCustomOutlookList.SetMouseInScrollButton(Value: TfcScrollButtonStyle);
  1339. begin
  1340.   if (FMouseInScrollButton <> Value) and ScrollButtonVisible(Value) then
  1341.   begin
  1342.     InvalidateScrollButton(FMouseInScrollButton);
  1343.     FMouseInScrollButton := Value;
  1344.     InvalidateScrollButton(Value);
  1345.   end;
  1346. end;
  1347. procedure TfcCustomOutlookList.SetScrollButtonsVisible(Value: Boolean);
  1348. begin
  1349.   if FScrollButtonsVisible <> Value then
  1350.   begin
  1351.     FScrollButtonsVisible := Value;
  1352.     Invalidate;
  1353.   end;
  1354. end;
  1355. procedure TfcCustomOutlookList.SetTopItem(Value: TfcOutlookListItem);
  1356. begin
  1357.   if FTopItem <> Value then
  1358.   begin
  1359.     FTopItem := Value;
  1360.     Invalidate;
  1361.   end;
  1362. end;
  1363. function TfcCustomOutlookList.GetFirstVisibleItem: TfcOutlookListItem;
  1364. var i: integer;
  1365. begin
  1366.    result:= nil;
  1367.    for i:= 0 to Items.count-1 do
  1368.    begin
  1369.        if items[i].visible then
  1370.        begin
  1371.           result:= items[i];
  1372.           exit;
  1373.        end;
  1374.   end;
  1375. end;
  1376. function TfcCustomOutlookList.ScrollButtonVisible(Button: TfcScrollButtonStyle): Boolean;
  1377. begin
  1378.   result := False;
  1379.   case Button of
  1380.     sbUp: result := not ((TopItem = nil) or (TopItem = GetFirstVisibleItem));
  1381.     sbDown: begin
  1382.       result := (TopItem<>nil) and (GetNextVisibleItem(BottomItem)<>nil);
  1383.     end;
  1384.   end;
  1385. end;
  1386. function TfcCustomOutlookList.GetItemAt(x, y: Integer): TfcOutlookListItem;
  1387. var i: Integer;
  1388. begin
  1389.   result := nil;
  1390.   for i := 0 to Items.Count - 1 do
  1391.     //3/24/2000 - PYW - Made sure Item is visible when checking if point is in ItemRect.
  1392.     if (Items[i].IsVisible(True)) and (PtInRect(Items[i].ItemRect, Point(x, y))) then
  1393.     begin
  1394.       result := Items[i];
  1395.       Break;
  1396.     end;
  1397. end;
  1398. procedure TfcCustomOutlookList.PaintScrollButton(Button: TfcScrollButtonStyle);
  1399. const ButtonStates: array[Boolean] of Integer = (0, DFCS_PUSHED);
  1400. var bm: TBitmap;
  1401.     resName: string;
  1402.     Down: Boolean;
  1403.     Offset: TPoint;
  1404.     r: TRect;
  1405. //    Details: TThemedElementDetails;
  1406. //    Style: TThemedScrollBar;
  1407. begin
  1408.   if not ScrollButtonVisible(Button) or not ScrollButtonsVisible then Exit;
  1409.   if Button = sbUp then r := FUpButtonRect else r := FDownButtonRect;
  1410.   Down := (MouseInScrollButton = Button) and (FScrollButtonDown = Button);
  1411.   case Button of
  1412.      sbUp: if Layout = loVertical then resName := 'FCDROPUP' else resName := 'FCDROPLEFT';
  1413.      sbDown: if Layout = loVertical then resName := 'FCDROPDOWN' else resName := 'FCDROPRIGHT';
  1414.   end;
  1415. {  if ThemeServices.ThemesEnabled then
  1416.   begin
  1417.       if resName = 'FCDROPUP' then style:= tsArrowBtnUpNormal
  1418.       else if resName = 'FCDROPDOWN' then style:= tsArrowBtnDownNormal
  1419.       else if resName = 'FCDROPLEFT' then style:= tsArrowBtnLeftNormal
  1420.       else if resName = 'FCDROPRIGHT' then style:= tsArrowBtnRightNormal;
  1421.       Details := ThemeServices.GetElementDetails(Style);
  1422.       ThemeServices.DrawElement(PaintCanvas.Handle, Details, r);
  1423.       ThemeServices.DrawParentBackground(Handle, PaintCanvas.Handle, nil, False, @r);
  1424.       exit;
  1425.   end;
  1426. }
  1427.   DrawFrameControl(PaintCanvas.Handle, r, DFC_BUTTON, DFCS_BUTTONPUSH or ButtonStates[Down]);
  1428. //  case Button of
  1429. //    sbUp: if Layout = loVertical then resName := 'FCDROPUP' else resName := 'FCDROPLEFT';
  1430. //    sbDown: if Layout = loVertical then resName := 'FCDROPDOWN' else resName := 'FCDROPRIGHT';
  1431. //  end;
  1432.   bm := TBitmap.Create;
  1433.   bm.Transparent := True;
  1434.   bm.LoadFromResourceName(HINSTANCE, resName);
  1435.   if Layout = loVertical then Offset := Point(r.Left + 2, r.Top + 5)
  1436.   else Offset := Point(r.Left + 5, r.Top + 3);
  1437.   if Down then with Offset do Offset := Point(x + 1, y + 1);
  1438.   PaintCanvas.Draw(Offset.x, Offset.y, bm);
  1439.   bm.Free;
  1440. end;
  1441. procedure TfcCustomOutlookList.ItemClick(Item: TfcOutlookListItem);
  1442. begin
  1443.   if (ClickStyle = csSelect) and not Item.Selected then
  1444.   begin
  1445.     Item.Selected := True;
  1446.     if Assigned(FOnItemChange) then FOnItemChange(self, Item);
  1447.   end;
  1448.   if Assigned(FOnItemClick) then FOnItemClick(self, Item);
  1449.   { 4/14/99 - RSW - Added following 2 lines }
  1450.   if Assigned(Item.FOnClick) then Item.FOnClick(self, Item);
  1451.   if Assigned(Item.Action) and Assigned(Item.Action.OnExecute) then
  1452.      Item.Action.OnExecute(Item);
  1453.   UpdateMouseOnItem;
  1454. end;
  1455. function TfcCustomOutlookList.GetNextVisibleItem(item: TfcOutlookListItem): TfcOutlookListItem;
  1456. var curIndex: integer;
  1457. begin
  1458.   result:= nil;
  1459.   if item=nil then exit;
  1460.   curIndex:= item.index;
  1461.   repeat
  1462.      inc(curIndex);
  1463.      if curIndex>items.count-1 then exit;
  1464.      if items[curIndex].visible then
  1465.      begin
  1466.         result:= items[curIndex];
  1467.         exit;
  1468.      end;
  1469.   until (curIndex>=items.count-1);
  1470. end;
  1471. function TfcCustomOutlookList.GetPriorVisibleItem(item: TfcOutlookListItem): TfcOutlookListItem;
  1472. var curIndex: integer;
  1473. begin
  1474.   result:= nil;
  1475.   if item=nil then exit;
  1476.   curIndex:= item.index;
  1477.   repeat
  1478.      dec(curIndex);
  1479.      if curIndex<0 then exit;
  1480.      if items[curIndex].visible then
  1481.      begin
  1482.         result:= items[curIndex];
  1483.         exit;
  1484.      end;
  1485.   until (curIndex<0);
  1486. end;
  1487. procedure TfcCustomOutlookList.ScrollButtonClick;
  1488. begin
  1489.   case FScrollButtonDown of
  1490.     sbUp: if (TopItem <> nil) and (TopItem.Index > 0) then TopItem := GetPriorVisibleItem(TopItem); //Items[TopItem.Index - 1];
  1491.     sbDown: if (TopItem <> nil) and (TopItem.Index < Items.Count - 1) then TopItem := GetNextVisibleItem(TopItem); //Items[TopItem.Index + 1];
  1492.   end;
  1493.   UpdateButtonRects;  // Moved, Insures that the hotrack rect is on the correct item; previously prevented OnDrawText from working properly -ksw (4/30/99)
  1494.   UpdateMouseOnItem;
  1495. end;
  1496. procedure TfcCustomOutlookList.UpdateMouseOnItem;
  1497. var i: Integer;
  1498.     pt: TPoint;
  1499. begin
  1500.   pt := ScreenToClient(fcGetCursorPos);
  1501.   if TopItem <> nil then for i := TopItem.Index to BottomItem.Index do
  1502.   begin
  1503.     if not Items[i].visible then continue; // 5/5/03
  1504.     Items[i].MouseOnItem := PtInRect(Items[i].ButtonRect, pt);
  1505.   end
  1506. end;
  1507. procedure TfcCustomOutlookList.UpdateScrollButtonsRect;
  1508. begin
  1509.   if Layout = loVertical then
  1510.   begin
  1511.     FUpButtonRect := Rect(Width - 25, 10, Width - 10, 25);
  1512.     FDownButtonRect := Rect(Width - 25, Height - 25, Width - 10, Height - 10);
  1513.   end else begin
  1514.     FUpButtonRect := Rect(10, 10, 25, 25);
  1515.     FDownButtonRect := Rect(Width - 25, 10, Width - 10, 25);
  1516.   end;
  1517. end;
  1518. procedure TfcCustomOutlookList.Paint;
  1519. var i: Integer;
  1520. begin
  1521.   inherited;
  1522.   if not Transparent then { 5/2/99 - Transparent fills in with parent outlookbar color }
  1523.   begin
  1524.     PaintCanvas.Brush.Color := Color;
  1525.     PaintCanvas.FillRect(Rect(0, 0, ClientWidth, ClientHeight));
  1526.   end else begin
  1527.      if GetImager<>nil then
  1528.      begin
  1529.         if GetImager.DrawStyle=dsTile then
  1530.            GetImager.WorkBitmap.TileDraw(PaintCanvas, Parent.BoundsRect)
  1531.         else
  1532.            PaintCanvas.StretchDraw(Parent.ClientRect, GetImager.WorkBitmap);
  1533.      end
  1534.      else begin
  1535.         PaintCanvas.Brush.Color := TfcOutlookPage(OutlookPage).OutlookBar.Color;
  1536.         PaintCanvas.FillRect(Rect(0, 0, ClientWidth, ClientHeight));
  1537.      end
  1538.   end;
  1539.   PaintCanvas.Font.Assign(Font);
  1540.   if TopItem <> nil then
  1541.   begin
  1542.     for i := TopItem.Index to BottomItem.Index do
  1543.     begin
  1544.       if not Items[i].visible then continue;
  1545.       Items[i].Paint;
  1546.     end;
  1547.     PaintScrollButton(sbUp);
  1548.     PaintScrollButton(sbDown);
  1549.   end;
  1550.   Canvas.CopyRect(Rect(0, 0, ClientWidth, ClientHeight), PaintCanvas, Rect(0, 0, ClientWidth, ClientHeight));
  1551. end;
  1552. procedure TfcCustomOutlookList.UpdateButtonRects;
  1553. var i: Integer;
  1554. begin
  1555.   for i := TopItem.Index to BottomItem.Index do
  1556.     if not IsEffectiveItemHilite then Items[i].FButtonRect := Items[i].DisplayRect(drIcon, -1)
  1557.     else Items[i].FButtonRect := Items[i].DisplayRect(drBounds, -1);
  1558. end;
  1559. procedure TfcCustomOutlookList.ValidateInsert(AComponent: TComponent);
  1560. begin
  1561.   raise EInvalidOperation.Create('TfcCustomOutlookList does not accept child controls.  Delete ' +
  1562.     'TfcCustomOutlookList and/or set the options property of the TfcControlBar, "cboAutoCreateOutlookList", to False');
  1563. end;
  1564. function TfcCustomOutlookList.IsEffectiveItemHilite: boolean;
  1565. begin
  1566.    result:= (HotTrackStyle=hsItemHilite) or (Images=nil)
  1567. end;
  1568. function TfcOutlookListItem.GetAction: TBasicAction;
  1569. begin
  1570.   if ActionLink <> nil then
  1571.     Result := ActionLink.Action else
  1572.     Result := nil;
  1573. end;
  1574. procedure TfcOutlookListItem.SetAction(Value: TBasicAction);
  1575. begin
  1576.   if Value = nil then
  1577.   begin
  1578.     ActionLink.Free;
  1579.     ActionLink := nil;
  1580.   end
  1581.   else
  1582.   begin
  1583.     if ActionLink = nil then
  1584.       ActionLink := TfcOutlookItemActionLinkClass.Create(Self);
  1585.     ActionLink.Action := Value;
  1586.     ActionLink.OnChange := DoActionChange;
  1587.     ActionChange(Value, csLoading in Value.ComponentState);
  1588.     Value.FreeNotification(OutlookList);
  1589.   end;
  1590. end;
  1591. procedure TfcOutlookListItem.ActionChange(Sender: TObject; CheckDefaults: Boolean);
  1592. begin
  1593.   if Sender is TCustomAction then
  1594.     with TCustomAction(Sender) do
  1595.     begin
  1596.       if not CheckDefaults or (Self.text = '') then
  1597.         Self.Text := Caption;
  1598.       if not CheckDefaults or (Self.Enabled = True) then
  1599.         Self.Enabled := Enabled;
  1600.       if not CheckDefaults or (Self.Hint = '') then
  1601.         Self.Hint := Hint;
  1602.       if not CheckDefaults or (Self.Visible = True) then
  1603.         Self.Visible := Visible;
  1604. //      if not CheckDefaults or not Assigned(Self.OnClick) then
  1605. //        Self.OnExecuteAction := OnExecute;
  1606.     end;
  1607. end;
  1608. procedure TfcOutlookListItem.DoActionChange(Sender: TObject);
  1609. begin
  1610.   if Sender = Action then ActionChange(Sender, False);
  1611. end;
  1612. procedure TfcOutlookItemActionLink.AssignClient(AClient: TObject);
  1613. begin
  1614.    FItem:= AClient as TfcOutlookListItem;
  1615. end;
  1616. function TfcOutlookItemActionLink.IsCaptionLinked: Boolean;
  1617. begin
  1618.    result:= true;
  1619. end;
  1620. function TfcOutlookItemActionLink.IsEnabledLinked: Boolean;
  1621. begin
  1622.    result:= true;
  1623. end;
  1624. function TfcOutlookItemActionLink.IsHintLinked: Boolean;
  1625. begin
  1626.    result:= true;
  1627. end;
  1628. function TfcOutlookItemActionLink.IsVisibleLinked: Boolean;
  1629. begin
  1630.    result:= true;
  1631. end;
  1632. function TfcOutlookItemActionLink.IsOnExecuteLinked: Boolean;
  1633. begin
  1634.    result:= true;
  1635. end;
  1636. {function TfcOutlookItemActionLink.DoShowHint(var HintStr: string): Boolean;
  1637. begin
  1638. end;
  1639. }
  1640. procedure TfcOutlookItemActionLink.SetCaption(const Value: string);
  1641. begin
  1642.   if IsCaptionLinked and (Value<>'') then FItem.Text := Value;
  1643. end;
  1644. procedure TfcOutlookItemActionLink.SetEnabled(Value: Boolean);
  1645. begin
  1646.    FItem.Enabled:= Value;
  1647. end;
  1648. procedure TfcOutlookItemActionLink.SetHint(const Value: string);
  1649. begin
  1650.    FItem.Hint:= Value;
  1651. end;
  1652. procedure TfcOutlookItemActionLink.SetVisible(Value: Boolean);
  1653. begin
  1654.    FItem.Visible:= Value;
  1655. end;
  1656. {procedure TfcOutlookItemActionLink.SetOnExecute(Value: TNotifyEvent);
  1657. begin
  1658.   FItem.OnExecuteAction:= Value;
  1659. end;
  1660. }
  1661. procedure TfcCustomOutlookList.HintTimerEvent(Sender: TObject);
  1662. var
  1663.     sp, cp: TPoint;
  1664.     OutsideClient: boolean;
  1665.     hintTimerInterval: integer;
  1666.     i: integer;
  1667. begin
  1668.    if (HintWindow=nil) then exit;
  1669.    GetCursorPos(cp);
  1670.    sp:= self.ScreenToClient(cp);
  1671.    if TopItem <> nil then
  1672.     for i := TopItem.Index to BottomItem.Index do
  1673.     begin
  1674.       if not Items[i].visible then continue; // 5/5/03
  1675.       if i>=Items.Count then break;  // 2/7/2002-Added to handle case where ItemClick deletes an item.
  1676.       if Items[i].MouseOnItem then
  1677.       begin
  1678.          if (not PtInRect(Items[i].ButtonRect, sp)) then
  1679.          begin
  1680.             Items[i].MouseOnItem := False;
  1681.             FreeHintWindow;
  1682.          end
  1683.          else begin
  1684.            if HintTimerCount=1 then
  1685.            begin
  1686.               HintWindow.ActivateHint(TOutlookListHintWindow(HintWindow).HintRect,
  1687.                    TOutlookListHintWindow(HintWindow).HintItem.Hint);
  1688.               exit;
  1689.            end
  1690.          end
  1691.       end
  1692.     end;
  1693.    sp:= self.ClientToScreen(Point(0, 0));
  1694.    if (cp.x<sp.x) or (cp.x>sp.x+ClientRect.Right-ClientRect.Left) or
  1695.       (cp.y<sp.y) or (cp.y>sp.y+ClientRect.Bottom-ClientRect.Top) then
  1696.    begin
  1697.       OutsideClient:= True;
  1698.    end
  1699.    else OutsideClient:= False;
  1700.    { Process Hint Timer clean-up}
  1701.    if OutsideClient then
  1702.    begin
  1703.       FreeHintWindow;
  1704.    end
  1705.    else begin
  1706.       inc(HintTimerCount);
  1707.       HintTimerInterval:= HintTimer.interval;
  1708.       if HintTimerCount>
  1709.          fcMax(Application.HintHidePause div HintTimerInterval, 10) then
  1710.       begin
  1711.         FreeHintWindow;
  1712.       end
  1713.    end
  1714. end;
  1715. procedure TfcCustomOutlookList.FreeHintWindow;
  1716. begin
  1717.    HintTimerCount:= 0;
  1718.    HintWindow.Free;
  1719.    HintWindow:= nil;
  1720.    if HintTimer<>nil then HintTimer.enabled:= False;
  1721. end;
  1722. initialization
  1723.   RegisterClasses([TfcOutlookList]);
  1724. end.