PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C#: Synchronisierung mit Events


Jesus
2006-01-23, 11:15:19
Hallo!

Ich versuche im Moment zwei grafische Objekte in zwei unabhängigen MDI Forms über Events zu synchronisieren, genauer gesagt ihr scrolling. Leider funktioniert das nur sehr zäh. Wenn ich Objekt 1 scrolle dann wird Objekt 2 nur in "echtzeit" mitgescrollt wenn ich das sehr langsam mache. Wenn ichs schneller mache dann aktualisiert sich objekt 2 nur wenn ich objekt 1 wieder stoppe.

Weiss jemand ne Methode um sowas quasi in Echtzeit zu machen?

zeckensack
2006-01-23, 16:44:56
Willkommen auf Windows.

Du könntest mal versuchen auch das "aktive" Fenster mit einem Event zu entkoppeln.
Dh beide Viewports warten auf jeweils einen Event, um sich neu zu zeichnen. Du reagierst auf "ziehen" (oder sonstige Eingaben, die die Ansicht verändern) mit dem Setzen beider Events. Das müsste besser funktionieren.

Vielleicht solltest du noch ein paar Worte zu deiner Architektur fallen lassen. Hast du separate Threads pro MDI-Fenster, oder einen für alle?

Jesus
2006-01-23, 19:00:51
Willkommen auf Windows.

Du könntest mal versuchen auch das "aktive" Fenster mit einem Event zu entkoppeln.
Dh beide Viewports warten auf jeweils einen Event, um sich neu zu zeichnen. Du reagierst auf "ziehen" (oder sonstige Eingaben, die die Ansicht verändern) mit dem Setzen beider Events. Das müsste besser funktionieren.

Vielleicht solltest du noch ein paar Worte zu deiner Architektur fallen lassen. Hast du separate Threads pro MDI-Fenster, oder einen für alle?

Moin, erstmal Danke!

Ich habe eine MDI Anwendung in C# die 2 (oder mehr) gleichartige MDI Childs haben kann, die beide ne Grafik anzeigen.

In der Paint() vom einen ruf ich jetzt im Parent jeweils die Eventhandler Funktion auf die dann im jeweils anderen MdiChild ein invalidate macht, wenn ich sie mit der Maus "ziehe" und die Koordinaten angleicht.

Leider sehr lahm alles.

Mit Threads hab ich nix am hut, einfach nen neues Objekt von der jeweiligen MDI form erstellt ( Viewer view1= new Viewer()...)

zeckensack
2006-01-24, 05:56:18
Moin, erstmal Danke!

Ich habe eine MDI Anwendung in C# die 2 (oder mehr) gleichartige MDI Childs haben kann, die beide ne Grafik anzeigen.

In der Paint() vom einen ruf ich jetzt im Parent jeweils die Eventhandler Funktion auf die dann im jeweils anderen MdiChild ein invalidate macht, wenn ich sie mit der Maus "ziehe" und die Koordinaten angleicht.Aha!
Gegenvorschlag:
Rufe InvalidateRect für beide MDI-Fenster auf wenn du deinen Maus-Input oder so behandelst. Nicht als Reaktion auf WM_PAINT! Dein Paint-Handler selbst sollte wirklich nur neu zeichnen. Und deine Applikation sollte nie Paint-Messages an sich selbst senden, sondern immer den indirekten Weg über InvalidateRect gehen.

Dann sollte es eigentlich flutschen. Das "Problem" ist dass alle Arten von Messages sich stapeln und dir deine Message Queue verstopfen können. Wenn du zB 20 Mouse-Messages pro Sekunde erhältst und jedesmal den Paint-Handler aufrufst, der aber 50ms braucht, dann ist das System damit mehr als ausgelastet und die Pflichten ggü anderen Fenstern werden dann vernachlässigt.

WM_PAINT-Nachrichten dagegen laufen nicht auf. Wenn schon eine WM_PAINT-Nachricht in der Message Queue ist, und es kommt eine neue, wird die neue einfach verworfen. Es stapelt sich nichts, und Input bekommt bei der Abarbeitung Priorität.
The system sends a WM_PAINT message to a window whenever its update region is not empty and there are no other messages in the application queue for that window.
Quelle (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_7ano.asp)

In deinem speziellen Fall wird das zweite MDI-Fenster halt so lange nicht neu gezeichnet, wie das System mit Input verstopft ist. InvalidateRect zeichnet ja nicht sofort neu, sondern erst wenn das System wieder Zeit hat.
Dadurch dass du außerhalb des Paint-Handlers für beide MDIs InvalidateRect aufrufst, bekommen beide eine faire Chance sich neu zu zeichnen. Keines der beiden Fenster hat dann eine übertriebene Priorität.

HTH.

grakaman
2006-01-24, 09:07:08
Mit .NET 1.1 wahrscheinlich nur über PInvoke:

http://free-blog-site.com/jason_2004/archive/2004/04/26/7951.aspx

Wie das mit .NET 2.0 aussieht, weiß ich nicht.

grakaman
2006-01-27, 18:54:08
Jesus, hast du das hinbekommen? Ich habe das nach dem Bsp. im Link jetzt eben mal schnell ausprobiert (aber bei einer Form, nicht Pabel) und das funktioniert. Wenn du willst, kann ich den Code hier posten.