Autor Beitrag
Aerin
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mo 06.11.06 00:18 
Ich habe eine PaintBox erstellt und möchte nun per Mausklick an der entsprechenden Stelle einen Punkt einzeichnen. Ich habe mir gedacht ich könnte das mit nem OnClick Event machen bei dem folgendes ausgeführt wird:

ausblenden Delphi-Quelltext
1:
PaintBox.Canvas.Pixels[x,y] := clBlack					


Das Problem ist, dass ich nicht weiß wie ich die aktuelle Zeigerposition auslese. Sry wenns ne dumme Frage is aber ich hab wirklich noch sehr wenig Erfahrung mit Delphi ;).
Also wie müsste das richtig aussehen?

Und die nächste Frage: Wie ändere ich die Hintergrundfarbe der PaintBox?

Moderiert von user profile iconChristian S.: Delphi-Tags hinzugefügt
Moderiert von user profile iconChristian S.: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am So 12.11.2006 um 18:41
Ironwulf
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 733
Erhaltene Danke: 2



BeitragVerfasst: Mo 06.11.06 00:46 
onmousedown verwenden, nicht onclick
das erste liefert noch die koordinaten mit x,y mit
Kroko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1284

W98 W2k WXP
Turbo D
BeitragVerfasst: Mo 06.11.06 06:18 
oder in OnMouseMove die Koordinaten merken

Hintergrund: TBrush + F1 , FillRect + F1

_________________
Die F1-Taste steht nicht unter Naturschutz und darf somit regelmäßig und oft benutzt werden! oder Wer lesen kann, ist klar im Vorteil!
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Mo 06.11.06 09:12 
Hallo,

oder in OnClick die Maus-Koordinaten ermitteln, z.B:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var aPoint : TPoint;
begin
  GetCursorPos(aPoint);// >> Bildschirmkoordinaten
  aPoint := PaintBox.ScreenToClient(aPoint);// >> Koordinaten in PaintBox
  PaintBox.Canvas.Pixels[aPoint.x,aPoint.y] := clBlack;


Ps.: Herzlich willkommen in der Entwickler-Ecke (EE) :wave:
Zur Formatierung von Delphi-Code kannst du die BBCodes [Delphi]Dein Code[/Delphi] verwenden. Weitere Infos dazu Link

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
Aerin Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mo 06.11.06 21:17 
user profile iconLannes hat folgendes geschrieben:
Hallo,

oder in OnClick die Maus-Koordinaten ermitteln, z.B:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var aPoint : TPoint;
begin
  GetCursorPos(aPoint);// >> Bildschirmkoordinaten
  aPoint := PaintBox.ScreenToClient(aPoint);// >> Koordinaten in PaintBox
  PaintBox.Canvas.Pixels[aPoint.x,aPoint.y] := clBlack;


Ps.: Herzlich willkommen in der Entwickler-Ecke (EE) :wave:
Zur Formatierung von Delphi-Code kannst du die BBCodes [Delphi]Dein Code[/Delphi] verwenden. Weitere Infos dazu [url=www.delphi-forum.de/...p;popup=1]Link[/url]


Das funktioniert genau so wie soll, danke.

Aber wie ich die Hintergrundfarbe ändere habe ich noch nicht ganz verstanden.
Ich hab die Eigenschaft Color auf clWhite geändert und dann als Test ob das so funktioniert folgendes in meine Clickprocedure eingefügt.
ausblenden Delphi-Quelltext
1:
with PB_Oberflaeche.Canvas do FillRect(ClipRect);					


damit bekomm ich den Hintergrund weiß, allerdings wird beim nächsten Punkt der alte auch wieder gelöscht, ist ja klar, denn jedes mal wird alles wieder mit Weiß gefüllt.
Also wo muss das hin damit der Hintergrund gleich beim Programmstart weiß ist? Oder gibts da vll ne bessere Lösung für das Problem?

Vielen Dank schon mal für euere Hilfe
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Mo 06.11.06 21:44 
Schreib das in OnCreate des Formulars.

_________________
"Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
Aerin Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mo 06.11.06 23:38 
user profile iconGTA-Place hat folgendes geschrieben:
Schreib das in OnCreate des Formulars.


Habs ausprobiert und so funktionierts leider nicht. Hab folgende procedure für OnCreate eingetragen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure TF_1.FormCreate(Sender: TObject);
begin
with PB_Oberflaeche.Canvas do FillRect(ClipRect);
end;


Allerdings wird da die Farbe zum füllen der PaintBox genommen die unter Form.Color eingestellt ist und nicht die PaintBox.Color. Außerdem wird die PaintBox auch wieder gelöscht sobald ich auf ein anderes Fenster wechsele und zurück, da in dem Fall jedes mal wieder die OnCreate procedure ausgeführt wird.
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Di 07.11.06 01:09 
Hallo,

such mal nach Suche in der Entwickler-Ecke OFFSCREENBITMAP

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Di 07.11.06 07:46 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TF_1.FormCreate(Sender: TObject);  
begin  
  with PB_Oberflaeche.Canvas do
  begin
    Brush.Color := clWhite;
    FillRect(ClipRect); 
  end;
end;

OnCreate wird nur 1x aufgerufen. Dein Problem hat einen anderen Grund. Der Tipp von Lannes wird da helfen.

_________________
"Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
Aerin Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Sa 11.11.06 17:56 
hab zu OFFSCREENBITMAP das hier gefunden:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var
Hintergrund : TBitmap;
begin
   //Bitmap erzeugen
  Hintergrund := TBitmap.Create;
   //Hintergrundfarbe
  Hintergrund.Canvas.Brush.Color := clWhite;
   //Größe festlegen
  Hintergrund.Width  := PB_Oberflaeche.Width;
  Hintergrund.Height := PB_Oberflaeche.Height;
end;


allerdings hilft mir das auch nich viel weiter, da die Farbe in der das Form eingefärbt wird wieder nicht das angegebene weiß ist....
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Sa 11.11.06 18:12 
Hallo,

aus Deinem Code ist nicht ersichtlich wo er ausgeführt wird.
Wird denn auch dein Bitmap "Hintergrund" mit BitBlt der PaintBox zugewiesen?

Wenn Du nur die Form färben willst brauchst Du nur Color der Form zu setzen.

Was hast Du denn zu OffScreenBitmap gefunden?
falls Du das (Link) noch nicht kennst, solltest Du es dir durchlesen(und verstehen :wink: ).

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
Aerin Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Sa 11.11.06 20:32 
user profile iconLannes hat folgendes geschrieben:
Hallo,
aus Deinem Code ist nicht ersichtlich wo er ausgeführt wird.
Wird denn auch dein Bitmap "Hintergrund" mit BitBlt der PaintBox zugewiesen?

hab das Ganze wieder im OnCreate des Forms ausführen lassen.
Hast recht, ich hatte die Bitmap gar nicht auf die PaintBox zeichnen lassen.
Hab das mal korrigiert und noch mal dran geschrieben was ich denke, was der jeweilige Befehl machen sollte
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TF_1.FormCreate(Sender: TObject);
var
Hintergrund : TBitmap;
begin
  Hintergrund := TBitmap.Create; //Bitmap erzeugen
  Hintergrund.Canvas.Brush.Color := clWhite; //Farbe des Pinsels festlegen
  Hintergrund.Canvas.Pen.Color := clWhite;   //Farbe des Stifts festlegen
  Hintergrund.Width  := PB_Oberflaeche.Width; //Breite der Bitmap festlegen
  Hintergrund.Height := PB_Oberflaeche.Height;//Höhe festlegen
  Hintergrund.Canvas.Rectangle(0,0,Hintergrund.Width,Hintergrund.Height);//Rechteck in die Bitmap zeichnen, das eigentlich weiß sein sollte und die komplette Bitmap abdecken sollte
  PB_Oberflaeche.Canvas.Draw(0,0,Hintergrund);//Die weiße Bitmap wird auf die Paintbox gemalt
end;


nach dem was in den einzelnen Schritten stattfindet sollte die Painbox also weiß sein, aber wenn ich F9 drücke ist sie dennoch grau....

Edit: Liegt daran das man das nicht mit OnCreate des Forms amchen kann, hab die selbe procedure grade OnClick bei meiner Paintbox zugewiesen und getestet, auf Click wird die PB weiß.

Also muss ich jetzt nur noch feststellen wo ich die procedure ausführen lassen muss damit dsa Form beim Start weiß wird.

Edit2:
und hier noch mein eigenes rumprobieren, was OnClick jetzt auch funktioniert

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var
PBRechteck : TRect;
begin
PB_Oberflaeche.Canvas.Brush.Color := clWhite;
PBRechteck := Rect(PB_Oberflaeche.Left,PB_Oberflaeche.Top,PB_Oberflaeche.Left+PB_Oberflaeche.Width,PB_Oberflaeche.Top+PB_Oberflaeche.Height);
PB_Oberflaeche.Canvas.FillRect(PBRechteck);


Edit3: Auch wenn ich nicht genau weiß wann OnPaint ausgelöst wird, es macht genau das was ich will, beim Progstart weiß füllen ;)
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Sa 11.11.06 23:09 
Hallo,
user profile iconAerin hat folgendes geschrieben:

...Auch wenn ich nicht genau weiß wann OnPaint ausgelöst wird...
das ist schade, deshalb hatte ich Dir den Link gegeben.
Und es ist schade das Du den Artikel vermutlich nicht ausführlich genug gelesen hast. Am Ende des Artikels steht auch ein schöner übersichtlicher Code der eigentlich alles gut verdeutlicht.

Lass Dir doch mal in einem zusätzlichen Memo das Auftreten des Ereignisses OnPaint ausgeben.

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
Aerin Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: So 12.11.06 02:55 
So, hab den Text mal ganz gelesen und jetzt ist mir auch klar wann OnPaint eigentlich ausgelöst werden sollte, einfach beim Zeichnen des Fensterinhaltes(wobei ich mir auch nicht so ganz sicher bin ob bei diesem neuzeichnen des Fensterinhaltes das onpaint der paintbox ausgelöst wird), also jedesmal wenn das Programmfenster angezeigt werden soll wenn es vorher nicht angezeigt wurde, also entweder wenn das Programm gestartet wird oder wenn ein Teil verdeckt gewesen ist und neu gezeichnet werden soll, weshalb es auch zu dem Phänomen kommt das der Teil wo ich mit nem anderen Fenster "drüberwische" wieder weiß wird. Wie ich das Zwischenspeichern des Inhalts genau in mein Programm einbaue beschäftigte ich mich dann morgen ;)
Aber eine Frage wär da noch:
Macht es denn demnach überhaupt Sinn die Hintergrundfarbe durch OnPaint zu ändern? Wenn ich den Text richtig verstanden würde ja dann bei jedem neuzeichnen wieder alles neugezeichnete weiß werden, selbst wenn ich eigentlich etwas einbaue um den Inhalt zwischenzuspeichern.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19313
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 12.11.06 09:05 
Nun ja, am sinnvollsten ist es, wenn du alles auf die Hintergrundbitmap zeichnest und diese dann auf die eigentliche Zeichenfläche kopierst.
In dem von dir etwas modifizierten Code, den du gepostet hast, malst du aber nur ein weißes Rechteck und kopierst dieses dann auf die Zeichenfläche. Vor allem machst du das aber in FormCreate mit einer lokalen Bitmap.

Sinnvoll ist das aber nur, wenn du eine globale Hintergrundbitmap benutzt (direkt unter public oben in der Formulardeklaration deklariert)! Diese wird in FormCreate erzugt und mit dem Hintergrund (in dies Fall nur das füllende Rechteck) gefüllt. In OnPaint zeichnest du die dann auf die reale Zeichenfläche.
Alles, was ausgegeben werden soll, zeichnest du auf die Hintergrundbitmap. Entweder zeichnest du kleine Operationen dann auch direkt zusätzlich auf die reale Zeichenfläche oder du rufst einfach Repaint auf, wo ja dann die Hintergrundbitmap inklusive der neuesten Änderung auf die Zeichenfläche übertragen wird.

Das ist auch in dem Link von user profile iconLannes so gemeint! Da du das anscheinend wirklich gelesen, aber nur nicht verstanden hast, habe ich es hier nochmal versucht zu erklären...
Denn ich muss zugeben, dass dies etwas kurz beschrieben ist, es steht aber da:
Zitat:
aber, und das ist die elegantere Methode, wir zeichnen auf ein Bitmap im Speicher und kopieren es bei Bedarf auf unser Fenster.
Aerin Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: So 12.11.06 19:39 
Ich denke ich habs geschafft. Danke für die Hilfe, hier mal der ganze Code:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
unit U_Test;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

type
  TF_1 = class(TForm)
    PB_Oberflaeche: TPaintBox;
    procedure FormCreate(Sender: TObject);
    procedure PB_OberflaechePaint(Sender: TObject);
    procedure PB_OberflaecheClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    Hintergrund : TBitmap;
    end;

var
  F_1: TF_1;

implementation

{$R *.dfm}

procedure TF_1.FormCreate(Sender: TObject);
begin
    Hintergrund := TBitmap.Create; //Bitmap erzeugen
    Hintergrund.Canvas.Brush.Color := clWhite; //Farbe des Pinsels festlegen
    Hintergrund.Canvas.Pen.Color := clWhite;   //Farbe des Stifts festlegen
    Hintergrund.Width  := PB_Oberflaeche.Width; //Breite der Bitmap festlegen
    Hintergrund.Height := PB_Oberflaeche.Height;//Höhe festlegen
    Hintergrund.Canvas.Rectangle(0,0,Hintergrund.Width,Hintergrund.Height);//Rechteck in die Bitmap zeichnen, das eigentlich weiß sein sollte und die komplette Bitmap abdecken sollte
end;

procedure TF_1.PB_OberflaechePaint(Sender: TObject);
begin
PB_Oberflaeche.Canvas.Draw(0,0,Hintergrund);//Die weiße Bitmap wird auf die Paintbox gemalt
end;

procedure TF_1.PB_OberflaecheClick(Sender: TObject);
var
aPoint : TPoint;
begin
GetCursorPos(aPoint);
aPoint := PB_Oberflaeche.ScreenToClient(aPoint);
Hintergrund.Canvas.Pixels[aPoint.x,aPoint.y] := clBlack;
PB_Oberflaeche.Repaint;
end;


end.


das ganze funktioniert, und auch wenn ich auf nen anderes Fenster wechsle und zurück, bleibt der Inhalt erhalten.

Wenn man sonst noch was verbessern kann bin ich natürlich für Vorschläge offen ;)
Vll gibts ja ne einfache Möglichkeit das Flackern beim Repaint zu vermeiden (stört aber nicht so wirklich)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19313
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 12.11.06 19:44 
Das Flackern kommt wohl daher, dass du die Draw Methode verwendest...
Versuchs doch mal so wie in dem Link oben.
Michael hat nicht ohne Grund BitBlt benutzt, das hat er ja auch geschrieben...
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Mo 13.11.06 00:50 
Hallo,

nicht vergessen das Bitmap in OnDestroy der Form wieder freizugeben. :mahn:

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
Aerin Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Fr 17.11.06 19:09 
OK, hab im OnDestroy Hintergrund.Free; eingetragen.
Und wenn ich das richtig verstanden habe wird doch durch den Befehl einfach der Inhalt der Bitmap wieder aus dem Speicher entfernt und der Speicher wieder freigegeben für andere Programme oder?
Was sollte/kann man noch beim OnDestroy freigeben? Ich verwende auch arrays, müssen die freigegeben werden?
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Fr 17.11.06 22:20 
Hallo,

so Pi mal Daumen,

mit Create(reserviert Speicher) erzeugte Objecte >> freigeben TStringList, Streams ...
Stichworte Owner, Create >> Delphi Hilfe

statische Arrays = nein,
dynamische Arrays = ja, denn mit SetLength reservierst Du Speicher

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )