Wie arbeitet PaintTo?

Für Fragen von Einsteigern und Programmieranfängern...
wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Wie arbeitet PaintTo?

Beitrag von wennerer »

Hallo,
ich habe in einer kleinen Komponente den Befehl Parent.PaintTo verwendendet. Unter Linux macht es alles so wie ich mir das vorstelle. Als ich es dann unter Windows probiert habe musste ich feststellen das es da wohl Unterschiede gibt und je nach Widget ein anderes Ergebnis raus kommt. Konkret habe ich nun festgestellt das unter Linux nur der Clientbereich eines Formulares gezeichnet wird während unter Windows die Titelleiste und der Rand mit gezeichnet werden.
Das sieht dann so aus:
Bildschirmfoto_paintto.png
Bildschirmfoto_paintto.png (11.04 KiB) 2746 mal betrachtet
Ich habe dann den Canvas von einem Panel mit paintto gezeichnet da hier keine Titelleiste vorhanden ist. Leider bleibt hier das Zielcanvas leer (unter Linux geht es). Gibt es eine Möglichkeit unter Windows painto so zu verwenden das das Ergebnis wie unter Linux ist?

Hier noch mein kleiner Test:

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
  Selector;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Panel1: TPanel;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure Panel1Paint(Sender: TObject);
  private
    bmp : tbitmap;
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormPaint(Sender: TObject);
begin

  canvas.Draw(0,50,bmp);
  canvas.Brush.Color:=cllime;
  canvas.Rectangle(120,40,220,150);

end;

procedure TForm1.Panel1Paint(Sender: TObject);
begin
  {
  with Panel1 do
  begin
   canvas.Draw(0,50,bmp);
   canvas.Brush.Color:=cllime;
   canvas.Rectangle(120,40,220,150);
  end;
  }
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 paintto(Canvas,0,0);
 //Panel1.PaintTo(Panel1.Canvas,0,0);
 //Panel1.PaintTo(Canvas,0,0);
end;

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  bmp.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  bmp := tbitmap.Create;
  bmp.SetSize(100,100);
  bmp.Canvas.Brush.Color:=clred;
  bmp.Canvas.Rectangle(0,0,100,100);

  panel1.Visible:=false;
end;

end.
Viele Grüße
Bernd

Edit: Rechtschreibfehler verbessert.
Zuletzt geändert von wennerer am Do 2. Jul 2020, 16:53, insgesamt 1-mal geändert.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wie arbeitet painto?

Beitrag von Winni »

Hi!

Da sind ja mehrere Sachen:

Mach mal Dein Panel Visible und blau. Dann klappts auch mit dem Panel.
Gerade getestet unter Win7/64.

Mit dem Title Bar ist das eine lästige Geschichte:
Unter Linux gehört der dem Window-Manager.
Und unter Windows gehört er zum Fenster.

Versuch das doch mal unter Win mit den Koordinaten von
Form.Clientrect. Dann sollte es hoffentlich klappen.

Winni

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: Wie arbeitet PaintTo?

Beitrag von wennerer »

Hi Winni,
vielen Dank für die Antwort und den Tipp mit der Hintergrundfarbe! Ich habe nun mal etwas herum probiert und festgestellt das PaintTo vom Panel immer dann funktioniert wenn die Panel.Color ungleich der Form.Color ist. Warum das so ist weiß ich nicht, mir hilft es aber schon mal weiter.
Wie du das mit Form.ClientRect meinst verstehe ich leider nicht. Wenn ich ClientRect.Left und Top verwende ändert das nichts am Ergebnis. Ich bin jetzt den Weg gegangen das ich die Titelleistenhöhe und die Randbreite verrechne. Ob es einfacher geht? Aber es funktioniert jedenfalls. Schaut dann so aus:

Code: Alles auswählen

PaintTo(Canvas,0-(GetSystemMetrics(32)),0-((GetSystemMetrics(4))+(GetSystemMetrics(32))));
Viele Grüße
Bernd

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wie arbeitet PaintTo?

Beitrag von Winni »

Hi!

Ich hab noch nie mit PaintTo gearbeitet und gerade kein Windows zur Hand.

Ich hab solche Sachen immer mit

Code: Alles auswählen

procedure canvas.CopyRect(const Dest: TRect; SrcCanvas: TCanvas;
                       const Source: TRect);
gelöst. Du kopierts das Rechteck Source vom SrcCanvas zum Rechteck Dest zum Canvas.
Dabei sollten Source und Dest die gleiche Größe besitzen.
Das geht immer!

Winni

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: Wie arbeitet PaintTo?

Beitrag von wennerer »

Hallo,
normal geb ich dir da recht. In meinem Fall möchte ich aber aus einer Komponente heraus den Canvas des Parent in eine Bitmap kopieren. Da ich aber vorher nicht weiß wer/was der Parent sein wird kann ich canvas.copyrect nicht verwenden. Was eben zur Verfügung steht ist Parent.PaintTo. Aus meiner Komponente heraus funktioniert es unter Windows nur wenn der Parent eine Form ist. Leider hilft es hier auch nicht die Hintergrundfarbe zu ändern. Wo der Unterschied zum Mini Beispiel liegt konnte ich noch nicht feststellen.
Ich habe jetzt noch einen interessanten Artikel gelesen.
http://docs.embarcadero.com/products/ra ... teger.html
Hier drin steht das man vor dem Aufrufen von PaintTo den Canvas sperren muss. Ich hab da nun schon einiges getestet komme aber nicht wirklich voran. Weiß hier jemand Bescheid bzw. einen Link mit Infos?
Und noch eine Frage: Ich hab so im Hinterkopf das PainTo den gesamten Canvas (also auch den nicht sichtbaren Bereich) liefert. Stimmt das?
Viele Grüße
Bernd

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wie arbeitet PaintTo?

Beitrag von Winni »

Hi!

Okay. Step by step.

Sieht so aus, also ob PaintTo die gesamte Komponente zeichnet. Du hast ja als Parameter für die Destination nur den Origin mit x und y, aber kein Rechteck.

Zweitens; Canvas locken solange gearbeitet wird:

Code: Alles auswählen

Canvas.BeginUpdate
// zeichnen
Canvas.Endupdate
Ansonsten teste ich gleich mal.

Winni

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: Wie arbeitet PaintTo?

Beitrag von wennerer »

Hallo Winni,
leider gibt es bei mir kein canvas.beginupdate.

Viele Grüße
Bernd

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wie arbeitet PaintTo?

Beitrag von Winni »

Sorry, tüddelüd gemacht.

Das heisst Canvas.Lock und ....UnLock

Winni

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: Wie arbeitet PaintTo?

Beitrag von wennerer »

Hi,
ja damit probier ich schon ne Zeit lang herum. Komme aber nicht weiter.

Viele Grüße
Bernd

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wie arbeitet PaintTo?

Beitrag von Winni »

So, ,jetzt ein ganz einfaches Beispiel.

Ohne OnPaint und anderen Kram.

Auf eine Form kommt
z.B.
* eine CheckGroup in gelb, 150 x 150
* ein Panel in aqua, 150 x 150
* Ein Button

Der Button macht:

Code: Alles auswählen

procedure TForm1.Button2Click(Sender: TObject);
begin
 CheckGroup1.PaintTo(Panel1.Canvas,0,0);
end;
Click, hast Du ein Abbild von der CheckBox auf dem Panel.
Geht astrein.

Mit einfachen Beispielen anfangen! Und nicht zu viel auf einmal wollen!

Keep on hacking!

Winni

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: Wie arbeitet PaintTo?

Beitrag von wennerer »

Ja hast du recht.
Hab hier nur schon leider etliche Mini Beispiele wo es geht (allerdings nur mit unterschiedlicher Hintergrundfarbe). Mein Problem ist momentan das ich den Unterschied nicht finden kann. Wahrscheinlich muss ich einfach mal eine Pause mache. Vielleicht kommt dann die Erleuchtung :D

Viele Grüße
Bernd

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wie arbeitet PaintTo?

Beitrag von Winni »

Hi!

Also Dein Problem mit den Hintergrundfarben - das habe ich nicht .
Ich hab gerade bei meinem obigen simplen Beispiel sowohl bei der GroupBox als auch beim Panel die Farbel auf hässliches clDefault gesetzt: klappt einwandfrei. Sowohl unter Linux als auch Windows.

Du musst mal den Müll aus Deinen Beispielen rausschmeissen - Du spielst da auch noch mit visible rum: Raus damit .

Winni

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: Wie arbeitet PaintTo?

Beitrag von wennerer »

Hallo,
habe mir nun noch ein Minimal Programm gebastelt (ohne jeden Schnick-Schnack :D ). Zuerst habe ich angefangen an meinem Verstand zu zweifeln. Mittlerweile kann ich aber folgendes sagen:
Kompiliere ich das Programm unter Linux geht alles wie gewünscht.
Kompiliere ich das Programm unter Windows läuft es unter Wine wie gewünscht.
Probiere ich die .exe in Windows XP oder auch in Win10 geht es nur dann wenn beim Kompilieren Panel1.ParentColor auf false gesetzt war.
Warum das so ist kann ich leider nicht sagen, ich habe es aber mehrmals getestet!
Danke an Winni ohne deine Antworten hätte ich nicht in der Richtung gesucht. Wie sich das jetzt in meiner Komponente auswirkt muss ich mal in Ruhe austesten.
Viele Grüße
Bernd
Dateianhänge
TestPaintTo.zip
(64.54 KiB) 134-mal heruntergeladen

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wie arbeitet PaintTo?

Beitrag von Winni »

Hi!

Es spukt!

Ich hab bei meinem simplen Beispiel sowohl bei der CheckGroup als auch beim Panel die ParentColor auf true gesetzt. Funktioniert weiter einwandfrei.

Win7/64 auf VirtualBox

Frag mich bitte nicht nach Logik .......

Winni

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Wie arbeitet PaintTo?

Beitrag von Winni »

Hi!

TestPaintTo läuft doch einwandfrei!
Gerade getestet!

Winni

Antworten