Seite 1 von 3

Partielles Update eines ImageGadgets?

Verfasst: 17.03.2008 00:08
von Kurzer
Hallo zusammen,

und wieder eine Frage (heute ist's echt schlimm) :)
Gegeben ist ein Imagegadget in einem Window. Das Image selbst verändere ich zeilenweise direkt im Speicher (funktioniert ohne Probleme).
Damit nun das Imagegadget nach jeder geänderten Zeile das (veränderte) Image anzeigt, muß ich
>>SetGadgetState(#ImageGadget_Modified, ImageID(#ImageID_Modified))
aufrufen, damit 'das neue' Image wieder in das Gadget geblittet wird.

Das ganze dauert ziemlich lange, wenn ich es für jede Zeile aufrufe (je nach Bildhöhe sind's dann x Aufrufe). Gibt es eine Möglichkeit, daß ich das ImageGadget zeilenweise aktualisieren kann - also so, daß nur die gerade veränderte Zeile des Images in das ImageGadget geblittet wird?

Edit: Ein einfacher Hinweis auf die richtige API Funktion oder Message reicht schon.

Verfasst: 17.03.2008 00:51
von hardfalcon
Warum aktualisierst du das Gadget nicht erst, nachdem du alle Zeilen draufgeblittet hast? :?

Verfasst: 17.03.2008 00:57
von Kurzer
Weil das je nach Komplexität der Bildmanipulation und Leistungsschwäche des Rechners länger dauert.
Ich könnte nen Fortschrittsbalken einbauen, aber es interessiert mich ehrlich gesagt auch einfach, ob sowas machbar ist.

Jetzt weiß ich auch warum Plot auf ein ImageGadget so sch$%$ langsam ist. Der macht vermutlich nach jedem Plot einen SetGadgetState(). Das Pixelweise kopieren eines Bilds (im Imagegadget) auf ein anderes ist mit Point() und Plot() unerträglich langsam.

Verfasst: 17.03.2008 12:44
von milan1612
Vielleicht InvalidateRect_()?

Verfasst: 17.03.2008 23:58
von Kurzer
InvalidateRect_ funktioniert soweit...
Hier mal der Teil, den ich nach jeder kopierten Bildzeile ausführe:

Code: Alles auswählen

If ProgramSettings\Preview And i % 1 = 0
  IvRect\left = 0
  IvRect\top = i
  IvRect\right = ImageSettings_Dest\dsBitmap\bmWidth
  IvRect\bottom = i+1
  InvalidateRect_(GadgetID(#ImageGadget_Dest), @IvRect, #True)
EndIf
... aber die augelösten WM_PAINT Messages werden leider erst ausgeführt, wenn die Berechnungsschleife komplett durchgelaufen ist.

In der Praxis sieht das so aus, daß ich auf "GO" klicke, dann passiert visuell gar nichts - das Destination Image bleibt schwarz. In der Zeit kopiert die Procedure das Source Image auf das Destination Image und ruft fleissig nach jeder kopierten Zeile InvalideRect_ auf).. und wenn alles fertig ist, dann "whooosh" wird das Destination-ImageGadget "scheinbar" auf einen Schlag gezeichnet.

Wenn ich statt InvalidateRect_ SetGadgetState() nehme, dann wird das Destination Image Zeile für Zeile schon während des kopierens geupdatet - nur kann man dann nebenherlaufen.

Wie kann ich dem Multitasking nach jeder Zeile genug zeit lassen, damit das WM_PAINT ausgeführt wird?

Verfasst: 18.03.2008 00:02
von hardfalcon
Vermutlich gar nicht, zumindest nicht ohne gewaltige Performance-Einbußen. Es hat schon seine Gründe, dass man einige Gadgets vor dem Befüllen ausblendet... :allright:

Verfasst: 18.03.2008 00:09
von Kaeru Gaman
probier mal pro zeile ein einziges mal WindowEvent() auszuführen....

Verfasst: 18.03.2008 00:15
von Kurzer
Jo, das hat zur Folge, daß die Hälfte der WM_PAINTs weggeschluckt werden.
Von daher invalidated/redrawed er jetzt nur noch die Hälfte des Images. :wink:

Verfasst: 18.03.2008 00:19
von Kaeru Gaman
hm.... aber normalerweise führst du eines aus? also jetzt zwei?
(weil nur die hälfte auftaucht...)
...war halt mein erster gedanke, weil bei PB eben die Events weitergereicht werden müssen, is ja nicht OOP.
von daher dachte ich dran, eben einen WindowEvent()-Aufruf pro Invalidate auszuführen...

Verfasst: 18.03.2008 19:16
von PMV
Kurzer hat geschrieben:Wie kann ich dem Multitasking nach jeder Zeile genug zeit lassen, damit das WM_PAINT ausgeführt wird?
In (Wait)WindowEvent() werden sämtliche Windowsnachrichten
verarbeitet, ohne wird also auch kein WM_PAINT durch geführt. Du hast ja
während des Zeichnens ein Fenster offen, läuft das in einem eigenen
Thread, so das unabhängig vom Zeichnen ein (Wait)WindowEvent()
aufgerufen wird? Oder wie hast du das gelöst?

MFG PMV