Seite 2 von 2

Verfasst: 25.03.2008 19:51
von Kurzer
Würde gern wissen, ob es richtig ist, daß ich mich bei der Bearbeitung der #WM_PAINT Message innerhalb eines Callbacks auch um die Restaurierung des Festerhintergrunds kümmern muß.

Erst zeichnete ich im #WM_PAINT nur die beiden Bilder in dem Preview-Window neu.
Das hatte aber zur Folge, daß die Zwischenräume während des Verschiebens des Fensters nicht refresched wurden (erst, wenn ich später mit nem anderen Window drüberging). Dabei kam dann u.U. sowas raus, wie in dem vorletzten Screenshot.
Nu geh ich her und zeichen auch die Zwischenräume selbst neu (im letzten Screenshoot durch farbige BOXen angedeutet).
F1: Ist das so gewollt von Windows?

Dann fiel mir auf, daß die Ermittlung der Hintergrundfarbe des Fensters mit GetSysColor_(#COLOR_WINDOW) die Farbe weiß zurückliefert, obwohl der Fensterhintergrund grau ist.
F2: Liegt das evtl. an PureBasic, daß es das Fenster mit einer anderen Hintergrundfarbe geöffnet hat?

Die Situation hier ist die, daß ich mir einige Dinge aus C-sourcecodes abgucke und sie in PB verwenden möchte. Evtl. liegt das Problem ja auch daran. In C wird ein Fenster ja ganz anders geöffnet als in PB. Ich weiß nicht ob PBs OpenWindow() den gleichen Code erzeugt, wie ein C Äquivalent.

Verfasst: 25.03.2008 21:43
von Fluid Byte
F1: Ist das so gewollt von Windows?
Ja, du bist verantwortlich für den gesamten Fensterinhalt. Du kannst aber das Aktualisieren der Zwischenräume umgehen in dem eine geclippte DC benutzt, sprich ein Fenster mit passender Größe wie z. B. ein ImageGadget().
F2: Liegt das evtl. an PureBasic, daß es das Fenster mit einer anderen Hintergrundfarbe geöffnet hat?
Nein, das ist korrekt so. Mit #COLOR_WINDOW bekommst du den Wert für den Hintergrund von Fenstern bzw. dessen Controls. Wenn du einen Ordner öffnest ist die Hintergrund Farbe (soweit nicht in "Anzeige" geändert) standardmäßig auch weiß. Die Farbe die du suchst bekommst du mit #COLOR_3DFACE.

Verfasst: 25.03.2008 21:58
von NicTheQuick
Du kannst doch auch 'InvalidateRect_()' einen rechteckigen Bereich
übergeben, der refresht werden soll. Dann übergibst du da eben alle
Bereiche, die zwischen deinen Bildern liegen. Also die, die da zum Test farbig
gemacht hast.

Verfasst: 25.03.2008 22:05
von scholly
Fluid Byte hat geschrieben: Die Farbe die du suchst bekommst du mit #COLOR_3DFACE.
Habe ich das jetzt richtig verstanden:

Code: Alles auswählen

win_bg = GetSysColor_(#COLOR_3DFACE)
ist (unter Windows) ein schnellerer, vollständiger Ersatz für

Code: Alles auswählen

 StartDrawing(WindowOutput(0))
   win_bg = Point(1,1)
 StopDrawing()
Und auch sicherer, weil ein verdecktes (1,1) keine Fehlinfo ermittelt?

:allright: Mr. Api :lol:

Verfasst: 25.03.2008 22:32
von Fluid Byte
NicTheQuick hat geschrieben:Du kannst doch auch 'InvalidateRect_()' einen rechteckigen Bereich
übergeben, der refresht werden soll. Dann übergibst du da eben alle
Bereiche, die zwischen deinen Bildern liegen. Also die, die da zum Test farbig
gemacht hast.
Natürlich gibt es diverse Möglichkeiten nur bestimmte Breiche zu refreshen ist aber unüblich bzw. umständlich hier. Es einfacher und eleganter eine eigene geclippte DC mittels eines seperaten Fensters zu erstellen. Warum gibts wohl ein ImageGadget()? Bild

Verfasst: 25.03.2008 23:09
von Kurzer
Ich hatte erst zwei Imagegadgets für die beiden Bilder, aber dann gab es (für mich) Probleme, weil die das Image nicht skalieren können. Daher bin ich auf DrawImage direkt ins Fenster umgestiegen.
http://www.purebasic.fr/german/viewtopi ... 759#191759

Aber mittlerweile bin ich im Bereich API zu StretchBlt() vorgedrungen und ich sehe, man könnte in der Tat wieder zwei Imagegadgets als Art Container nutzen um dort die Images mittles API (StretchBlt) innerhalb der #WM_Paint reinwuppen. Ich denke, daß Du das meinst.
Und es ist sicher, den Rest des Windows refreshed Windows selbst (auch während des verschiebens)?

Verfasst: 25.03.2008 23:14
von edel
Versuch mal folgende Variante :

Code: Alles auswählen

Global oldProc

Procedure c(h,m,w,p)
   
   result = CallWindowProc_(oldProc,h,m,w,p)
   
   If m = #WM_PAINT   	
      StartDrawing(WindowOutput(0))
         Box(0,0,300,300,$5F8EA0)
      StopDrawing() 
      ProcedureReturn result    
   EndIf
   
   ProcedureReturn result
EndProcedure


h = OpenWindow(0,0,0,300,300,"")
oldProc = SetWindowLong_(h,#GWL_WNDPROC,@c())

Repeat
   e = WaitWindowEvent()
Until e = 16

Verfasst: 26.03.2008 00:14
von Kurzer
Danke für die Mühe, Edel, leider bringt das auch keien Abhilfe. Aber ich merke gerade, daß das Problem eh hausgemacht ist.

Das Fenster ist erst groß mit großen Images darin und wird dann einfach nur auf die Hälfte verkleinert. Logisch, daß da die Reste von den großen Images an den Rändern kleben, wenn ich die vor dem Verkleinern des Fensters nicht lösche. Sorry für den Aufstand... :oops:
Nu lösche ich das Fenster kompett mit der (richtigen) Hintergrundfarbe (Danke Fluid Byte), resize dann und zeichne die Images neu.
Das flackert zwar einmal beim resizen kurz, aber das ist zu verschmerzen.
WM_PAINT im Callback war irgendwie die falsche Stelle, an der ich rumgedoktort habe.

Verfasst: 26.03.2008 11:24
von Fluid Byte
Alles schicki lacki jetzt oder wat?

Verfasst: 27.03.2008 00:26
von Kurzer
Jupp, da ich durch den CallBack ja selbst für das gesamte Fenster verantwortlich bin, sollte die jetzige Lösung richtig sein. :allright: