Seite 1 von 2

kurzfristig Repaint bei Gadget verhindern

Verfasst: 20.08.2012 11:26
von Bisonte
Hallo.

Wie kann ich (auch per WinApi) kurzfristig das Repaint Event ausschalten ?

Es geht darum, ein Window per AnimateWindow_() ein/auszublenden, auf dem ein Canvas ist,
Allerdings flackert das Canvas oft während der Animation.

Daher wäre jetzt meine Idee, vor der Animation das "Repaint" abschalten und danach wieder einschalten...

Hier der Code, um den es sich dreht :

Code: Alles auswählen

Enumeration 1 ; Windows
  #MainWin
EndEnumeration
Enumeration 1
  #MCanvas
EndEnumeration

Procedure DrawMainCanvas()
  
  If StartDrawing(CanvasOutput(#MCanvas))
    DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_Gradient)
    BackColor( $7a7a7a ) : FrontColor( $303030 )
    LinearGradient(0,0,0,OutputHeight())
    Box(0, 0, OutputWidth(), OutputHeight(), 0)    
    DrawingMode(#PB_2DDrawing_Default)
    Line(0, OutputHeight()-1, OutputWidth(), 1, #Black)
    StopDrawing()
  EndIf
    
EndProcedure

OpenWindow(#MainWin, 0, 0, GetSystemMetrics_(#SM_CXSCREEN), 42, "TestWindow", #PB_Window_BorderLess|#PB_Window_Invisible)
CanvasGadget(#MCanvas, 0,0,WindowWidth(#MainWin),WindowHeight(#MainWin))
DrawMainCanvas()
WindowState = #False
Repeat
  Event = WaitWindowEvent(25)
  mx = DesktopMouseX() : my = DesktopMouseY()
  If my <= 0 And WindowState = #False And TimerStart = #False
    TimerStart = #True
    AddWindowTimer(#MainWin, 10, 500)
  Else
    WinRect.RECT
    GetWindowRect_(WindowID(#MainWin), @WinRect)
    If my > WinRect\bottom
      AnimateWindow_(WindowID(#MainWin), 150, #AW_HIDE|#AW_VER_NEGATIVE)
      WindowState = #False
      TimerStart = #False
    EndIf    
  EndIf  
  If Event = #PB_Event_Timer
    If EventTimer() = 10
      If my <= 0 And WindowState = #False
        AnimateWindow_(WindowID(#MainWin), 150, #AW_ACTIVATE|#AW_VER_POSITIVE)
        WindowState = #True
        RemoveWindowTimer(#MainWin, 10)
      EndIf
    EndIf
  EndIf  
Until Quit > 0
Hat da jemand eine Idee ? Wenn ja welche ?

P.S. : Achja... damit das Window "ausklappt", die Maus an den oberen Bildschirmrand bewegen und mind. 500ms dort stehen lassen ;)

Re: kurzfristig Repaint bei Gadget verhindern

Verfasst: 20.08.2012 11:51
von RSBasic
Hallo Bisonte,

bei mir flackert leider nichts. Daher kann ich dir auch keine getestete Lösungen anbieten. Aber du kannst mal versuchen, das CanvasGadget zu deaktivieren oder ein Callback auf das CanvasGadget zu setzen und eine Null bei Repaint zurückzugeben, falls es überhaupt geht bei diesem CustomGadget.

Re: kurzfristig Repaint bei Gadget verhindern

Verfasst: 20.08.2012 12:00
von Bisonte
kein weisses aufblitzen am unteren Rand ? Auch bei wiederholtem auf/zu auf/zu usw. ?
Sieht bei mir aus wie eine weisse Linie im unteren Bereich des Fensters.

Das DisableGadget hab ich probiert, leider hilft das nicht.

Das mit dem Callback werd ich mal ausprobieren...

Re: kurzfristig Repaint bei Gadget verhindern

Verfasst: 20.08.2012 12:08
von Josh
Bei mir flackert da nichts, obwohl ich auch nicht die mega super Kiste habe.

Aber was anderes was mir aufgefallen ist. Ich habe meine Taskleiste links und dein Fenster geht unter die Taskleiste rein, was sicher nicht beabsichtigt ist.

Josh

Re: kurzfristig Repaint bei Gadget verhindern

Verfasst: 20.08.2012 12:11
von RSBasic
Bisonte hat geschrieben:kein weisses aufblitzen am unteren Rand ? Auch bei wiederholtem auf/zu auf/zu usw. ?
Ja, ich habe mehrfach getestet, kein Flackern. Wird sauber nach oben und unten geschoben.

Wenn es mit dem Callback auf das CanvasGadget nicht funktioniert, dann versuch mal das Repaint-Event des Fensters zu blocken.
Ansonsten musst du während der Animation das CanvasGadget temporär verstecken und stattdessen ImageGadget mit dem gezeichneten Hintergrundbild nehmen. Vielleicht geht es damit besser.

Re: kurzfristig Repaint bei Gadget verhindern

Verfasst: 20.08.2012 12:16
von Bisonte
Das war nur testweise, normal soll das Window dann sticky sein...

Diese Animation scheint kein Paint Event an das Window oder das Gadget zu schicken...

Schon komisch.

Vielleicht flackert es bei mir, weil ich einen sehr dunklen Desktop habe ?

Edit :

Also ein

Code: Alles auswählen

  
Image = GetGadgetAttribute(#MCanvas,#PB_Canvas_Image)
hBrush = CreatePatternBrush_(Image)
SetClassLongPtr_(WindowID(#MainWin), #GCL_HBRBACKGROUND, hBrush)
InvalidateRect_(WindowID(#MainWin), #Null, #True)
in der DrawMainCanvas() eingefuegt und das Canvas während der Animphase verstecken funktioniert bei mir dann auch ohne blitzen/flackern..

Mal sehen wie das ganze aussieht, wenn mehr als nur der Hintergrund auf dem Canvas zu sehen ist...

Re: kurzfristig Repaint bei Gadget verhindern

Verfasst: 20.08.2012 12:30
von RSBasic

Code: Alles auswählen

Enumeration 1 ; Windows
  #MainWin
EndEnumeration
Enumeration 1
  #MCanvas
EndEnumeration

Procedure DrawMainCanvas()
 
  If StartDrawing(CanvasOutput(#MCanvas))
    DrawingMode(#PB_2DDrawing_Default|#PB_2DDrawing_Gradient)
    BackColor( $7a7a7a ) : FrontColor( $303030 )
    LinearGradient(0,0,0,OutputHeight())
    Box(0, 0, OutputWidth(), OutputHeight(), 0)   
    DrawingMode(#PB_2DDrawing_Default)
    Line(0, OutputHeight()-1, OutputWidth(), 1, #Black)
    StopDrawing()
  EndIf
   
EndProcedure

Procedure myCallback(hWnd, uMsg, wParam, lParam)
  Debug uMsg
  
  ;Select uMsg
  ;  Case #WM_
  ;    ;ProcedureReturn 0
  ;EndSelect
  
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

OpenWindow(#MainWin, 0, 0, GetSystemMetrics_(#SM_CXSCREEN), 42, "TestWindow", #PB_Window_BorderLess|#PB_Window_Invisible)
CanvasGadget(#MCanvas, 0,0,WindowWidth(#MainWin),WindowHeight(#MainWin))
DrawMainCanvas()
WindowState = #False

SetWindowCallback(@myCallback())

Repeat
  Event = WaitWindowEvent(25)
  mx = DesktopMouseX() : my = DesktopMouseY()
  If my <= 0 And WindowState = #False And TimerStart = #False
    TimerStart = #True
    AddWindowTimer(#MainWin, 10, 500)
  Else
    WinRect.RECT
    GetWindowRect_(WindowID(#MainWin), @WinRect)
    If my > WinRect\bottom
      AnimateWindow_(WindowID(#MainWin), 150, #AW_HIDE|#AW_VER_NEGATIVE)
      WindowState = #False
      TimerStart = #False
    EndIf   
  EndIf 
  If Event = #PB_Event_Timer
    If EventTimer() = 10
      If my <= 0 And WindowState = #False
        AnimateWindow_(WindowID(#MainWin), 150, #AW_ACTIVATE|#AW_VER_POSITIVE)
        WindowState = #True
        RemoveWindowTimer(#MainWin, 10)
      EndIf
    EndIf
  EndIf 
Until Quit > 0
Da werden einige Events ausgegeben. Du kannst mit Hilfe der Anwendung "Konstantia" die richtigen #WM-Konstanten finden und selber testen, ob du damit was erreichen kannst.
Ansonsten werde ich es erst heute Abend zu Hause nochmal testen, ob ich es unter VirtualBox nachvollziehen kann.

Re: kurzfristig Repaint bei Gadget verhindern

Verfasst: 20.08.2012 12:55
von Bisonte
Ok, also das einzig nennenswerte Event ist #WM_ERASEBKGND

Alles andere hat nichts mit dem neuzeichnen zu tun... soweit ich weiss
Ich werd da noch ne weile rumpfriemeln .... ;)

Ok für Test : Ich hab hier Win7 64Bit, benutze PB4.61 x86...

Re: kurzfristig Repaint bei Gadget verhindern

Verfasst: 20.08.2012 21:27
von RSBasic
@Bisonte
So, ich hab deinen Code bei mir getestet (W7) und auch unter VirtualBox (WXP), aber das Flackern ist auf beiden Systemen nicht vorhanden.

Re: kurzfristig Repaint bei Gadget verhindern

Verfasst: 21.08.2012 11:15
von Lord
Bisonte hat geschrieben:...
Ok für Test : Ich hab hier Win7 64Bit, benutze PB4.61 x86...
Hab' ich jetzt auch benutzt: kein Flackern.
Das Fenster kommt sauber runter.

Bei Win7 64Bit und PB 4.61 x64 auch keine Probleme zu sehen.