Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Scrolling Canvas

342 views
Skip to first unread message

Geoff

unread,
Apr 22, 2003, 5:46:02 AM4/22/03
to
I need a control that allows me to scroll text written on a canvas.
The only control I have found that allows this is a TForm, but that has
problems in that text can only be written to a visible section of the
screen.
Items derived from TGraphicControl have a canvas but cannot be scrolled.
TWinControls can be scrolled but do not have a canvas, or at least not a
visible one.

Q1) Do TWinContol components have a hidden canvass and if so how can
they be made visible?

I can create a TWinControl with a canvas, but when I try to write to
that canvas I get an error message "Canvas does not allow drawing" - (I
thought that was the purpose of a canvas!), and I can't get any further
at the moment.

Q2) How do I write to a canvas I have attached to a TWinControl

Q3) How do I get the canvas to paint, in particular at the correct
location.

Thanks in advance fore any assistance.
Geoff

Andrew Jameson

unread,
Apr 22, 2003, 7:48:26 AM4/22/03
to
Hi Geoff,
I'm maybe missing the point but it sounds too obvious to simply suggest that
you use a TMemo or TRichEdit that displays text and can scroll too ... so I
presume that you want to be able to write directly to a canvas in order to
maybe display other graphics / effects ... so why not put a TImage in a
TScrollBox ?

Andrew

Geoff <Ge...@nospam.com> wrote in message
news:3EA50F5A...@nospam.com...

Geoff

unread,
Apr 22, 2003, 8:58:12 AM4/22/03
to
Thanks for the comments Andrew. My requirement is for an infinitely
long scrollable region. By using the Scrollby method of a TWinControl I
can effectively achieve this because the canvas is just moved x pixels,
the displaced pixels are lost and new pixels are provided at the other
side.

Memos don't have a canvas so I can't write directly to them. If I use
an image it appears to have a finite size, and the scroll is of the
whole image component not just the canvas.

With a Form I can write to the canvas and progressively scroll the text,
adding more text as I progress. The only problem is that I can't write
to an invisible part of the form. I can't make the form bigger than the
screen anyway, and if I place another control over the spot where the
text is being written it simply does not appear when scrolled. If I
write even a single letter to the screen then this of course suddenly
appears and gives a non smooth appearance.

I could of course write the text to a separate canvas and then copy one
row of pixels at a time, but what I wanted to do was write to a piece of
canvas off screen and simply let it slide into view.
Geoff

Peter Below (TeamB)

unread,
Apr 22, 2003, 1:42:57 PM4/22/03
to
In article <3EA53C64...@nospam.com>, Geoff wrote:
> Thanks for the comments Andrew. My requirement is for an infinitely
> long scrollable region. By using the Scrollby method of a TWinControl I
> can effectively achieve this because the canvas is just moved x pixels,
> the displaced pixels are lost and new pixels are provided at the other
> side.

Use a TPaintbox to display the text, that is your canvas. You can plop it on a
panel, on the form itself, what best suits your need. You paint the text in the
paintboxes OnPaint event.

Here is an old example you may cannibalize.

<quote
source="http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=19374">

Here is a bare-bones file viewer using a tstringlist for storage, a paintbox for
display, and a tscrollbar for navigation. It has no problems with a 4 MByte
file. (D4.03, Win95B)

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, Menus, ExtCtrls, Grids, ExtDlgs;

type
TForm1 = class(TForm)
Panel1: TPanel;
Panel2: TPanel;
ScrollBar1: TScrollBar;
Panel3: TPanel;
PaintBox1: TPaintBox;
Button1: TButton;
OpenDialog1: TOpenDialog;
Button2: TButton;
OpenPictureDialog1: TOpenPictureDialog;
procedure Button1Click(Sender: TObject);
procedure Panel3Resize(Sender: TObject);
procedure ScrollBar1Change(Sender: TObject);
procedure PaintBox1Paint(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
FLines: TStringlist;
FLineHeight: Integer;
FTexture: TPicture;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation


{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
If Opendialog1.execute then begin
if not assigned( FLines ) then
FLines := TStringlist.Create;
FLines.Loadfromfile( opendialog1.filename );
canvas.font.assign( paintbox1.font );
FLineheight := canvas.textheight( 'Äg' );
with scrollbar1 do begin
position := 0;
max := FLines.Count;
smallchange := 1;
panel3resize( nil );
end;
paintbox1.Invalidate;
end;
end;

procedure TForm1.Panel3Resize(Sender: TObject);
begin
If FLineHeight > 0 Then
with scrollbar1 do begin
LargeChange := paintbox1.Height div FLineheight - 1;
pagesize := largechange;
end;
end;

procedure TForm1.ScrollBar1Change(Sender: TObject);
begin
paintbox1.invalidate;
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
const
textcolors : array [0..3] of TColor =
(clBlack, clblue, clRed, clGreen);
var
n,x,y: Integer;

begin
with paintbox1, paintbox1.canvas do begin
if assigned( FTexture ) then begin
y:= 0;
while y < clientheight do begin
x:= 0;
while x < clientwidth do begin
draw( x, y, FTexture.Graphic );
Inc( x, FTexture.Width );
end;
Inc( y , FTexture.Height );
end;
end
else begin
brush.color := clWindow;
brush.style := bsSolid;
fillrect( clientrect );
end;
If not assigned( FLines ) Then
exit;
n:= scrollbar1.position;
y:= 0;
brush.Style := bsclear;
while (y < clientheight) and (n < Flines.count ) do begin
font.color := textcolors[ n mod 4 ];
textout( 2, y, Flines[n] );
inc( n );
inc( y, FLineHeight );
end;
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
with openpicturedialog1 do
if execute then begin
if not assigned( Ftexture ) then
FTexture := TPicture.Create;
Ftexture.loadfromfile( filename );
paintbox1.Invalidate;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
paintbox1.parent.doublebuffered := true;
// required to avoid flicker
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
FTexture.free;
end;

end.
{
object Form1: TForm1
Left = 192
Top = 128
Width = 732
Height = 433
Caption = 'Form1'
Color = clBtnFace
Font.Charset = ANSI_CHARSET
Font.Color = clBlack
Font.Height = -17
Font.Name = 'Arial'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch = 120
TextHeight = 19
object Panel1: TPanel
Left = 0
Top = 0
Width = 588
Height = 406
Align = alClient
BevelInner = bvLowered
Caption = 'Panel1'
TabOrder = 0
object ScrollBar1: TScrollBar
Left = 568
Top = 2
Width = 18
Height = 402
Align = alRight
Kind = sbVertical
PageSize = 0
TabOrder = 0
OnChange = ScrollBar1Change
end
object Panel3: TPanel
Left = 2
Top = 2
Width = 566
Height = 402
Align = alClient
BevelOuter = bvNone
TabOrder = 1
OnResize = Panel3Resize
object PaintBox1: TPaintBox
Left = 0
Top = 0
Width = 566
Height = 402
Align = alClient
Color = clBtnFace
Font.Charset = ANSI_CHARSET
Font.Color = clBlack
Font.Height = -17
Font.Name = 'Times New Roman'
Font.Style = []
ParentColor = False
ParentFont = False
OnPaint = PaintBox1Paint
end
end
end
object Panel2: TPanel
Left = 588
Top = 0
Width = 136
Height = 406
Align = alRight
Caption = 'Panel2'
TabOrder = 1
object Button1: TButton
Left = 16
Top = 20
Width = 95
Height = 25
Caption = 'Open file'
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 17
Top = 100
Width = 100
Height = 25
Caption = 'Texture'
TabOrder = 1
OnClick = Button2Click
end
end
object OpenDialog1: TOpenDialog
Filter = 'Textfiles (*.TXT)|*.TXT|Pascal source files|*.PAS;*.DPR'
Left = 608
Top = 56
end
object OpenPictureDialog1: TOpenPictureDialog
Filter =
'All (*.jpg;*.jpeg;*.bmp;*.ico;*.emf;*.wmf)|*.jpg;*.jpeg;*.bmp;*.' +
'ico;*.emf;*.wmf|JPEG Image File (*.jpg)|*.jpg|JPEG Image File (*' +
'.jpeg)|*.jpeg|Bitmaps (*.bmp)|*.bmp|Icons (*.ico)|*.ico|Enhanced' +
' Metafiles (*.emf)|*.emf|Metafiles (*.wmf)|*.wmf'
Left = 616
Top = 140
end
end
}
</quote>

--
Peter Below (TeamB)
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be


Geoff

unread,
Apr 22, 2003, 3:57:56 PM4/22/03
to
Thanks Peter I'll look and that and come back.
Geoff
0 new messages