Recent

Author Topic: How to draw on the form with scroll bars using "absolute" coordinates?  (Read 4043 times)

zamtmn

  • Hero Member
  • *****
  • Posts: 594
Hi All!

I need to draw something on a form in a certain place, excluding the position of scrollbars. I can `t do it.
Look at the test case. Label "abs" moves with the scrolling, and returns to the coordinates 100,100 only when resizing. I need to stop it moving
Code: [Select]
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs;

type

  { TForm1 }

  TForm1 = class(TForm)
    procedure _onCreate(Sender: TObject);
    procedure _onPaint(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1._onCreate(Sender: TObject);
begin
     VertScrollBar.Range:=1000;
     VertScrollBar.Tracking:=true;
     HorzScrollBar.Range:=1000;
     HorzScrollBar.Tracking:=true;
end;

procedure TForm1._onPaint(Sender: TObject);
var
  arect:trect;
begin
     //UpdateScrollbars;{uncomment this line - draw good, but other errors (app not close)}
     ARect := GetClientRect;
     canvas.TextRect(ARect,100+HorzScrollBar.Position,100+VertScrollBar.Position,'Abs');
end;

end.
How to do it?
win7, trunk lazarus, trunk fpc

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: How to draw on the form with scroll bars using "absolute" coordinates?
« Reply #1 on: October 14, 2014, 10:39:54 pm »
You should not do anything in an OnPaint handler (or Paint procedure) except painting, or you will set up an endless loop of resizing/repainting, as you discovered when your app could not be closed.
Try this as an alternative.
Drop a label named absLabel on the main form of a new project, and complete the code as follows:

Code: [Select]
unit testScrolling;

{$mode objfpc}{$H+}

interface

uses
  Classes, Forms, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    absLabel: TLabel;
    procedure FormCreate(Sender: TObject);
  protected
    procedure ScrollbarHandler(ScrollKind: TScrollBarKind; OldPosition: Integer);
      override;
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  absLabel.Caption:='abs';
  absLabel.Top:=100;
  absLabel.Left:=100;

  VertScrollBar.Range:=1000;
  VertScrollBar.Tracking:=True;
  VertScrollBar.Smooth:=True;
  HorzScrollBar.Range:=1000;
  HorzScrollBar.Tracking:=True;
  HorzScrollBar.Smooth:=True;
end;

procedure TForm1.ScrollbarHandler(ScrollKind: TScrollBarKind;
  OldPosition: Integer);
begin
  inherited ScrollbarHandler(ScrollKind, OldPosition);
  case ScrollKind of
    sbHorizontal: absLabel.Left:=100+OldPosition;
    sbVertical:   absLabel.Top:=100+OldPosition;
  end;
end;

end.


zamtmn

  • Hero Member
  • *****
  • Posts: 594
Re: How to draw on the form with scroll bars using "absolute" coordinates?
« Reply #2 on: October 14, 2014, 11:17:04 pm »
>>You should not do anything in an OnPaint handler (or Paint procedure) except painting, or you will set up an endless loop of resizing/repainting, as you discovered when your app could not be closed.
I understand that, just trying to understand why I did not get

>>Try this as an alternative.
Thanks! Unfortunately it does not suit me. I need to draw, and do not use controls


howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: How to draw on the form with scroll bars using "absolute" coordinates?
« Reply #3 on: October 14, 2014, 11:45:51 pm »
You can adapt what I showed earlier to paint on the form's canvas:

Code: [Select]
unit testScrolling;

{$mode objfpc}{$H+}

interface

uses
  Classes, Forms, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
  protected
    procedure ScrollbarHandler(ScrollKind: TScrollBarKind; OldPosition: Integer);
      override;
  private
    const lbl = 'abs';
  private
    scrollPosX: integer;
    scrollPosY: integer;
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  VertScrollBar.Range:=1000;
  VertScrollBar.Tracking:=True;
  VertScrollBar.Smooth:=True;
  HorzScrollBar.Range:=1000;
  HorzScrollBar.Tracking:=True;
  HorzScrollBar.Smooth:=True;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
  r: TRect;
begin
  r:=Rect(0, 0, HorzScrollBar.Range+100, VertScrollBar.Range+100);
  Canvas.TextRect(r, 100+scrollPosX, 100+scrollPosY, lbl);
end;

procedure TForm1.ScrollbarHandler(ScrollKind: TScrollBarKind;
  OldPosition: Integer);
begin
  inherited ScrollbarHandler(ScrollKind, OldPosition);
  case ScrollKind of
    sbHorizontal: scrollPosX:=OldPosition;
    sbVertical:   scrollPosY:=OldPosition;
  end;
end;

end.


zamtmn

  • Hero Member
  • *****
  • Posts: 594
Re: How to draw on the form with scroll bars using "absolute" coordinates?
« Reply #4 on: October 15, 2014, 06:38:46 am »
>>You can adapt what I showed earlier to paint on the form's canvas:
This not works on windows, in fact it is almost the same as the code in my first post.
Thanks for the tip on ScrollbarHandler, I will use such variant:
Code: [Select]
...
procedure TForm1.FormPaint(Sender: TObject);
var
  r: TRect;
begin
  r:=Rect(0, 0, HorzScrollBar.Range+100, VertScrollBar.Range+100);
  canvas.TextRect(r,100+HorzScrollBar.Position,100+VertScrollBar.Position,'Abs');
end;

procedure TForm1.ScrollbarHandler(ScrollKind: TScrollBarKind;
  OldPosition: Integer);
begin
  invalidate;
  inherited;
end;
...
Maybe he's not quite true, but it works

zamtmn

  • Hero Member
  • *****
  • Posts: 594
Re: How to draw on the form with scroll bars using "absolute" coordinates?
« Reply #5 on: October 15, 2014, 06:34:18 pm »
>>Maybe he's not quite true, but it works
Not work on GTK2(( text leaps +/- 1 pixel. Is such a simple problem has no solution?

 

TinyPortal © 2005-2018