home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 January / Pcwk0198.iso / Dcomplib / BIGTEXT.LZH / BIGTEXT.PAS < prev    next >
Pascal/Delphi Source File  |  1995-10-05  |  38KB  |  1,241 lines

  1. unit BigText;
  2. { TBigText 3.1  (c) 1995 by Gerry Skolnik (skolnik@kapsch.co.at)
  3.  
  4.                 A big thanx to the following contributors:
  5.  
  6.                 (c) 1995 by Danny Thorpe
  7.                             original scrolling and keyboard handling
  8.                             as he gave no email address, he doesn't
  9.                             know about it, I took his stuff from his
  10.                             TConsole component :-)
  11.  
  12.                 (c) 1995 by David Sampson (dsampson@dca.com) -
  13.                             Color,  Scroll Bar and Text Attribute enhancements
  14.  
  15.                 (c) 1995 by Eric Heverly (erichev@ix.netcom.com)
  16.                             Search capability, Positioning, cursor fixes
  17.  
  18.   history:
  19.   TBigText 1.x  - first release
  20.   TBigText 2.x  - never made it, chaos is not a theory
  21.   TBigText 3.0  - enhancements by David Sampson, Eric Heverly
  22.   TBigText 3.1  - bug fix (horizontal scrolling) by Gerry Skolnik
  23.  
  24.   This component will display up to 32767 lines of text. Each line has its
  25.   own dedicated foreground, background color, text attributes and can be 255
  26.   chars long. If memory permits this is a maximum of about 8MB of data.
  27.   At this time no editing functions are available.
  28.  
  29.   TBigList is still there because at the time I wrote this I didn't know about
  30.   HugeList. Talk about reinventing the wheel.
  31.  
  32.   TBigText is limited to 32767 lines, because the Windows API functions only
  33.   accept integer values. Expect some problems a little earlier, though, at
  34.   about 32740.
  35.  
  36.   TBigText is FreeWare. You may use it freely at your own risk in any
  37.   kind of environment. This component is not to be sold at any charge, and
  38.   must be distributed along with the source code.
  39.  
  40.   If you make modifications or enhancements to this component, please
  41.   contact me via email so that I can include your stuff in the next
  42.   release. As Delphi32 won't produce Win3.x code, and we still will
  43.   have to support Win 3.x, this component may survive a little longer
  44.   longer than I'd expected...
  45.  
  46.   property MaxLines
  47.            if set to 0, as much lines as memory permits are included. The
  48.            absolute maximum, however, is 32767. If set to something else,
  49.            TBigText will limit itself to that many lines.
  50.  
  51.   property PurgeLines
  52.            determines how to handle the situation when no more lines can be
  53.            added (line count reached Maxlines value or we ran out of memory).
  54.            if set to 0, an exception is raised. If set to something different
  55.            (default 200) the number of lines specified by PurgeLines are
  56.            deleted, the TBigList objects are packed, and most likely more
  57.            lines can be added (though the first ones will be lost).
  58.            This option is useful for logging windows.
  59.  
  60.   property Count
  61.            run-time read-only. If the Lines and TextAttrib counts are equal, this
  62.            property holds the number of lines in TBigText. If the two counts are
  63.            unequal, there's something wrong and the property holds a value of -1.
  64.  
  65.   procedure AddLine(LineString: string; FCol, BCol: TColor; UpdateDisplay: boolean);
  66.            The essential routine to insert lines into TBigText.
  67.            LineString   : the text to be inserted
  68.            FCol         : forground color
  69.            BCol         : background color
  70.            UpdateDisplay: if true, TBigText will scroll to the last line
  71.                           (where the new line will be added), and update
  72.                           its display. This is not recommended if lots of
  73.                           lines are to be included in a loop.
  74.  
  75.   procedure LoadFromFile(FileName: TFileName);
  76.            Loads a file into TBigText. Every line will have the default colors
  77.            clWindowText, clWindow.
  78.  
  79.   procedure Print
  80.            prints all lines on the specified printer. Haven't checked this out, though.
  81.  
  82.   procedure ChangeColor(Index: longint; OldFCol, OldBCol, NewFCol, NewBCol: TColor);
  83.            changes the colors of the line at Index, but only if the current colors
  84.            match OldFCol and OldBCol (FCol = foreground color, BCol = background color).
  85.  
  86.   procedure SetColors(Index: longint; NewFCol, NewBCol: TColor);
  87.            changes the colors of the line at Index
  88.  
  89.   the following procedures do pretty much the same as the according TList methods:
  90.  
  91.   procedure Clear;
  92.   procedure Delete(Index: longint);
  93.   procedure Remove(Index: longint);
  94.   procedure Pack;
  95.  
  96.   ============================================================================
  97.   New Stuff added 8/31/95 by David Sampson
  98.  
  99.   Properties:
  100.   ------------------------
  101.  
  102.   property Colors :  changed so that it is the window background color
  103.  
  104.   property ForeColor:
  105.   property BackColor:  These are the default forground and background colors
  106.                        that will be used to display the text in the window.
  107.  
  108.   property FillBack: Fills the background of the whole line with the Backgnd color
  109.  
  110.   property ScrollBars: Let's you select scrollbars
  111.  
  112.   Methods:
  113.   ------------------------
  114.  
  115.   procedure AddString(LineString: string; UpdateDisplay: boolean);
  116.  
  117.     --This adds a string using the default fore and back colors and left
  118.       alignment.
  119.  
  120.   procedure AddStringA(LineString: string; Fore, Back : TColor;
  121.                        Align : TTextAlign; Style : TFontStyles; UpdateDisplay: boolean);
  122.  
  123.     --This lets you add a string and specify the colors, alignment, and text style
  124.  
  125.   procedure AlignText(Index : LongInt; Align : TTextAlign; UpdateDisplay: boolean);
  126.  
  127.     --This lets you set the text alignment on an item.
  128.       Updatedisplay set to true refreshes the display
  129.  
  130.   procedure SetColors(Index: longint; NewFCol, NewBCol: TColor);
  131.  
  132.     --Let's you specify a fore and back color for a specific index
  133.  
  134.   procedure SetStyle (Index : LongInt; Style :TFontStyles; UpdateDisplay: boolean);
  135.  
  136.     --Let's you set the text style
  137.       Updatedisplay set to true refreshes the display
  138.  
  139.   Here's some example calls:
  140.  
  141.  BigText1.AddLine('Hello', clWhite, clNavy, True);
  142.  BigText1.AddString('There', True);
  143.  BigText1.AddStringA('Yogi', clYellow, clRed, taRight, [], True);
  144.  BigText1.AddStringA('Bear', clWhite, clGreen, taCenter, [], True);
  145.  BigText1.AddString('This was left aligned', [], False);
  146.  BigText1.AlignText (BigText1.Count -1, taCenter, true);
  147.  BigText1.SetStyle(BigText1.Count -1, [fsBold, fsItalic, fsUnderline, fsStrikeout], true);
  148.  
  149.  ============================================================================
  150.  New Stuff added by Eric Heverly
  151.  
  152.  Function Search - Added EJH 07/04/95
  153.  Search('this text', True, True);
  154.  Parameters:
  155.        SrcWord  : String - What to Look for in the array
  156.        SrchDown : Bool - True - Search down; False - Search Up
  157.        MCase    : Bool - True - Match Case Exact; False - Disregard Case
  158.  
  159.  Returns:       True - Found ; False - Not Found
  160.  
  161.       Note: This is a little screwy because it does not redisplay the
  162.             last page if text is found there when already on the last page.
  163.             Also, during displays of found data, on the last call, if the
  164.             user closes the finddialog, I could not see an automatic way
  165.             for this application to know that it was not visible, so the
  166.             final blue line stays on the screen untill the window scrolls
  167.             beyond it, from then on it is not there.  This is sometimes
  168.             useful, othertimes it is just ugly.
  169.  
  170.       Note: To find exact matches if you have the option available to the
  171.             user, put a space on both sides of SrcWord, otherwise partial
  172.             matches are used.
  173.  
  174.  Modifications - Eric Heverly - July 1995 (erichev@ix.netcom.com)
  175.  
  176.        Scroll- Added keys F1-F4 to the Scrool Keys table.
  177.        Print - Added canvas font for the display canvas to the printer
  178.                so the expected printer font was the same.  Also added some
  179.                Cursor := crHourGlass to show that the system was busy during
  180.                print cycles.
  181.        Search- Added function.
  182.        GoPosi- GoPosition function added.
  183.        LoadFr- LoadFromFile added some Cursor := crHourGlass to show the
  184.                user that the system is busy.  Also I changed the call to the
  185.                addline function to use the dumchar, this keeps the font to
  186.                the defined font in the object editor (ie. I used Courier and
  187.                this way it kept Courier as the display font, with the OEM
  188.                characters, it always used the System font).
  189.  
  190. }
  191.  
  192. interface
  193.  
  194. uses WinTypes, WinProcs, Messages, Classes, Controls, Printers,
  195.      Forms, Graphics, SysUtils, StdCtrls;
  196.  
  197. type
  198.   {$M+}
  199.  
  200.   { Supporting types & structures for text attributes}
  201.   TTextAlign = (taLeft, taCenter, taRight);
  202.  
  203.   TTextAttributes = class
  204.   public
  205.     FColor : TColor;
  206.     BColor : TColor;
  207.     Align  : TTextAlign;
  208.     Style  : TFontStyles;
  209.   end;
  210.  
  211.  
  212.   TBigList = class
  213.   private
  214.     function GetCapacity: longint;
  215.     function GetCount: longint;
  216.     function GetItems(Index: longint): pointer;
  217.     procedure SetItems(Index: longint; const Item: pointer);
  218.   protected
  219.     ListCount : integer;
  220.     TheLines  : array[0..3] of TList;
  221.   published
  222.     property Capacity: longint read GetCapacity;
  223.     property Count: longint read GetCount;
  224.   public
  225.     property Items[Index: longint]: pointer read GetItems write SetItems;
  226.     constructor Create;
  227.     destructor Destroy;
  228.     class function ClassName: string;
  229.     function Add(Item: Pointer): longint;
  230.     procedure Delete(Index: longint);
  231.     procedure Remove(Index: longint);
  232.     procedure Pack;
  233.     procedure Clear;
  234.     function First: pointer;
  235.     function Last: pointer;
  236.   end;
  237.   {$M-}
  238.  
  239.  
  240.   TBigText = class(TCustomControl)
  241.   private
  242.     FFont: TFont;
  243.     FMaxLines: word;
  244.     FPurgeLines: word;
  245.     FForeColor : TColor;
  246.     FBackColor : TColor;
  247.     FFillBack  : Boolean;
  248.     FScrollBars: TScrollStyle;    {TScrollStyle = (ssNone, ssHorizontal, ssVertical, ssBoth);}
  249.     procedure DoScroll(Which, Action, Thumb: longint);
  250.     procedure WMHScroll(var M: TWMHScroll); message wm_HScroll;
  251.     procedure WMVScroll(var M: TWMVScroll); message wm_VScroll;
  252.     procedure WMSize(var M: TWMSize); message wm_Size;
  253.     procedure WMGetDlgCode(var M: TWMGetDlgCode); message wm_GetDlgCode;
  254.     function GetCount: longint;
  255.     procedure SetFont(F: TFont);
  256.   protected
  257.     FRange: TPoint;
  258.     FOrigin: TPoint;
  259.     FClientSize: TPoint;
  260.     FCharSize: TPoint;
  261.     FOverhang: longint;
  262.     FPageSize: longint;
  263.     Lines: TBigList;
  264.     TextAttrib : TBigList;
  265.     procedure Paint; override;
  266.     procedure SetScrollbars;
  267.     procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  268.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
  269.                 X, Y: Integer); override;
  270.   public
  271.     constructor Create(AnOwner: TComponent); override;
  272.     destructor Destroy; override;
  273.     procedure CreateParams(var Params: TCreateParams); override;
  274.     procedure ChangeScrollBars(Value: TScrollStyle);
  275.     procedure ScrollTo(X, Y: longint);
  276.     procedure AddLine(LineString: string; FCol, BCol: TColor; UpdateDisplay: boolean);
  277.     {added by dfs}
  278.     procedure AddString(LineString: string; UpdateDisplay: boolean);  {use default attributes}
  279.     procedure AddStringA(LineString: string; Fore, Back : TColor; Align : TTextAlign;
  280.                    Style : TFontStyles; UpdateDisplay: boolean);
  281.     procedure AlignText(Index : LongInt; Align : TTextAlign; UpdateDisplay: boolean);
  282.     procedure SetStyle (Index : LongInt; Style :TFontStyles; UpdateDisplay: boolean);
  283.     {end of dfs changes}
  284.     procedure Delete(Index: longint);
  285.     procedure Clear;
  286.     procedure Print;
  287.     {added by EJH }
  288.     function CurPos: longint;
  289.     function GoPosition(GoPos: longint): bool;
  290.     function Search(SrcWord: string; SrchDown, MCase: bool): bool;
  291.     function DoSearch(SrcWord: string; MCase: bool; I: longint): longint;
  292.     procedure LoadFromFileANSI(FileName: TFileName);
  293.     function Printspec(const szWLine: string): bool;
  294.     {end of EJH changes}
  295.     procedure LoadFromFile(FileName: TFileName);
  296.     function  GetLine(Index: longint): string;
  297.     procedure ChangeColor(Index: longint; OldFCol, OldBCol, NewFCol, NewBCol: TColor);
  298.     {added by dfs}
  299.     procedure SetColors(Index: longint; NewFCol, NewBCol: TColor);
  300.     {end of dfs changes}
  301.   published
  302.     procedure RecalcRange;
  303.     procedure FontChanged(Sender: TObject);
  304.     property Font: TFont read FFont write SetFont;
  305.     property Align;
  306.     property ParentColor;
  307.     property MaxLines: word read FMaxLines write FMaxLines default 0;
  308.     property PurgeLines: word read FPurgeLines write FPurgeLines default 200;
  309.     property Color;
  310.     property Count: longint read GetCount;
  311.  
  312.     {added by dfs}
  313.     {these are the defaults if a fore and back color isn't specified when a line
  314.      of text is added to the list}
  315.     property ForeColor : TColor read FForeColor write FForeColor default clBlack;
  316.     property BackColor : TColor read FBackColor write FBackColor default clWhite;
  317.     property FillBack : Boolean read FFillBack write FFillBack default False;
  318.     property ScrollBars: TScrollStyle read FScrollBars write ChangeScrollBars default ssNone;
  319.     {end of dfs changes}
  320.   end;
  321.  
  322. procedure Register;
  323.  
  324. implementation
  325.  
  326. { Scroll key definition record }
  327.  
  328. type
  329.   TScrollKey = record
  330.     sKey: Byte;
  331.     Ctrl: Boolean;
  332.     SBar: Byte;
  333.     Action: Byte;
  334.   end;
  335.  
  336. { Scroll keys table }
  337.  
  338. const
  339.   ScrollKeyCount = 16; {modified by EJH from 12}
  340.   ScrollKeys: array[1..ScrollKeyCount] of TScrollKey = (
  341.     (sKey: vk_Left;  Ctrl: False; SBar: sb_Horz; Action: sb_LineUp),
  342.     (sKey: vk_Right; Ctrl: False; SBar: sb_Horz; Action: sb_LineDown),
  343.     (sKey: vk_Left;  Ctrl: True;  SBar: sb_Horz; Action: sb_PageUp),
  344.     (sKey: vk_Right; Ctrl: True;  SBar: sb_Horz; Action: sb_PageDown),
  345.     (sKey: vk_Home;  Ctrl: False; SBar: sb_Horz; Action: sb_Top),
  346.     (sKey: vk_End;   Ctrl: False; SBar: sb_Horz; Action: sb_Bottom),
  347.     (sKey: vk_Up;    Ctrl: False; SBar: sb_Vert; Action: sb_LineUp),
  348.     (sKey: vk_Down;  Ctrl: False; SBar: sb_Vert; Action: sb_LineDown),
  349.     (sKey: vk_Prior; Ctrl: False; SBar: sb_Vert; Action: sb_PageUp),
  350.     (sKey: vk_Next;  Ctrl: False; SBar: sb_Vert; Action: sb_PageDown),
  351.     (sKey: vk_F1;    Ctrl: False;  SBar: sb_Vert; Action: sb_PageDown),{EJH}
  352.     (sKey: vk_F2;    Ctrl: False;  SBar: sb_Vert; Action: sb_PageUp),  {EJH}
  353.     (sKey: vk_F3;    Ctrl: False;  SBar: sb_Vert; Action: sb_Top),     {EJH}
  354.     (sKey: vk_F4;    Ctrl: False;  SBar: sb_Vert; Action: sb_Bottom),  {EJH}
  355.     (sKey: vk_Home;  Ctrl: True;  SBar: sb_Vert; Action: sb_Top),
  356.     (sKey: vk_End;   Ctrl: True;  SBar: sb_Vert; Action: sb_Bottom));
  357.  
  358. var
  359.    szANSI : String;
  360.  
  361. function Min(X, Y: longint): longint;
  362. begin
  363.   if X < Y then Min := X else Min := Y;
  364. end;
  365.  
  366. function Max(X, Y: longint): longint;
  367. begin
  368.   if X > Y then Max := X else Max := Y;
  369. end;
  370.  
  371. {<<<<<<<<<<<<<<<<<<<< TBigList >>>>>>>>>>>>>>>>>>>>>>>}
  372.  
  373. constructor TBigList.Create;
  374. begin
  375.   ListCount := 0;
  376.   TheLines[ListCount] := TList.Create;
  377. end;
  378.  
  379. destructor TBigList.Destroy;
  380. var
  381.   i: longint;
  382. begin
  383.   for i := 0 to ListCount do
  384.     TheLines[i].Free;
  385. end;
  386.  
  387. class function TBigList.ClassName: string;
  388. begin
  389.   ClassName := 'TBigList';
  390. end;
  391.  
  392. function TBigList.GetCapacity: longint;
  393. var
  394.   i: longint;
  395.   j: longint;
  396. begin
  397.   j := 0;
  398.   for i := 0 to ListCount do
  399.     inc(j, TheLines[i].Capacity);
  400.   GetCapacity := j;
  401. end;
  402.  
  403. function TBigList.GetCount: longint;
  404. var
  405.   i: longint;
  406.   j: longint;
  407. begin
  408.   j := 0;
  409.   for i := 0 to ListCount do
  410.     inc(j, TheLines[i].Count);
  411.   GetCount := j;
  412. end;
  413.  
  414. function TBigList.Add(Item: Pointer): longint;
  415. var
  416.   i: longint;
  417.   j: longint;
  418. begin
  419.   try
  420.     TheLines[ListCount].Add(Item);
  421.     j := 0;
  422.     for i := 0 to ListCount do
  423.       inc(j, TheLines[ListCount].Count);
  424.     Add := j - 1;
  425.   except
  426.     try
  427.       inc(ListCount);
  428.       TheLines[ListCount] := TList.Create;
  429.       TheLines[ListCount].Add(Item);
  430.       j := 0;
  431.       for i := 0 to ListCount do
  432.         inc(j, TheLines[i].Count);
  433.       Add := j - 1;
  434.     except
  435.       j := 0;
  436.       for i := 0 to (ListCount - 1) do
  437.         inc(j, TheLines[i].Count);
  438.       raise EOutOfResources.Create('Out of Memory at line ' + IntToStr(j));
  439.       Add := -1;
  440.     end;
  441.   end;
  442. end;
  443.  
  444. procedure TBigList.Delete(Index: longint);
  445. var
  446.   i: longint;
  447. begin
  448.   if Index > Count then
  449.     raise ERangeError.Create('TBigList Index out of bounds')
  450.   else
  451.   begin
  452.     i := 0;
  453.     while Index > (TheLines[i].Count - 1) do
  454.     begin
  455.       dec(Index, TheLines[i].Count);
  456.       inc(i);
  457.     end;
  458.     TheLines[i].Delete(Index);
  459.   end;
  460. end;
  461.  
  462. procedure TBigList.Remove(Index: longint);
  463. begin
  464.   Delete(Index);
  465. end;
  466.  
  467. procedure TBigList.Pack;
  468. var
  469.   i       : longint;
  470.   j       : longint;
  471.   ListFull: boolean;
  472. begin
  473.   TheLines[0].Pack;
  474.   i := 0;
  475.   while (i < ListCount) do
  476.   begin
  477.     try
  478.       TheLines[i].Add(TheLines[i + 1].Items[0]);
  479.       TheLines[i + 1].Delete(0);
  480.     except
  481.       inc(i);
  482.     end;
  483.   end;
  484.   TheLines[i].Pack;
  485.   for i := ListCount downto 1 do
  486.   begin
  487.     if TheLines[i].Count = 0 then
  488.       TheLines[i].Free;
  489.   end;
  490. end;
  491.  
  492. procedure TBigList.Clear;
  493. var
  494.   i: longint;
  495. begin
  496.   for i := 1 to ListCount do
  497.     TheLines[ListCount].Free;
  498.   ListCount := 0;
  499.   TheLines[ListCount].Clear;
  500. end;
  501.  
  502. function TBigList.First: pointer;
  503. begin
  504.   First := TheLines[0].Items[0];
  505. end;
  506.  
  507. function TBigList.Last: pointer;
  508. begin
  509.   Last := TheLines[ListCount].Items[TheLines[ListCount].Count - 1];
  510. end;
  511.  
  512. function TBigList.GetItems(Index: longint): pointer;
  513. var
  514.   i: longint;
  515. begin
  516.   if Index > Count then
  517.     raise ERangeError.Create('TBigList Index out of bounds')
  518.   else
  519.   begin
  520.     i := 0;
  521.     while Index > (TheLines[i].Count - 1) do
  522.     begin
  523.       dec(Index, TheLines[i].Count);
  524.       inc(i);
  525.     end;
  526.     GetItems := TheLines[i].Items[Index];
  527.   end;
  528. end;
  529.  
  530. procedure TBigList.SetItems(Index: longint; const Item: pointer);
  531. var
  532.   i: longint;
  533. begin
  534.   if Index > Count then
  535.     raise ERangeError.Create('TBigList Index out of bounds')
  536.   else
  537.   begin
  538.     i := 0;
  539.     while Index > (TheLines[i].Count - 1) do
  540.     begin
  541.       dec(Index, TheLines[i].Count);
  542.       inc(i);
  543.     end;
  544.     TheLines[i].Items[Index] := Item;
  545.   end;
  546. end;
  547.  
  548.  
  549.  
  550. {<<<<<<<<<<<<<<<<<<<< TBigText >>>>>>>>>>>>>>>>>>>>>>>}
  551.  
  552. constructor TBigText.Create(AnOwner: TComponent);
  553. begin
  554.   inherited Create(AnOwner);
  555.   Width := 320;
  556.   Height := 200;
  557.   ParentColor := False;
  558.   FFont := TFont.Create;
  559.   FFont.Name := 'Courier';
  560.   FFont.OnChange := FontChanged;
  561.   FForeColor := clBlack;    {dfs}
  562.   FBackColor := clWhite;    {dfs}
  563.   FMaxLines := 0;
  564.   FPurgeLines := 200;
  565.   FOrigin.X := 0;
  566.   FOrigin.Y := 0;
  567.   FontChanged(nil);
  568.   FScrollBars := ssVertical;   {dfs}
  569.   FFillBack := False;          {dfs}
  570.   Enabled := True;
  571.   Lines := TBigList.Create;
  572.   TextAttrib := TBigList.Create;   {dfs}
  573. end;
  574.  
  575. destructor TBigText.Destroy;
  576. begin
  577.   Lines.Free;
  578.   TextAttrib.Free;    {dfs}
  579.   FFont.Free;
  580.   inherited Destroy;
  581. end;
  582.  
  583. {added by dfs}
  584. procedure TBigText.CreateParams(var Params: TCreateParams);
  585. const
  586.   ScrollBar: array[TScrollStyle] of LongInt = (0, WS_HSCROLL, WS_VSCROLL,
  587.     WS_HSCROLL or WS_VSCROLL);
  588. begin
  589.   inherited CreateParams(Params);
  590.   Params.Style := Params.Style or ScrollBar[FScrollBars];
  591. end;
  592.  
  593. procedure TBigText.ChangeScrollBars(Value: TScrollStyle);
  594. begin
  595.   if FScrollBars <> Value then
  596.   begin
  597.     FScrollBars := Value;
  598.     RecreateWnd;
  599.   end;
  600. end;
  601. {end of dfs changes}
  602.  
  603. procedure TBigText.FontChanged(Sender: TObject);
  604. var
  605.   DC: HDC;
  606.   Save: THandle;
  607.   Metrics: TTextMetric;
  608.   Temp: String;
  609. begin
  610.   DC := GetDC(0);
  611.   Save := SelectObject(DC, Font.Handle);
  612.   GetTextMetrics(DC, Metrics);
  613.   SelectObject(DC, Save);
  614.   ReleaseDC(0, DC);
  615.   with Metrics do
  616.   begin
  617.     FCharSize.X := tmAveCharWidth;
  618.     FCharSize.Y := tmHeight + tmExternalLeading;
  619.     FOverhang   := Max(tmOverhang, tmMaxCharWidth - tmAveCharWidth);
  620.     RecalcRange;
  621.     Invalidate;
  622.   end;
  623. end;
  624.  
  625. procedure TBigText.RecalcRange;
  626. begin
  627.   if HandleAllocated then
  628.   begin
  629.     FClientSize.X := ClientWidth div FCharSize.X;
  630.     FClientSize.Y := ClientHeight div FCharSize.Y;
  631.     FPageSize := FClientSize.Y;
  632.     FRange.X := Max(0, 255 - FClientSize.X);
  633.     FRange.Y := Max(0, Lines.Count - FClientSize.Y);
  634.     ScrollTo(Min(FOrigin.X, FRange.X), Min(FOrigin.Y, FRange.Y));
  635.     SetScrollBars;
  636.   end;
  637. end;
  638.  
  639. procedure TBigText.SetScrollBars;
  640. begin
  641.   if HandleAllocated then
  642.   begin
  643.     if (FScrollBars = ssHorizontal) or (FScrollBars = ssBoth) then    {dfs}
  644.     begin
  645.       SetScrollRange(Handle, sb_Horz, 0, Max(1, FRange.X), False);
  646.       SetScrollPos(Handle, sb_Horz, FOrigin.X, True);
  647.     end;
  648.     if (FScrollBars = ssVertical) or (FScrollBars = ssBoth) then   {dfs}
  649.     begin
  650.       SetScrollRange(Handle, sb_Vert, 0, Max(1, FRange.Y), False);
  651.       SetScrollPos(Handle, sb_Vert, FOrigin.Y, True);
  652.     end;
  653.   end;
  654. end;
  655.  
  656. procedure TBigText.Paint;      {lot's of changes here -- dfs}
  657. var
  658.   i: longint;
  659.   R: TRect;
  660.   flag : Word;
  661. begin
  662.   SetViewportOrg(Canvas.Handle, -FOrigin.X * FCharSize.X, 0);
  663.   i := FOrigin.Y;
  664.   while (i < Lines.Count) and (i < ((FOrigin.Y + FPageSize) + 1)) do
  665.   begin
  666.     Canvas.Font := FFont;
  667.     Canvas.Font.Color := TTextAttributes(TextAttrib.Items[i]).FColor;
  668.     Canvas.Brush.Color := TTextAttributes(TextAttrib.Items[i]).BColor;
  669.     Canvas.Font.Style := TTextAttributes(TextAttrib.Items[i]).Style;
  670.     R.Left := 0;
  671.     R.Right := ClientWidth + FOrigin.X + FRange.X * FCharSize.X;  { ges }
  672.     R.Top := FCharSize.Y * (i - FOrigin.Y);
  673.     R.Bottom := R.Top + FCharSize.Y;
  674.     flag := DT_TOP or DT_SINGLELINE or DT_EXTERNALLEADING or DT_LEFT;
  675.     case TTextAttributes(TextAttrib.Items[i]).Align of
  676.       taLeft : flag := flag or DT_LEFT;
  677.       taCenter : flag := flag or DT_CENTER;
  678.       taRight : flag := flag or DT_RIGHT;
  679.     end;
  680.     if FFillBack then Canvas.FillRect(R);
  681.     DrawText(Canvas.Handle, Lines.Items[i], StrLen(Lines.Items[i]), R, flag);
  682.     inc(i);
  683.   end;
  684. end;
  685.  
  686. procedure TBigText.DoScroll(Which, Action, Thumb: longint);
  687. var
  688.   X, Y: longint;
  689. function GetNewPos(Pos, Page, Range: longint): longint;
  690. begin
  691.   case Action of
  692.     sb_LineUp: GetNewPos := Pos - 1;
  693.     sb_LineDown: GetNewPos := Pos + 1;
  694.     sb_PageUp: GetNewPos := Pos - Page;
  695.     sb_PageDown: GetNewPos := Pos + Page;
  696.     sb_Top: GetNewPos := 0;
  697.     sb_Bottom: GetNewPos := Range;
  698.     sb_ThumbPosition,
  699.     sb_ThumbTrack    : GetNewPos := Thumb;
  700.   else
  701.     GetNewPos := Pos;
  702.   end;
  703. end;
  704. begin
  705.   X := FOrigin.X;
  706.   Y := FOrigin.Y;
  707.   case Which of
  708.     sb_Horz: X := GetNewPos(X, FClientSize.X div 2, FRange.X);
  709.     sb_Vert: Y := GetNewPos(Y, FClientSize.Y, FRange.Y);
  710.   end;
  711.   ScrollTo(X, Y);
  712. end;
  713.  
  714. procedure TBigText.WMHScroll(var M: TWMHScroll);
  715. begin
  716.   DoScroll(sb_Horz, M.ScrollCode, M.Pos);
  717. end;
  718.  
  719. procedure TBigText.WMVScroll(var M: TWMVScroll);
  720. begin
  721.   DoScroll(sb_Vert, M.ScrollCode, M.Pos);
  722. end;
  723.  
  724. procedure TBigText.WMSize(var M: TWMSize);
  725. begin
  726.   inherited;
  727.   RecalcRange;
  728. end;
  729.  
  730. procedure TBigText.ScrollTo(X, Y: longint);
  731. var
  732.   R: TRect;
  733.   OldOrigin: TPoint;
  734. begin
  735.   X := Max(0, Min(X, FRange.X));  { check boundaries }
  736.   Y := Max(0, Min(Y, FRange.Y));
  737.   if (X <> FOrigin.X) or (Y <> FOrigin.Y) then
  738.   begin
  739.     OldOrigin := FOrigin;
  740.     FOrigin.X := X;
  741.     FOrigin.Y := Y;
  742.     if HandleAllocated then
  743.     begin
  744.       R := Parent.ClientRect; {EJH added Parent }
  745.       ScrollWindowEx(Handle, (OldOrigin.X - X) * FCharSize.X, (OldOrigin.Y - Y) * FCharSize.Y,
  746.                      nil, @R, 0, @R, 0);
  747.       if Y <> OldOrigin.Y then
  748.         SetScrollPos(Handle, sb_Vert, Y, True);
  749.       if X <> OldOrigin.X then
  750.         SetScrollPos(Handle, sb_Horz, X, True);
  751.       InvalidateRect(Handle, @R, true);
  752.       Update;
  753.     end;
  754.   end;
  755. end;
  756.  
  757. procedure TBigText.AddLine(LineString: string; FCol, BCol: TColor; UpdateDisplay: boolean);
  758. var
  759.   DumChar: array[0..255] of char;
  760.   WhereY : longint;
  761.   i      : longint;
  762.   attrib : TTextAttributes;
  763.   R      : TRect;
  764.   flag   : Word;
  765. begin
  766.   if FMaxLines <> 0 then
  767.   begin
  768.     if (Lines.Count >= FMaxLines) or (Lines.Count > 32000) then
  769.     begin
  770.       if PurgeLines <> 0 then
  771.       begin
  772.         for i := 1 to PurgeLines do
  773.         begin
  774.           Lines.Delete(0);
  775.           TextAttrib.Delete(0);
  776.         end;
  777.         Lines.Pack;
  778.         TextAttrib.Pack;
  779.       end
  780.       else
  781.         raise ERangeError.Create('Maximum line count at line ' + IntToStr(Lines.Count))
  782.     end;
  783.   end;
  784.  
  785.   try
  786.     Lines.Add(StrNew(StrPCopy(DumChar, LineString)));
  787.     attrib := TTextAttributes.Create;        {dfs stuff}
  788.     attrib.FColor := FCol;
  789.     attrib.BColor := BCol;
  790.     attrib.Align := taLeft;
  791.     attrib.Style := [];
  792.     TextAttrib.Add(attrib);
  793.   except
  794.     if PurgeLines <> 0 then
  795.     begin
  796.       for i := 1 to PurgeLines do
  797.       begin
  798.         Lines.Delete(0);
  799.         TextAttrib.Delete(0);    {dfs}
  800.       end;
  801.       Lines.Pack;
  802.       TextAttrib.Delete(0);
  803.       try
  804.         Lines.Add(StrNew(StrPCopy(DumChar, LineString)));
  805.         attrib := TTextAttributes.Create;   {dfs stuff}
  806.         attrib.FColor := FCol;
  807.         attrib.BColor := BCol;
  808.         attrib.Align := taLeft;
  809.         attrib.Style := [];
  810.         TextAttrib.Add(attrib);
  811.       except
  812.         raise EOutOfResources.Create('Out of Memory at line ' + IntToStr(Lines.Count))
  813.       end;
  814.     end
  815.     else
  816.       raise EOutOfResources.Create('Out of Memory at line ' + IntToStr(Lines.Count))
  817.   end;
  818.  
  819.   if UpdateDisplay then
  820.   begin
  821.     SetViewportOrg(Canvas.Handle, 0, 0);
  822.     RecalcRange;
  823.     WhereY := Min(Lines.Count - 1, FPageSize);
  824.     Canvas.Font := FFont;                   {more dfs changes below}
  825.     Canvas.Font.Color := TTextAttributes(TextAttrib.Items[Lines.Count -1]).FColor;
  826.     Canvas.Brush.Color := TTextAttributes(TextAttrib.Items[Lines.Count -1]).BColor;
  827.     Canvas.Font.Style := TTextAttributes(TextAttrib.Items[Lines.Count -1]).Style;
  828.     R.Left := 0;
  829.     R.Right := ClientWidth + FOrigin.X + FRange.X * FCharSize.X;  { ges }
  830.     R.Top := FCharSize.Y * WhereY;
  831.     R.Bottom := R.Top + FCharSize.Y;
  832.     flag := DT_TOP or DT_SINGLELINE or DT_EXTERNALLEADING or DT_LEFT;
  833.     case TTextAttributes(TextAttrib.Items[Lines.Count -1]).Align of
  834.       taLeft : flag := flag or DT_LEFT;
  835.       taCenter : flag := flag or DT_CENTER;
  836.       taRight : flag := flag or DT_RIGHT;
  837.     end;
  838.     if FFillBack then Canvas.FillRect(R);
  839.     DrawText(Canvas.Handle, Lines.Items[Lines.Count - 1],
  840.                             StrLen(Lines.Items[Lines.Count -1]), R, flag);
  841.     ScrollTo(0, FRange.Y);
  842.   end;
  843. end;
  844.  
  845. {dfs additions}
  846.  
  847. procedure TBigText.AddString(LineString: string; UpdateDisplay: boolean);
  848. begin
  849.    AddLine(LineString, FForeColor, FBackColor, UpdateDisplay);
  850. end;
  851.  
  852. procedure TBigText.AddStringA(LineString: string; Fore, Back : TColor;
  853.                      Align : TTextAlign; Style : TFontStyles; UpdateDisplay: boolean);
  854. begin
  855.    AddLine(LineString, Fore, Back, True);
  856.    TTextAttributes(TextAttrib.Items[Count -1]).Align := Align;
  857.    TTextAttributes(TextAttrib.Items[Count -1]).Style := Style;
  858.    SetStyle(Count-1, Style, False);
  859.    AlignText(Count-1, Align, True);
  860. end;
  861.  
  862. procedure TBigText.AlignText(Index : LongInt; Align : TTextAlign; UpdateDisplay: boolean);
  863. begin
  864.    TTextAttributes(TextAttrib.Items[Index]).Align := Align;
  865.    if UpdateDisplay then Refresh;
  866. end;
  867.  
  868. procedure TBigText.SetStyle (Index : LongInt; Style :TFontStyles; UpdateDisplay: boolean);
  869. begin
  870.   TTextAttributes(TextAttrib.Items[Index]).Style := Style;
  871.   if UpdateDisplay then Refresh;
  872. end;
  873.  
  874. {end of dfs additions}
  875.  
  876. procedure TBigText.Delete(Index: longint);
  877. begin
  878.   Lines.Delete(Index);
  879.   TextAttrib.Delete(Index);
  880. end;
  881.  
  882. procedure TBigText.Clear;
  883. begin
  884.   Lines.Clear;
  885.   TextAttrib.Clear;
  886.   RecalcRange;
  887.   Invalidate;
  888. end;
  889.  
  890. procedure TBigText.Print;
  891. var
  892.   i: longint;
  893.   f: Textfile;
  894. begin
  895.   cursor := crHourGlass;           { Added EJH 7/5/95 }
  896.   AssignPrn(f);
  897.   Rewrite(f);
  898.   cursor := crHourGlass;           { Added EJH 7/5/95 }
  899.   Printer.Canvas.Font := FFont;    { Added EJH 7/5/95 }
  900.   for i := 0 to (Lines.Count - 1) do
  901.     WriteLn(f, StrPas(Lines.Items[i]));
  902.   System.Close(f);
  903.   cursor := crDefault;             { Added EJH 7/5/95 }
  904. end;
  905.  
  906. {
  907. Added - EJH
  908. }
  909. function TBigText.CurPos : longint;
  910. begin
  911.      Result := Forigin.Y;
  912. end;
  913. {
  914. Function GoPosition - Added EJH 07/11/95
  915. Parameters:
  916.       GoPos : Integer - Position to go to 1-N.
  917.  
  918.       Returns False if GoPos is > maximum lines.  True otherwise.
  919. }
  920. function TBigText.GoPosition(GoPos: longint): bool;
  921. var
  922.   Y :  longint;
  923.   X :  longint;
  924.   LC:  longint;
  925. begin
  926.   Y      := FOrigin.Y;
  927.   X      := FOrigin.X;
  928.   LC     := Lines.Count;
  929.   result := False;
  930.   if GoPos > 0 then
  931.     begin
  932.       if LC > GoPos then
  933.         begin
  934.          Y := GoPos;
  935.          ScrollTo(X, Y);
  936.          result := true;
  937.         end;
  938.     end;
  939.   end;
  940.  
  941. {
  942. Function Search - Added EJH 07/04/95
  943. Parameters:
  944.       SrcWord  : String - What to Look for in the array
  945.       SrchDown : Bool - True - Search down; False - Search Up
  946.       MCase    : Bool - True - Match Case Exact; False - Disregard Case
  947.  
  948.       Note: This is a little screwy because it does not redisplay the
  949.             last page if text is found there, the re-drawn then found
  950.             again on that line.
  951. }
  952. function TBigText.Search(SrcWord: string; SrchDown : Bool; MCase : Bool): bool;
  953. var
  954.   Y:     longint;
  955.   X:     longint;
  956.   fnd:   longint;
  957.   index: longint;
  958.   I:     longint;
  959.   LC:    longint;
  960.   SavCol:TColor;
  961. begin
  962.   Y   := FOrigin.Y;
  963.   X   := FOrigin.X;
  964.   fnd := 0;
  965.   I   := Y;
  966.   LC  := Lines.Count;
  967.   if SrchDown then
  968.      begin
  969.        while I < (LC - 1) do
  970.              begin
  971.                  I := I + 1;
  972.                  fnd := DoSearch(SrcWord, MCase, I);
  973.                  if fnd > 0 then
  974.                   begin
  975.                     index := I;
  976.                     I := Lines.Count;
  977.                   end;
  978.               end;
  979.     end
  980.   else
  981.     begin
  982.          while I > 0 do
  983.              begin
  984.                  I   := I - 1;
  985.                  fnd := DoSearch(SrcWord, MCase, I);
  986.                  if fnd > 0 then
  987.                   begin
  988.                     index := I;
  989.                     I := 0;
  990.                   end;
  991.               end;
  992.     end;
  993.   if fnd > 0 then
  994.      begin
  995.         Y := index;
  996.         SavCol := TTextAttributes(TextAttrib.Items[Index]).BColor;
  997.         ChangeColor(Y,
  998.            (TTextAttributes(TextAttrib.Items[Index]).FColor),
  999.            SavCol,
  1000.            (TTextAttributes(TextAttrib.Items[Index]).FColor),
  1001.            $00FF0000);
  1002.         invalidate;
  1003.         ScrollTo(X, Y);
  1004.         ChangeColor(Y,
  1005.            (TTextAttributes(TextAttrib.Items[Index]).FColor),
  1006.            $00FF0000,
  1007.            (TTextAttributes(TextAttrib.Items[Index]).FColor),
  1008.            SavCol);
  1009.         result := true;
  1010.      end
  1011.   else
  1012.      begin
  1013.         result := false;
  1014.      end;
  1015. end;
  1016.  
  1017. function TBigText.DoSearch(SrcWord:String; MCase:Bool; I:longint ): longint;
  1018. begin
  1019.    if MCase then
  1020.       result := pos(SrcWord, StrPas(Lines.Items[I]))
  1021.    else
  1022.       result := pos(UpperCase(SrcWord),
  1023.                     UpperCase(StrPas(Lines.Items[I])));
  1024. end;
  1025.  
  1026. procedure TBigText.LoadFromFile(FileName: TFileName);
  1027. var
  1028.   f: TextFile;
  1029.   i: integer;
  1030.   ReadLine: string;
  1031.   DumChar: array[0..255] of char;
  1032.   OEMDumChar: array[0..255] of char;
  1033. begin
  1034.   Clear;
  1035.   Cursor := crHourGlass;     { EJH 07/04/95 }
  1036.   AssignFile(f, FileName);
  1037.   Reset(f);
  1038.   while not eof(f) do
  1039.   begin
  1040.     ReadLn(f, ReadLine);
  1041.     while pos(#$9, ReadLine) > 0 do
  1042.     begin
  1043.       i := pos(#$9, ReadLine);
  1044.       System.delete(ReadLine, i, 1);
  1045.       while (i mod 8) <> 0 do
  1046.       begin
  1047.         insert(' ', ReadLine, i);
  1048.         inc(i);
  1049.       end;
  1050.     end;
  1051.     StrPCopy(DumChar, ReadLine);
  1052.     {OEMToAnsi(DumChar, OEMDumChar);
  1053.     AddLine(StrPas(OEMDumChar), clWindowText, clWindow, false);}
  1054.     AddLine(StrPas(DumChar), clWindowText, clWindow, false); {EJH}
  1055.   end;
  1056.   CloseFile(f);
  1057.   Cursor := crDefault;  {EJH}
  1058.   RecalcRange;
  1059.   Invalidate;
  1060. end;
  1061.  
  1062. procedure TBigText.LoadFromFileANSI(FileName: TFileName);
  1063. var
  1064.   f: TextFile;
  1065.   i: LongInt;
  1066.   ReadLine: string;
  1067.   DumChar: array[0..255] of char;
  1068.   OEMDumChar: array[0..255] of char;
  1069.   ansil : string;
  1070. begin
  1071.   Clear;
  1072.   Cursor := crHourGlass;     { EJH 07/04/95 }
  1073.   AssignFile(f, FileName);
  1074.   Reset(f);
  1075.   while not eof(f) do
  1076.   begin
  1077.     ReadLn(f, ReadLine);
  1078.     ansil := Copy (ReadLine, 2, Length(Readline) - 1);
  1079.  
  1080.     if Readline[1] = '@' then
  1081.        begin
  1082.           Printspec(ansil);
  1083.           ReadLine := Copy(szANSI, 1, Length(szANSI) - 1);
  1084.        end
  1085.     else
  1086.        begin
  1087.           ReadLine := Copy(ansil, 1, Length(ansil));
  1088.        end;
  1089.  
  1090.     while pos(#$9, ReadLine) > 0 do
  1091.     begin
  1092.       Cursor := crHourGlass;
  1093.       i := pos(#$9, ReadLine);
  1094.       System.delete(ReadLine, i, 1);
  1095.       while (i mod 8) <> 0 do
  1096.       begin
  1097.         insert(' ', ReadLine, i);
  1098.         inc(i);
  1099.       end;
  1100.     end;
  1101.     StrPCopy(DumChar, ReadLine);
  1102.     OEMToAnsi(DumChar, OEMDumChar);
  1103.     AddLine(StrPas(OEMDumChar), clWindowText, clWindow, false);
  1104.   end;
  1105.   CloseFile(f);
  1106.   Cursor := crDefault;  {EJH}
  1107.   RecalcRange;
  1108.   Invalidate;
  1109. end;
  1110.  
  1111. {
  1112. Function Clears up the @@ line markers
  1113. }
  1114. function  TBigText.Printspec(const szWLine: String): Bool;
  1115. var
  1116. szFont   :  String;
  1117. cCh      :  Char;
  1118. iPos     :  LongInt;
  1119. iTrail   :  LongInt;
  1120. iLength  :  LongInt;
  1121. bDouble  :  Bool;
  1122. szLine   :  String;
  1123. begin
  1124.      iPos   := 0;
  1125.      szANSI := '';
  1126.      szLine := '';
  1127.      bDouble:= False;
  1128.      iLength := Length(szWLine);
  1129.      while iPos < iLength - 1 do
  1130.      begin
  1131.           iPos := iPos + 1;
  1132.           if iPos < 255 then
  1133.             begin
  1134.               if szWLine[iPos] = '@' then
  1135.                begin
  1136.                 iTrail := iPos + 1;           { Use next byte for check }
  1137.                 if szWLine[iTrail] = '@' then { Found Signal }
  1138.                     begin
  1139.                         iPos := iPos + 2;     { Reset pointer }
  1140.                         case szWLine[iPos] of
  1141.                         'N', '1' : begin { N0, N2, N7, 10, 12, 17 cpi}
  1142.                                    iPos := iPos + 2;
  1143.                                    bDouble := False;
  1144.                                    end;
  1145.                              'D' : begin { D0, D2, D7 - Double Wide }
  1146.                                    bDouble := True;
  1147.                                    iPos := iPos + 2;
  1148.                                    end;
  1149.                         '6', '8' : begin { @@6L  &  @@8L }
  1150.                                    bDouble := False;
  1151.                                    iPos := iPos + 2;
  1152.                                    end;
  1153.                         else               { Do nothing...}
  1154.                         end;
  1155.                 end;
  1156.             end;
  1157.             if bDouble then
  1158.                begin
  1159.                   AppendStr(szLine, ' ');
  1160.                   AppendStr(szLine, szWLine[iPos]);
  1161.                end
  1162.             else
  1163.                 AppendStr(szLine, szWline[iPos]);
  1164.        end;    { End of while statement }
  1165.      end;      { End of if ipos < 255 }
  1166.      AppendStr(szANSI, szLine);
  1167. end;
  1168.  
  1169. function TBigText.GetLine(Index: longint): string;
  1170. begin
  1171.   if Index < Lines.Count then
  1172.     GetLine := StrPas(Lines.Items[Index])
  1173.   else
  1174.     GetLine := '';
  1175. end;
  1176.  
  1177. procedure TBigText.SetFont(F: TFont);
  1178. begin
  1179.   FFont.Assign(F);
  1180. end;
  1181.  
  1182. procedure TBigText.KeyDown(var Key: Word; Shift: TShiftState);
  1183. var
  1184.   I: Integer;
  1185. begin
  1186.   inherited KeyDown(Key, Shift);
  1187.   if Key <> 0 then
  1188.   begin
  1189.     for I := 1 to ScrollKeyCount do
  1190.       with ScrollKeys[I] do
  1191.         if (sKey = Key) and (Ctrl = (Shift = [ssCtrl])) then
  1192.         begin
  1193.       DoScroll(SBar, Action, 0);
  1194.       Exit;
  1195.         end;
  1196.   end;
  1197. end;
  1198.  
  1199. procedure TBigText.MouseDown(Button: TMouseButton;
  1200.   Shift: TShiftState; X, Y: Integer);
  1201. begin
  1202.   SetFocus;
  1203.   inherited MouseDown(Button, Shift, X, Y);
  1204. end;
  1205.  
  1206. procedure TBigText.WMGetDlgCode(var M: TWMGetDlgCode);
  1207. begin
  1208.   M.Result := dlgc_WantArrows or dlgc_WantChars;
  1209. end;
  1210.  
  1211. procedure TBigText.ChangeColor(Index: longint; OldFCol, OldBCol, NewFCol, NewBCol: TColor);
  1212. begin
  1213.   if (TTextAttributes(TextAttrib.Items[Index]).FColor = OldFCol) and     {dfs}
  1214.      (TTextAttributes(TextAttrib.Items[Index]).BColor = OldBCol) then
  1215.   begin
  1216.     TTextAttributes(TextAttrib.Items[Index]).FColor := NewFCol;
  1217.     TTextAttributes(TextAttrib.Items[Index]).BColor := NewBCol;
  1218.   end;
  1219. end;
  1220.  
  1221. procedure TBigText.SetColors(Index: longint; NewFCol, NewBCol: TColor);
  1222. begin
  1223.    TTextAttributes(TextAttrib.Items[Index]).FColor := NewFCol;   {dfs}
  1224.    TTextAttributes(TextAttrib.Items[Index]).BColor := NewBCol;
  1225. end;
  1226.  
  1227. function TBigText.GetCount: longint;
  1228. begin
  1229.   if Lines.Count = TextAttrib.Count then
  1230.     GetCount := Lines.Count
  1231.   else
  1232.     GetCount := -1;
  1233. end;
  1234.  
  1235. procedure Register;
  1236. begin
  1237.   RegisterComponents('FreeWare', [TBigText]);
  1238. end;
  1239.  
  1240. end.
  1241.