![]() |
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 |
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...
|
Re: In einer Klasse Messages für alle Komponenten abfangen
|
Re: In einer Klasse Messages für alle Komponenten abfangen
Hi,
schau dir mal den Windows XP Theme Manager von Mike Lischke an. [ ![]() Er zeichnet das den XP Style über jedes Control. Manne |
Re: In einer Klasse Messages für alle Komponenten abfangen
Eventuell langt aber auch schon die Benutzung eines einfachen "Application.OnMessage".
|
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? |
Re: In einer Klasse Messages für alle Komponenten abfangen
Ich vermute mal, dass das eigentliche Neuzeichnen von WM_PAINT ausgelöst wird.
|
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.
|
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...
|
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 |
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:
|
Re: In einer Klasse Messages für alle Komponenten abfangen
Zitat:
|
Re: In einer Klasse Messages für alle Komponenten abfangen
Zitat:
Zitat:
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 |
Re: In einer Klasse Messages für alle Komponenten abfangen
Zitat:
DAS IST ein Hook. Gruß Hagen |
Re: In einer Klasse Messages für alle Komponenten abfangen
Zitat:
Zitat:
|
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 |
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? |
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 |
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