Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 15:43

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 23 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: "Neuzeichnen" kommt nicht immer
BeitragVerfasst: Do Jul 28, 2005 08:38 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Apr 25, 2005 17:51
Beiträge: 464
Also bei mir passiert folgendes: ich habe ne Form auf der sich u.a. ein TPanel befindet. In das TPanel wird per OpenGL gezeichnet. Nun habe ich die OnPaint-Methode der Form überscrhieben, um ein Neuzeichnen abzufangen, was evtl ausgelöst wird. Bei mir passiert aber folgendes: wenn ich die Größe des Fensters änder, wird das Panel nicht immer neu gezeichnet. Woran kann das liegen? Ein OnSize hat doch ein OnPaint zur Folge???


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jul 28, 2005 10:33 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Nein. Nicht zwingend. Wenn du das Fenster kleiner machst wird OnPaint nicht ausgelöst, da kein neuer sichtbarer Bereiche existieren. OnPaint wird nur beim vergrößern und beim Neuzeichnen (fenster drüber bewegen) ausgelöst. Warum das so ist Frage ich mich auch ständig aber dem ist leider so. Die sinnvollste Alternative wäre, wenn du im OnResize ein Repaint aufrufst. Wenn du magst kann du dort auch noch abprüfen ob es kleiner oder größer geworden ist. Dann würdest du nur neu zeichnen wenn es kleiner gemacht wird. So würdest du zusätzlich ein mal zeichnen sparen. Ist aber nicht zwingend notwendig. Manchmal auch nicht sinnvoll machbar.

OnPaint ist keine Methode sondern ein Event und dem kannst du eine Methode zuweisen. Die nach gut dünken des Programms aufgerufen werden kann. Das Event OnPaint wird nach dem Zeichnen des Forms ausgelöst und nicht anstelle des Zeichnens. Wenn du also verhindern möchtest, dass es sich selber neu zeichnet solltest du die Methode Paint überschrieben. In der dürftest du dann nichts machen. In den Meisten fällen genügt es vollkommen, wenn du eine bestimmte Windowsmessage unterdrückst. Dafür genügt es wenn du csOpaqe in den ControlStyles der entsprechenden Komponenten (Panel, Form etc) aufnehmen.
Code:
  1. Panel1.ControlStyle := Panel1.ControlStyle + [csOpaque];


Das sorgt dafür, dass die Message WM_ERASEBACKGRND abgefangen und unschädlich gemacht wird. Dann löscht Windows dein Fenster nicht mehr und es flimmert und flackert nicht mehr. Du musst dann aber dafür sorgen, dass du IMMER dein Fenster neu zeichnest sonst entstehen häßliche Schlieren, weil das Fenster eben nicht gelöscht wird. Bei OpenGL Ansichten wird dann normal aber auch der gesammte Inhalt neu gezeichnet weswegen das kein Problem sein sollte.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jul 28, 2005 12:43 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Apr 25, 2005 17:51
Beiträge: 464
erstmal danke

also ich kenns nur aus der MFC, da is OnPaint() ne Methode und die wird halt nur aufgerufen, wenn die Nachricht WM_PAINT ausgelöst wurde.
Mit dem verhindern des löschens denke ich, dass das mein Problem ist. Weil OpenGL zeichnet das Fenster schwarz. Wenn ich die Größe der Form so ändere das nur die Höhe aber nicht die Breite ändere(zum kleineren wie du geschrieben hast), dann wird das Panel grau.
Für das Panel habe ich kein OnPaint()-Event im Objektinspektor.

Das Resize hat ein Problem: es wird aufgerufen, bevor die Form richtig erstellt wurde. Wenn ich da einfach ein Neuzeichnen reinmach existieren noch garnicht die grafischen Objekete ... ergo Exception. Da müsste ich also außerhalb ne Statusvariable machen und das abtesten, wäre möglich will ich aber nur machen, wenn es nicht anders geht(globale Variable halt ^^)

Dein Befehl den du mir beschrieben hast, das kompiliert er zwar, aber irgendwie passiert der Effelkt trotzdem. Muss ich das wirklich auf das Panel anwenden, oder auf doch auf die ganze Form?
Oder gibts ne Möglichkeit in Delphi, es so wie in der MFC zu machen, wo ich jede Nachricht wirklich per Hand abfangen kann?


MfG Pellaeon


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jul 28, 2005 14:04 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Habe mal das Doppelpost gelöscht.

Noch mal um etwas klar zu stellen. Das EraseBackGround und OnPaint sind zwei unterschiedliche Sachen die aber im Endeffekt ziemlich zusammen hängen. Das normale Flackern entsteht dadurch, dass das Fenster kurz vor dem Zeichnen noch mal von Windows gelöscht wird. Das kannst du mit dem ControlStyle lösen. Das musst du auf die Komponente zuweisen auf der du Zeichnest. In deinem Falle also das Panel.

Resize: Ja. Das hatte ich vergessen. Da musst du eine Variable definieren die du nach dem erfolgreichen Initialisieren setzt. Diese prüfst du dann im OnResize des Panels ab. Ist sie gesetzt so setzt du deinen ViewPort und rufst Panel1.Repaint auf. Damit wird dein Panel neu gezeichnet. Aber BITTE benutz dafür keine globale Variable. Wir sind schließlich alle Objekt orientierte Programmierer. Du hast ein Formular in dem du einen Privaten bereich hast. Dort kannst du solche Variablen rein packen. Unter anderem auch die für deinen RC und DC. Der Vorteil ist so kannst du mehrere Instanzen deines Formulars anlegen und auch benutzen. Wenn du alles als globale Variablen machst geht das nicht. Dann würden die sich gegenseitig überschreiben. Denkt auch an meine Nerven wenn ich solche Codes zu Gesicht bekomme. ;-)
Ich glaube ich bin ein wenig vom Thema abgekommen.

OnPaint des Panels: Richtig das Standardpanel unterstützt so etwas nicht. Schau mal das hier. Das ist eine Komponente die ich vom Panel abgelitten habe. Der unterstützt dann auch OnPaint. In dem du dann zeichnen kannst. Du musst nur die dpk installieren und bei deinem Programm das Verzeichnis zu den Suchpfaden hinzufügen.

Messages kann man auch selber abfangen. Nur ist es dafr überhaupt nicht notweindig. Würde die Sache nur unnötig verkomplizieren. Und du kannst nur Messages von dem Formular abfangen. Das Panel wäre davon also vollständig unbeeindruckt. Versuch es also ohne hinzubekommen. Und das nur fürs Protokoll.
Code:
  1. type
  2.   TForm1 = class(TForm)
  3.     // Elemente
  4.   private
  5.     // Hier kannst du unter anderem deine Variablen für den DC, RC
  6.     // und fürs erfolgreiche Initialisieren reinhängen.
  7.     // Nur um es noch mal zu zeigen was ich vorhin meinte. <!-- s;-) --><img src=\"{SMILIES_PATH}/icon_wink.gif\" alt=\";-)\" title=\"Wink\" /><!-- s;-) -->
  8.   protected
  9.     procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  10.     procedure WMEraseBkgnd(var Message: TWMEraseBkgnd);
  11.       message WM_ERASEBKGND;
  12.   public
  13.     { Public-Deklarationen }
  14.   end;
  15.  
  16. implementation
  17.  
  18. procedure TForm1.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  19. begin
  20.  
  21. end;
  22.  
  23. procedure TForm1.WMPaint(var Message: TWMPaint);
  24. begin
  25.  
  26. end;

In Delphi Pro ist eine Hilfe eingebaut. Wenn du strg+space drückst erscheint die Codevervollständigung und wenn du dann WMPaint eintippst erscheint die entsprechende Message. Bei Return fügt er die Funktionsdeklaration ein.

Solltest du es nicht hinbekommen so schicke mir bitte mal deine Codes und ich schaue mir das mal an. Oder hänge sie hier ins Forum. Das würde auch noch gehen. Das ist besser als so auf die Entfernung zu raten was genau nicht so ganz funktioniert.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jul 28, 2005 18:33 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Apr 25, 2005 17:51
Beiträge: 464
so nochmal danke für die Infos :-)

Zitat:
die ich vom Panel abgelitten habe.
hergeLITTEN? wars so schlimm ;-) (kleiner Scherz konnt ich mir jetzt nicht verkneifen sorry^^)

und keine Angst ich, ich will deine Nerven nicht belasten, ich mag ja selber auch keine globalen Variablen, war an der Stelle ein denkfehler meinerseits, war irgendwie drauf aus das resize "in dem Panel" zu machen anstatt "in der Form " und da hätte ich ja kein Zugriff auf die Form-Variablen ... .

ich werd das auf jedenfall so machen :-) also nochma danke für die Hilfe


MfG Pellaeon


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jul 28, 2005 19:44 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Pellaeon hat geschrieben:
Zitat:
die ich vom Panel abgelitten habe.
hergeLITTEN? wars so schlimm ;-) (kleiner Scherz konnt ich mir jetzt nicht verkneifen sorry^^)

Och Mist...den wollt ich auch bringen. :mrgreen:

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jul 28, 2005 19:55 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Ihr wisst doch. Programm kann echt ne Qual sein. ;-)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jul 29, 2005 08:50 
Offline
DGL Member

Registriert: Mo Dez 20, 2004 08:58
Beiträge: 442
Wohnort: Mittweida (Sachsen)
Ausserdem ist doch 'abgelitten' der Imperfekt von 'ableiden' oder täusch ich mich da?

_________________
Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jul 29, 2005 13:14 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Apr 25, 2005 17:51
Beiträge: 464
was soll "ableiden" sein?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Nov 07, 2005 18:17 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Apr 25, 2005 17:51
Beiträge: 464
So ich wollt das nochmal pushen.
Kann ich denn nirgends nur das Neuzeichnen des Panels abstellen? Wäre wichtig.
Problem ist der Start: in der formShow wird was gezeichnet , das macht er auch, aber dann tut Delphi noch irgendetwas aufrufen und übernmalt das ganze wieder mit der Standardfarbe des Panels :(


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Nov 07, 2005 19:50 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Also wenn das Formular noch nicht sichtbar ist, dann kannst du so viel zeichnen wie du willst. Das wird nie auf dem Formular sichtbar sein. Das wird erst richtig gezeichnet, wenn das Fenster sichtbar ist. Und sobald ein neues es verdeckt ist der inhalt wieder weg. Du kannst immer nur lediglich auf das Zeichnen reagieren und es neu zeichnen.
Soll bedeuten, dass du ein Fenster immer neu zeichnen musst. Also ein mal zeichnen und dann dich darauf beruhen, dass es da ist gibt es nicht.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Nov 07, 2005 20:00 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Apr 25, 2005 17:51
Beiträge: 464
Wie bekome ich es dann hin, dass beim Start meine OpenGL-Grafik angezeigt wurd? Die OnPaint der Form ist ja überschrieben. Aber irgendwie legt sich halt das Panel beim Start doch drüber.
Kann man wie bei der MFC irgendwie abfangen(in einer Methode), wenn die Steuerelemente gezeichnet werden?
Oder wie ist in Delphi der Syntax für die Nachricht WM_CTLCOLOR? Hat bei mir bisher nicht funktioniert.
Aber das muss dich irgendwie gehen


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Nov 08, 2005 12:18 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Um so mehr du versucht das zu erklären um so weniger scheine ich zu verstehen worum es dir eigentlich genau geht.

Wenn du ein Formular hast und auf diesem mit der Methode OnPaint renderst, dann werden alle Komponenten deine OpenGL Ansicht verdecken.

Wenn du auf einem Panel zeichnen möchtest musst du logischerweise auch das OnPaint eines Panels benutzen. Da es das von Hause aus nicht hat musst du es halt selber hinzufügen. Und das geht nur indem du die Methode Paint einer abgelittenen Klasse überschreibst und darin dann ein Event aufrufst. Das sollte treffenderweise OnPaint heißen, da es ja auch genau das macht. Und wenn du das geschafft hast (oder siehe sie meine Komponente von oben) dann sollte das auch ohne Probleme funktionieren. Du musst aber auf jeden Fall auf das Paint / OnPaint / WM_PAINT der entsprechenden Komponente reagieren auf der du zeichnen möchtest.

PS: Du könntest auch auf ein Formular zeichnen und das OnPaint des Forms und des Panels benutzen um zu zeichnen. Macht zwar nicht wirklich viel Sinn aber gehen würde das auch. ;-)

PPS: Delphi verwaltet die Messages einer Komponente in einer Komponente selber und liefert lediglich Events nach außen. In der MFC musst du ja direkt die Messages bei den Komponenten abfangen. Das ist in Delphi ein wenig Objektorientierter. Dadurch ist es nicht unbedingt immer einfacher. Speziell wenn man etwas besonderes haben will eher nachteilig. Sonst aber sehr praktisch.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Nov 08, 2005 18:49 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Apr 25, 2005 17:51
Beiträge: 464
Hm also erstmal zur MFC. Du musst nicht die Messages abfangen, du KANNST, das ist ein großer Unterschied. Dort ist es viel bequemer Steuerelemente anzupassen. Einfach ableiten, messagemap deklarieren, gewünschte Nachrichten behandeln, den Rest macht die Elternklasse.

Dein Panel hab ich versucht einzubinden. Aber irgendwie hat das nicht geklappt. Kannst du das bitte genauer beschreiben? Ich wollts als Package reinholen, aber irgendwie hat die Dateiendung nicht gepasst.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Nov 08, 2005 18:53 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Apr 25, 2005 17:51
Beiträge: 464
ach ja und muss man wirklich jedes gewünschte Ereignis neu schreiben, auch die wo einem das verhalten der basisklasse ausreicht?


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 23 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: Google [Bot] und 3 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.010s | 16 Queries | GZIP : On ]