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???
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.
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.
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?
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:
type
TForm1 =class(TForm)
// Elemente
private
// Hier kannst du unter anderem deine Variablen für den DC, RC
// und fürs erfolgreiche Initialisieren reinhängen.
// Nur um es noch mal zu zeigen was ich vorhin meinte. <!-- s;-) --><img src=\"{SMILIES_PATH}/icon_wink.gif\" alt=\";-)\" title=\"Wink\" /><!-- s;-) -->
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.
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
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.
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
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.
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
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.
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.
Mitglieder in diesem Forum: 0 Mitglieder und 5 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.