Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi In einer Klasse Messages für alle Komponenten abfangen (https://www.delphipraxis.net/91463-einer-klasse-messages-fuer-alle-komponenten-abfangen.html)

LH_Freak 5. Mai 2007 08:51


In einer Klasse Messages für alle Komponenten abfangen
 
Hi hi, alle miteinander...

ich programmiere ja immer noch an der Skinkomponente für M.U.H Messenger (es macht Fortschritte ;-), kaum zu glauben aber wahr)...jetzt steh ich vor dem Problem, dass ich ja alle Komponenten überzeichnet aufs Formular zeichnen muss...das klappt bis jetzt ganz gut...allerdings will ich nicht jeden Redraw, HoverEffekt etc. durch ein MouseOver ermitteln. Das ruckelt dann schon alles etc.
Deswegen hab ich mir gedacht, ich könnte doch irgendwie die Messages, die sich aufs zeichnen beziehen von all den Komponenten auf dem Formular abfangen und dann das ganze zeichnen...allerdings steh ich grad auf dem Schlauch ob das überhaupt geht und wie das geht...ich hoffe mir kann da jemand helfen

MfG
LH_Freak

Ach ja...es wäre nett wenn mir jemand helfen könnte wie ich das löse, falls das mit den Messages nicht funktioniert...Danke :D

LH_Freak 6. Mai 2007 09:46

Re: In einer Klasse Messages für alle Komponenten abfangen
 
also ich denke mal, dass ich dafür Hooks verwenden muss...hat dazu jemand ein gutes Tutorial? Ich hab bisher nur eins für C++ gefunden...allerdings wäre dass sowas was ich will...ich werde mal schaun ob ich damit zurecht komme...

sirius 6. Mai 2007 09:57

Re: In einer Klasse Messages für alle Komponenten abfangen
 
Schau mal da!

Manne 6. Mai 2007 09:58

Re: In einer Klasse Messages für alle Komponenten abfangen
 
Hi,

schau dir mal den Windows XP Theme Manager von Mike Lischke an. [ Link ]
Er zeichnet das den XP Style über jedes Control.

Manne

TStringlist 6. Mai 2007 18:38

Re: In einer Klasse Messages für alle Komponenten abfangen
 
Eventuell langt aber auch schon die Benutzung eines einfachen "Application.OnMessage".

LH_Freak 13. Mai 2007 09:48

Re: In einer Klasse Messages für alle Komponenten abfangen
 
Ok, also erstmal danke...
im Moment versuche ich die WindowProcs der Komponenten zu überschreiben...das funktioniert auch gut...
allerdings weiß ich jetzt nicht wirklich welche Messages ich alle abfangen muss :oops:
Was löst z.B. bei einem Edit den Redraw aus wenn ich tippe? WM_TEXTCHANGE hat nicht funktioniert...hmhm...gibts da irgendwas wo man bezüglich dem nachschauen kann?

Apollonius 13. Mai 2007 09:58

Re: In einer Klasse Messages für alle Komponenten abfangen
 
Ich vermute mal, dass das eigentliche Neuzeichnen von WM_PAINT ausgelöst wird.

SirThornberry 13. Mai 2007 10:28

Re: In einer Klasse Messages für alle Komponenten abfangen
 
du musst auf wm_paint und wm_erasebkrnd (oder wie man das schreibt) mindestens eingehen.

LH_Freak 13. Mai 2007 17:12

Re: In einer Klasse Messages für alle Komponenten abfangen
 
ya...das mach ich ja...aber ich muss ja auch drauf reagieren wenn das Eingabefeld den Fokus bekommt, wenn man text ändert...da bekommt das Edit kein WM_PAINT...so hab ichs zumindest festgestellt...

negaH 14. Mai 2007 10:26

Re: In einer Klasse Messages für alle Komponenten abfangen
 
Schau mal, was machen alle deine Komponenten ?

Sie bekommen unterschiedlichste Messages, speichern intern unterschiedlichste Staties und stellen dies auf dem Bildschirm dar.
Logische Konsequenz: möchtest du per Hooks, egal ob Windowsbotschaften oder die vielen Delphi-VCL-Botschaften, alles abfangen und selber machen, dann wäre es besser deine eigenen Komponenten zu bauen. Denn der Aufwand ist höher mit den Hooks. Der Tipp mit den Themes ist schon richtig, denn das ist der präferierte Weg. Mit Hooks wirst du immer nur gezielte und einfache Manipulationen bewerkstelligen können und hast niemals den kompletten Zugriff auf alle internen Staties deiner Komponenten. Das was du versuchst ist so als ob du das Verhalten aller Menschen kontrollieren möchtest indem du alles von Aussen kontrollierst, also Wind,Wetter,Fernsehen,Nahrung etc.pp. ohne das du die innersten Gedanken der Menschen direkt beeinflussen kannst.

Mit Hooks wirst du auf lang oder kurz an einem Punkt ankommen bei dem du besser über alle Komponenten, die du beeinflussen möchtest, bescheid weist als der Programmierer der diese Komponenten erzeugt hat. Ergo: dann bist du schneller wenn du all diese Komponenten durch eigene Entwicklungen ersetzt. Einzigster Ausweg ist die Benutzung eines APIs das exakt diese Veränderungen vorsieht, und das sind die Themes.

Gruß Hagen

LH_Freak 15. Mai 2007 15:36

Re: In einer Klasse Messages für alle Komponenten abfangen
 
ich probier doch schon garnicht mehr mit Hooks...hab ich doch oben schon geschrieben :mrgreen:
Zitat:

im Moment versuche ich die WindowProcs der Komponenten zu überschreiben...das funktioniert auch gut...
das ist auch die Möglichkeit die in dem ThemeManager benutzt wird. Allerdings suche ich sowas wie eine Referenz wo ich nachschaun kann was die Controls alles für Messages bekommen...daran häng ich gerade ^^

Der_Unwissende 15. Mai 2007 16:36

Re: In einer Klasse Messages für alle Komponenten abfangen
 
Zitat:

Zitat von negaH
Mit Hooks wirst du auf lang oder kurz an einem Punkt ankommen bei dem du besser über alle Komponenten, die du beeinflussen möchtest, bescheid weist als der Programmierer der diese Komponenten erzeugt hat. Ergo: dann bist du schneller wenn du all diese Komponenten durch eigene Entwicklungen ersetzt.

Aber mit Hooks weißt Du mehr über die Komponenten als wenn Du diese selbst schreibst :)

negaH 15. Mai 2007 21:15

Re: In einer Klasse Messages für alle Komponenten abfangen
 
Zitat:

Aber mit Hooks weißt Du mehr über die Komponenten als wenn Du diese selbst schreibst
Falsch. Ein Hook ist immer ein nachträgliches Instrument das nachträglich eine Funktionalität umbiegen möchte. Das bedeutet auch das als erster Schritt erstmal eine umbiegbare Fuktionalität vorhanden sein muß damit man überhaupt was Hooken kann. Der Komponentenentwickler ist also zeitlich und informell immer einen Schritt vorraus, ohne Kompoentenentwickler gibts keinen Hook-Entwickler. Denoch benötigt man das komplette Wissen eines Komponentenentwicklers wenn man einen Hook sauber platzierene möchte. Und das bestätigt sich auch, fragt doch der Threadersteller exakt nach diesem Wissen ->

Zitat:

Allerdings suche ich sowas wie eine Referenz wo ich nachschaun kann was die Controls alles für Messages bekommen...daran häng ich gerade
Die Antwort ist sehr einfach ;) Die einzigste Referenz der man trauen kann sind die Sourcen aller Komponenten selber. Verschaffe dir also einen fundierten Einblick in die Funktonsweise aller Komponeten die du hooken möchtest dann hast du die Möglichkeit durch Messages circa 40% des Verhaltens der Komponenten zu verändern. Die restlichen 60% wirst du über Hooks nicht verändern können da es statische und geschützte Programsequenzen sind die intern eigene Staties benutzten die alle per Hooks nichts erreichbar sind. Hooks im herkömlichen Sinne benutzen die Messageabarbeitung der Komponenten und Fenster. Bei simplen Windows-Fenster ist das eine feine Sache bei der VCL aber nicht mehr. Viele Komponenten benutzen garkein Windowshandle mehr -> TControl->TGraphicControl sondern benutzen ein separates Messagekonzeopt nur typisch für Delphi VCL Controls. Zb. Nachrichten die oberhabl von cm_Base liegen -> cm_Activate, cm_Deactive, cm_Paint usw. usw. Um das alles mitzubekommen MUSST du die WindowProc der VCL-Controls hooken und NICHT das Fensterhandle des Parent WinControls -> zb. TPanel.Handle

Du wirst also nicht umhinkommen und dir das Wissen wie die komplette VCL intern arbeitet anzueignen. Alles andere wird ansonsten ein Blindflug, ein Trial&Error und aufgrund der hohen Komplexität der VCL Komponenten, niemals zu einem Erfolg führen.

Einen guten Abriß über die Arbeitsweise der VCL wird man wohl eher nicht finden. Mein "Abriß" in meinem Hirn besteht aus dem Wissen von 15 Jahren in denen ich als Komponentenentwickler mit der VCL arbeite.

Suche dir am besten Sourcen die fast das manchen was du dir wünscht, und dann studiere sie.

Gruß Hagen

negaH 15. Mai 2007 21:21

Re: In einer Klasse Messages für alle Komponenten abfangen
 
Zitat:

ich probier doch schon garnicht mehr mit Hooks...hab ich doch oben schon geschrieben
Du biegst die WindowPocs der Komponenten um. Also aktuellen Wert von Control.WindowProc in FSaveWindowProc. Dann Control.WindowProc auf MeineWindowProc umbsetzen und in MeineWindowProc reagierst du auf die Messages und/oder leitest sie an FSaveWindowProc weiter. Richtig ?

DAS IST ein Hook.

Gruß Hagen

Der_Unwissende 16. Mai 2007 07:58

Re: In einer Klasse Messages für alle Komponenten abfangen
 
Zitat:

Zitat von negaH
Zitat:

Aber mit Hooks weißt Du mehr über die Komponenten als wenn Du diese selbst schreibst
Falsch.

Sorry, nur den falschen Smiley benutzt, wollte eigentlich nur auf die etwas lustige Aussage Deines vorrigen Beitrages hinweisen

Zitat:

Zitat von negaH
Mit Hooks wirst du auf lang oder kurz an einem Punkt ankommen bei dem du besser über alle Komponenten, die du beeinflussen möchtest, bescheid weist als der Programmierer der diese Komponenten erzeugt hat.

Wenn man jetzt selbst die Komponenten erzeugt hat, dann dürfte wohl gelten, dass man mehr durch Hooks über die Komponenten weiß als der Programmierer, der sie schrieb (ergo man selbst). :mrgreen: (ein wenig paradox)

negaH 16. Mai 2007 09:31

Re: In einer Klasse Messages für alle Komponenten abfangen
 
Nein nicht ganz.

Betrachte die Summe aller Komponenten die man hooken möchte als die Arbeit mehrer Programmierer. Man muß also alles das Wissen was eine Gruppe von Programmierern verzapft haben. Wenn man nun selber Komponenten schreibt dann werden das auch nur eine Teilmenge von denen sein die man hooken müsste, ergo: nicht mehr ganz so paradox ;)

Aber das wird zu philosophisch.

Die Kernaussage bleibt besteht:

Hooken und solche Tricks bedingen das der Programmierer ein sehr teifgründiges Wissen besitzen muß. Dieses Wissen wird mindestens so tief sein wie das eines erfahrenen Komponentenentwickler. Ist dem nicht so so wird man mit Hooks meistens mehr kaputt machen als reparieren. Die Frage nach mehr zusammengefassten Backgroundwissen ist also korrekt, nur habe ich eben keine Antwort darauf wo man solche fundierten Sachen nachlesen könnte, als im Source selber.

Schau mal, wer kann sich heute als Komponetenentwickler bezeichnen ?
All diejenigen die selber Komponenten schreiben, logisch. Da diese Entwickler die meiste Zeit nur Komponeten auf eine fertige konstruierte Basis aus Komponeten draufsetzten, wie zb. Propertyeditoren für die IDE usw. usw. heist das auch das ein Komponentenentwickler heutzutage nicht zwangsläufig darüber bescheid wissen muß was er da eigentlich benutzt.
Das ist ja das schöne an der Arbeitsweise der OOP, bzw. im Grunde exakt ihr Ziel.

Ein Hook greift aber ganz unten, im innersten in das Prozessing einer oder sogar einer ganzen Gruppe von Komponenten ein. Der Hook bekommt auch innere Staties mit die man aussen der Schnittstelle Komponente garnicht ansehen kann. Denoch ist es wiederum so das ein Hook niemals komplett alles über die gehookte Komponete wissen kann, das diese eben private Felder/Staties/Methoden benutzt die nicht über die WindowProc laufen.

Egal: über die Komponeten der VCL gut bescheid zu wissen kann nie schaden. Borland liefert die Sourcen mit, ergo kann man darin stöbern, und ich habe es auch so gelernt. Nur einen Abriß der fundiert ist wird man meines erachtens so nicht finden, das wäre ein dickes Buch.

Grundsätzlich muß er fast alle Messages berücksichtigen, da sie fast alle das Ziel haben einen internen Status, zb. Text, im GUI darzustellen/sie zu editieren und auch das darzustellen, und exakt das möchte er verändern. Es gibt nur sehr wenige Windowsbotschaften die redundant sind. Zb. wm_Size,wm_Move,wm_Activate zu wm_WindowPosChanged/wm_WindowPosChanging. Die in der VCL eingeführten Messages, die nichts mehr mit Windows zu tuen haben, sind die cm_XXXX Messages. Deren Arbeitsweise kann sich leicht zu den Windowsbotschaften unterscheiden und sind in ihrer Menge genauso groß wie die Windows Botschaften. Deren logischer Aufbau ist dabei intuitiver und logischer konstruiert als die Windowsbotschaften. Sehr oft sind es gemappte Windowsbotschaften wie wm_SetFocus zu cm_Activate/cm_Deactivate die eine Nachricht an ein TWinControl benutzen das dann diese Nachricht als cm_XXXX Nachricht broadcastet an seine untergeordneten TControl's, die ja kein eigenes Fensterhandle besitzen.

In vielen Fällen könnten also die cm_XXXX Messages ausreichend sein sie zu hooken und darauf zu reagieren, aber eben nicht immer. Die Deklaration der cm_XXXX Messages findet man in Unit Controls.pas.

Zb. die wm_Paint Messages zu Hooken ist gefährlich. Macht man dort einen Fehler, zb. die Fragestelleung wann muß man den DC->Devicecontext der in Message.wParam übergeben wurde, wenn er übergeben wurde, freigeben oder nicht, kann Speicherleaks im GDI verursachen. Ein Fehler dabei und man hat in Millisekunden oder erst Stunden die GDI Resourcen bei den DC's überschritten, für's gesammte System wohlgemerkt. Danach funktioniert garnichts mehr, sogar der Taskmanager wird nicht mehr richtig dargestellt.

Bei Windowscontrols ist es durchaus üblich das diese auf dem Bildschirm zeichnen auch inerhalb anderer Nachrichten. Ganz besonders schlim wurde dies bei den normalen TForm Fenstern, also der Titelzeile eines Windows, gemacht. Klickt man mit der Maus auf den Schließenbutton so wird wm_NCLButtonDown gesendet. Windows beginnt nun eine Schleife die erst zurück kehrt wenn der Button wieder losgelassen wird. Innerhalb dieser Schleife werden die Fensterbuttons und Titelzeile neu gezeichnet, unabhängig von wm_Paint und wm_NCPaint. Ein Hook muß also wm_NCLButtonDown abfangen und dann ALLES selber machen. Nun ist es aber so das sich gerade der Code dieser Schleife, auf den wir keinen Einfluß haben, mit jeder neuen Windowsversion ständig veränderte und es kein API zur Beeinflussung dafür gibt.
Das zeigt uns das
1.) es schon eine Kunst ist einen 4'ten Button in der Titelzeile einzublenden
2.) warum so viele Tools die so einen Button einblenden fast nie ganz sauber arbeiten, besonders bei neuen Windows Versionen versagen sie.
Diese Problematik ist ein Beispiel für die Anwendung von Hooks, deren Komplexität und eben auch der "Gefahren" dabei. Ist natürlich ein extremes Beispiel.

Gruß Hagen

LH_Freak 16. Mai 2007 18:48

Re: In einer Klasse Messages für alle Komponenten abfangen
 
Naja, aber ich arbeite ja nie mit DCs ^^...ich nehm mir Left, Top, Width und Height und zeichne mein PNG Bild auf das Bild vom Formular...also ich reagiere nur auf die Messages wie WM_PAINT usw.
Kann man da auch viel kaputt machen?

negaH 16. Mai 2007 22:58

Re: In einer Klasse Messages für alle Komponenten abfangen
 
Hm, aus deiner Fragestellung am Threadanfang konnte man schließen das du das Styling aller Controls die auf deinem Form liegen verändern möchtest. Deshalb auch die Frage nach den Hooks etc.pp.

So wie es aber jetzt scheint möchtest du nur eine Bitmap in deine Form zeichnen, quasi als Hintergrundbild. Das ist natürlich was ganz anderes und geht ganz ohne Hooks oder manuellem abfangen der wm_Paint Messages. Nimm ein TImage, setze es auf dein TForm mit alClient und in der Property Picture lädst du deine Bitmap.


Gruß Hagen

LH_Freak 17. Mai 2007 21:09

Re: In einer Klasse Messages für alle Komponenten abfangen
 
jein...also ich habe ein LayeredWindow. per UpdateLayeredWindow zeige ich ein PNG an. Dadurch sind natürlich alle VCL Komponenten verschwunden. Deshalb möchte ich diese auf das Bild der Form zeichnen damit ich die auch beim LayeredWindow sehe...Aber wenn ich nur den WM_Paint abfange funktioniert das ja auch nicht. Weil bei nem Eingabefeld z.B. wird ja kein WM_PAINT geschickt wenn getippt wird (zumindest wars bei mir nicht so o_O)...


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:27 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz