Autor Beitrag
Morduk666
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: Do 19.06.03 23:23 
hi leutz,

ich suche eineZeichenfläche wie TPaintBox, auf die man Linien zeichnen kann. Nur ohne canvas. Suche etwas wo auf der Zeichenfläche bleibt auch nachdem ich ein andren Formular drüber gelegt hab. und zwar ohne jedesmal die Linien neu zeichnen zu müssen.

oder gits n befehl füs canvas wo mir mein bisheriges bild neu zeichnet ?
also PaintBox.Refresh bringt etc bringt nix :(


bin dankbar für jeden hinweis
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Do 19.06.03 23:54 
Wie wäre es mit TPaintBox.OnPaint. Alternativ kannst du natürlich auch ein TImage missbrauchen.

_________________
Ist Zeit wirklich Geld?
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 20.06.03 01:59 
Du muß dir mal das Prinzip von Windows vor die Augen halten, dann hast du die Lösung auch schon vor dir.

Also *holttiefluft*. Windows funktioniert über Nachrichten, das heißt jedes eintretende Ereignis löst einen Nachriht aus, auf die dein Programm reagiert. Seies, dass du mit Code Windows bzw deinem Programm explizit sagst was passieren soll oder das Windows die standard Behandlungsroutine ausführt. Bei einem Klick auf einem Button wäre das BM_CLICK. Beim Erzeugen eines fensters wäre das WM_CREATE.

Was passiert nun, wenn dein Fenster von einem anderen überlagert wird und es dann weggenommen wird? Nun der Bereich des Desktop wird für ungültig erklärt. Windows weiß nun nicht, was es darstellen soll. Das alleine weiß nur das wieder sichtbar gewordenen Fenster bzw. Programm. Also schickt Windows an das betreffende Fenster eine Nachricht, die es dazu veranlaßt sich neu zu zeichnen (WM_PAINT).
Bei den standard Kontrolls (Buttons, Listboxen etc.) braucht es dazu keinen Code von dir. Windows weiß wie sie aussehen und dein Programm kann WM_PAINT an die Fensterprozedur dieser Kontrolls weiterleiten. Diese bearbeitet nun WM_PAINT welche die Kontrolls neu zeichnet.

Bei der Paintbox geht das nicht. Wie auch Windows, bzw. die standard fensterprozedur weiß ja nicht, was du da drauf gezeichnet hast. Also wird diser Bereich deines Fenster bzw. der Paintbox weiß von Windows dargestellt.

So die Lösung ist nun recht einfach. Die Paintbox speziell besitzt das Ereignis OnPaint welches auf die Windows-Nachricht WM_PAINT reagiert. In diesem Ereignis mußt du nun alle Zeichenoperationen ausführen. Sind es viele wird es flackern, da die GDI-Ausgabe relativ langsam ist. Aber deine Paintbox zeigt immer das, was sie zeigen soll. Dies ist natürlich unschön immer alles in OnPaint zu zeichnen hinzukommt, weil ja nicht immer das gleich egezeichnet werden soll. Klickt man auf den einen Button soll ein Kreis gezeichnet werden, klickt man auf den anderen ein Rechteck.

"Was tun?", sprach Zeus. Nun ganz einfach, man greift zu einem Trick. Dieser Trick besteht darin nicht direkt auf die Paintbox oder auf die Canvas des Fensters zu zeichnen, sonder auf ein Bitmap im Speichern und immer wenn nötig dieses Bitmap auf den Canvas zu kopieren. Die geschieht einmal in der ButtonClick-Prozedur und jedes mal im OnPaint Ereignis der Paintbox oder des Fensters. Das Kopieren hat auch nch den Vorteil, dass erstmal das zeichnen im Speicher schneller geht und die Ausgabe erfolgt auch schneller, da das Kopieren wesentlich schneller ist, als alles einzeln zu zeichnen.

Und weil heute Freitag ist und mir tommie-lie vorgeworfen hat, meine Antworten würden sich immer auf nötigste beschränken ein Beispiel.
Wir brauchen eine Paintbox und einen Button. Der Rest sollte sich selbst erklären.
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:
56:
type
  TForm1 = class(TForm)
    Button1: TButton;
    PaintBox1: TPaintBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
  private
    { Private-Deklarationen }
    bmp : TBitmap;  { Bitmap im Speicher }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  { Bitamp erzeugen }
  bmp := TBitmap.Create;
  { Hintergrundfarbe únd Stift dicke }
  bmp.Canvas.Brush.Color := clRed;
  bmp.Canvas.Pen.Width := 3;
  { Größe festlegen }
  bmp.Width := Paintbox1.Width;
  bmp.Height := Paintbox1.Height;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  { Bitmap freigeben }
  bmp.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  { Rechteck zeichnen }
  bmp.Canvas.Rectangle(5,5, 75, 75);
  { und auf die Paintbox kopieren }
  BitBlt(PaintBox1.Canvas.Handle, 0, 0, bmp.Width, bmp.Height, bmp.Canvas.Handle,
    0, 0, SrcCopy);
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  { bei Bedarf neu zeichnen }
  BitBlt(PaintBox1.Canvas.Handle, 0, 0, bmp.Width, bmp.Height, bmp.Canvas.Handle,
    0, 0, SrcCopy);
  { ist schon rot, da wir es in OnCreate der Form rot gemacht haben }
end;


Du siehst, mit etwas Hintergrundwissen wie Windows funktioniert läßt sich ganz einfach eine Lösung für dein Problem finde, welches gar keins ist.

Ein weiters Beispiel findest du auf meiner Homepage in dem Programm "Life of Luckie". Da habe ich auch genau diese Technik angewendet. Und das TImage solltest du nicht mißbrauchen, da es für solche Zeichenaktionen nicht geschaffen wurde.
Morduk666 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: Fr 20.06.03 21:45 
boahhhh eh *Staun*

das is ja wirklich die traum antwort. also bessere antwort könnt ich mir glaub ned wünschen.

ich bedank mich recht fedd udn werd gleich mal mein neu erworbenes wissen in tat umsetzen und mich an die arbeit maken.

also danke und schreib weiterhin so brauchbare antworten :)
Morduk666 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: Fr 20.06.03 22:27 
so wollt nur nochma bescheid geben dass alles bei mir funzt :)
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 20.06.03 22:43 
Also wenn es nach dem Posting nicht geklappt hätte, dann hätte ich dir zu einem anderem Hobby geraten. :mrgreen:
Morduk666 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20



BeitragVerfasst: Sa 21.06.03 04:17 
hihhi ;)

jo war so ziemlich idiotensicheres posting ;))