It is currently Mon Jan 20, 2020 6:26 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: [Module] DeFlicker - easily deflicker resizeable Windows
PostPosted: Thu Mar 31, 2016 4:29 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Mon Apr 16, 2007 3:57 am
Posts: 420
Location: Germany, NRW
Hi there,

any PB Programmer on Windows might have noticed, that a resizeable GUI will flicker like hell while resizing the Window.

DeFlicker provides you with an easy way to suppress this flicker by just adding two simple lines of code:
---------------------------------------------------------------------------------------------------------------------------------------------------------
1. In your Gadget-Resize Routine, just call 'DeFlicker::StartResize(Window#)' before your first ResizeGadget()
2. If you finished the resizing, just call 'DeFlicker::EndResize()' after your last ResizeGadget()
... Done !!!

So, that's all you have to add to your Code: (Ok, ... if we also count the XInclude-Line, you need 3 additional Lines of Code:) :wink:
Code:
XInclude "Modul_DeFlicker.pbi"
...
...
DeFlicker::StartResize(Window#)
... (Your Routine where you resize your Gadgets)
DeFlicker::EndResize()
...

DeFlicker has already been testet by some users from the german forum and it seems to work fine on XP, Win7, Win8.1 & Win10.

You will find some Information about additional Functions within the Sourcecode in german language.
But because these additional functions are only needed if you have to finetune the deflickering, you may not need them at all.
Nevertheless ... if you would like to know more about these finetuning-functions and do not understand the german description, leave me a comment.

The Code does include a stress-test demo with 124 resizable Gadgets.
At the top left in the demo, you can enable or disable the 2 included 'DeFlicker'-commands with a CheckBox.
So you can easily see the difference with 'DeFlicker' and without 'DeFlicker'.

'DeFlicker' is Windows-Only, but as far as I know, Linux and OS-X do not have this flicker-problem at all.

Code:
;   Modul: DeFlicker   (Windows only)
;   --------------------------------------------------
;   Bei größenveränderlichen Fenstern tritt häufig (vor allem bei älteren, langsameren PCs) ein störendes
;   Flimmern auf, wenn das Fenster und die darin befindlichen Gadgets resized werden.
;   Durch DeFlicker kann man dieses Flimmern nun auf einfache Weise unterbinden.

;   Anwendung:
;   ---------------------
;   Die 'standard' Anwendung ist denkbar einfach:
;   In der Routine, in der das Resizing der Gadgets vorgenommen wird, muss vor dem ersten ResizeGadget()
;   die DeFlicker-Funktion 'StartResize(Window)' aufgerufen werden (mit Angabe der entspechenden Fensternummer).
;   Wenn alle Gadgets resized wurden, muss noch EndResize() aufgerufen werden, wodurch das Fenster und die Gadgets
;   (weitestgehend) flimmerfrei neu gezeichnet wird.

;   Hinweis:
;   ---------------------
;   Manchmal muss - um ein optimales Ergebnis zu erhalten - noch bei eingen Gadgets ein wenig Feintuning betrieben werden.
;   Wenn z.B. transparente Images verwendet werden, so sollte DeFlicker für diese Images ggfl. abgeschaltet werden um
;   keine unschönen Nebeneffekte durch nicht gelöschte Grafikreste zu erhalten (siehe 'SetGadgetDeFlicker()' oder
;   'SetGadgetTypeDeFlicker()' weiter unten).
;
;   Hierzu kann man das DeFlickern auf 4 Arten sowohl generell für eine GadgetTyp als auf für einzelne Gadgets justieren:
;   -   #DeFlicker_Full      -   der gesamte Bereich eines Gadgets wird entflimmert (sinnvoll bei allen 'normalen' rechteckigen Gadgets)
;   -   #DeFlicker_NO         -   der Bereich des Gadgets wird nicht entflimmert (sinnvoll bei allen Arten von Container- Gadgets, die weitere Gadgets enthalten)
;   -   #DeFlicker_Top16/20   -   hier werden nur die oberen 16/20 Pixel des Gadgets entflimmert (z.B. nützlich für PanelGadgets die nur in der Höhe verändert werden)
;      (oder auch Werte)         (statt der Konstanten #DeFlicker_Top16/20 kann auch die Anzahl der Pixel als Parameter übergeben
;                               werden (also z.B. '16' oder '20'. Erlaubt sind hierbei Werte von 3-999 Pixel)
;   -   #DeFlicker_Region      -   Bei #DeFlicker_Region kann ein spezieller Bereich definiert werden, der entflimmert werden soll.
;                              Dies ist z.B. zum Optimieren des Tab-Bereichs bei PanelGadgets sinnvoll.

;   Zur Verfügung stehende Funktionen:
;   ----------------------------------------
;   -    StartResize(Window)               -   verhindert von nun an, dass das Fenster neu gezeichnet wird (s.o.)
;   -   EndResize(RefreshWindow=#True)   -   erlaubt wieder das Neuzeichnen des Fensters und zeichnet den Inhalt neu (s.o.)
;                                          (Hinweis: EndResize() ruft automatisch 'RefreshWindow(Window)' auf um den Fensterinhalt
;                                           neu zu zeichnen. Dies kann durch den optionalen Parameter (RefreshWindow=#False)
;                                           unterbunden werden. RefreshWindow() kann dann bei Bedarf separat aufgerufen werden.
;   -   RefreshWindow(Window)            -   zeichnet den Fensterinhalt möglichst flimmerfrei neu (s.o.)


;   -   SetGadgetTypeDeFlicker(GadgetType, RefreshType)      - setzt die standard DeFlicker-Art für einen bestimmten GadgetType
;                                                           (#DeFlicker_Region ist hierbei nicht möglich)
;   -   GetGadgetTypeDeFlicker(GadgetType)                  - gibt die aktuell eingestellte DeFlicker-Art für einen GadgetType zurück


;   -   SetGadgetDeFlicker(Gadget, RefreshType [, xPos, yPos, Width, Height])
;                                                         - setzt die DeFlicker-Art für ein ganz bestimmtes Gadget
;                                                           Bei #DeFlicker_Region muss noch der Bereich definiert werden
;   -   GetGadgetDeFlicker(Gadget)                           - gibt die aktuell eingestellte DeFlicker-Art für dieses Gadget zurück


;   Anwendungsbeispiel:
;   ---------------------------------------------------------------------------------------------------------------------------
;   Am Ende dieses Codes (nach der Definition des Moduls: DeFlicker) findet Ihr ein kleines Hardcore-Beispiel mit 124 Gadgets


#DeFlicker_NO         = 1
#DeFlicker_Region      = 2
#DeFlicker_Top16      = 16
#DeFlicker_Top20      = 20
#DeFlicker_Full      = 1000

DeclareModule      DeFlicker

   Declare   StartResize(Window)
    Declare   RefreshWindow(Window)
   Declare   EndResize(RefreshWindow=#True)
   
   Declare   GetGadgetTypeDeFlicker(GadgetType)
   Declare   SetGadgetTypeDeFlicker(GadgetType, RefreshType)

   Declare   GetGadgetDeFlicker(Gadget)
   Declare   SetGadgetDeFlicker(Gadget, RefreshType, xPos=#PB_Ignore, yPos=#PB_Ignore, Width=#PB_Ignore, Height=#PB_Ignore)

EndDeclareModule
Module   DeFlicker
   
   EnableExplicit
   
   #DeFlicker_NO         = 1
   #DeFlicker_Region      = 2
   #DeFlicker_Top16      = 16
   #DeFlicker_Top20      = 20
   #DeFlicker_Full      = 1000
     
   Structure   GadgetDetails_Struct
      GadgetID.i
      GadgetNumber.i
      GadgetType.i
      left.l
      top.l
      right.l
      bottom.l
   EndStructure
   Structure   UserDefined_DeFlickerType_Struct
      GadgetNumber.i
      DeFlicker_Type.l
      xPos.w
      yPos.w
      Width.w
      Height.w
   EndStructure
   
   #MaxGadgetTypes = 40
   Global   Dim GadgetType_Default.l(#MaxGadgetTypes)
   Global   NewList   CallBackGadgetList.GadgetDetails_Struct()
   Global   NewList   UserDefined_DeFlickerType.UserDefined_DeFlickerType_Struct()
   Global   LastResizedWindow
   Define   n
   
   For n = 0 To #MaxGadgetTypes
      GadgetType_Default(n) = #DeFlicker_Full                        ; Standard für alle Gadgets ist erst einmal 'Full'-Deflicker
   Next
   
   GadgetType_Default(#PB_GadgetType_Frame)      = #DeFlicker_Top16   ; Jetzt werden einige Ausnamen voreingestellt
   GadgetType_Default(#PB_GadgetType_Container)   = #DeFlicker_NO
   GadgetType_Default(#PB_GadgetType_Splitter)   = #DeFlicker_NO
   GadgetType_Default(#PB_GadgetType_Panel)      = #DeFlicker_Full
   
   Procedure   GetGadgetList_Callback(hwnd,*WinPos.POINT)                     ; interne Routine - CallBack zum Ermitteln der Gadgets-Liste
     
      ; CallBack zur Erstellung einer LinkedListe mit Details zu allen Gadgets in einem Window
     
      Protected   ActPBGadget, GadgetPos.RECT
     
      ActPBGadget = GetProp_(hwnd, "PB_ID")                                    ; Gadget# des PB-Gadgets
     
      If IsGadget(ActPBGadget) And GadgetID(ActPBGadget) = hwnd               ; Checken ob die ermittelte Gadget# aus ok ist
         If AddElement(CallBackGadgetList())
            CallBackGadgetList()\GadgetID         = hwnd
            CallBackGadgetList()\GadgetNumber   = ActPBGadget
            CallBackGadgetList()\GadgetType      = GadgetType(ActPBGadget)
            GetWindowRect_(hwnd, @GadgetPos)                                       ; Desktop-Position des Gadgets ermitteln
            CallBackGadgetList()\left      = GadgetPos\left      - *WinPos\x         ; Gadgetposition auf Position im Fenster umrechnen
            CallBackGadgetList()\top      = GadgetPos\top      - *WinPos\y         ;       ''
            CallBackGadgetList()\right      = GadgetPos\right      - *WinPos\x         ;       ''
            CallBackGadgetList()\bottom   = GadgetPos\bottom   - *WinPos\y         ;       ''
         EndIf
      EndIf
     
      ProcedureReturn #True
     
   EndProcedure
   Procedure   GetGadgetList(Window, List GadgetList.GadgetDetails_Struct())   ; interne Routine zum Erstellen einer Liste mit allen Gadgets
     
      ; Ermittelt Details aller PB-Gadgets in einem Fenster und gibt diese in einer LinkedList zurück
     
      Protected   WinPos.POINT
     
      If IsWindow(Window)
         WinPos\x = WindowX(Window, #PB_Window_InnerCoordinate)      ; Window-Position ermitteln, dami diese an den CallBack übergeben werden kann
         WinPos\y = WindowY(Window, #PB_Window_InnerCoordinate)
       
         ClearList(CallBackGadgetList())                                          ; LinkedList des CallBacks löschen
         EnumChildWindows_(WindowID(Window),@GetGadgetList_Callback(),@WinPos)   ; Alle Gadgets ermitteln und per CallBack auswerten
         CopyList(CallBackGadgetList(), GadgetList())                              ; Die vom CallBack erstellte LinkedListe auf die eigentliche Liste kopieren
      Else
         Debug "Window Nr."+Str(Window)+" konnte nicht gefunden werden."
      EndIf
     
      ProcedureReturn   ListSize(GadgetList())
     
   EndProcedure
   
   Procedure   StartResize(Window)
      If IsWindow(Window)
         SendMessage_(WindowID(Window),#WM_SETREDRAW,#False,0)
         LastResizedWindow = Window
      Else
         Debug "Window Nr."+Str(Window)+" nicht gefunden."
      EndIf
   EndProcedure
   Procedure   RefreshWindow(Window)
     
      If IsWindow(Window)
         
         Protected   ps.PAINTSTRUCT
         Protected   Validate.RECT
         Protected   NewList GadgetList.GadgetDetails_Struct()
         Protected   hWnd.i = WindowID(Window)
         Protected   WinRect.rect
         Protected   ActDeFlickerType
         Protected   ClearEventLoop = #True
         
         GetGadgetList(Window, GadgetList())
         
         GetClientRect_(hWnd, @WinRect)
         InvalidateRect_(hWnd,WinRect,1)
         
         ForEach GadgetList()
           
            If GadgetList()\GadgetType = #PB_GadgetType_Panel
               ClearEventLoop = #True
            EndIf
           
            ActDeFlickerType   = GadgetType_Default(GadgetList()\GadgetType)
           
            ForEach UserDefined_DeFlickerType()
               If UserDefined_DeFlickerType()\GadgetNumber = GadgetList()\GadgetNumber
                  ActDeFlickerType = UserDefined_DeFlickerType()\DeFlicker_Type
                  Break
               EndIf
            Next
           
            Select ActDeFlickerType
                 
               Case   #DeFlicker_Full            ;   Gadget-Bereich wird komplett 'DeFlickered'
                 
                  ValidateRect_(hWnd, @GadgetList()\left)
                 
               Case   #DeFlicker_Region
                 
                  Validate\left      = GadgetList()\left   + UserDefined_DeFlickerType()\xPos
                  Validate\top      = GadgetList()\top   + UserDefined_DeFlickerType()\yPos
                  Validate\right      = GadgetList()\left   + UserDefined_DeFlickerType()\Width
                  Validate\bottom   = GadgetList()\top   + UserDefined_DeFlickerType()\Height
                 
               Case   #DeFlicker_Region+1 To #DeFlicker_Full-1      ;  Nur oberen Teil des Gadgets 'DeFlickern'
                 
                  Validate\left      = GadgetList()\left + 8
                  Validate\top      = GadgetList()\top
                  Validate\right      = GadgetList()\right - 8
                  Validate\bottom   = GadgetList()\top + ActDeFlickerType - 1
                 
                  If GadgetList()\GadgetType = #PB_GadgetType_Frame
                     If StartDrawing(WindowOutput(Window))
                        DrawingFont(GetGadgetFont(GadgetList()\GadgetNumber))
                        Validate\right      = GadgetList()\left + 8 + TextWidth(GetGadgetText(GadgetList()\GadgetNumber))
                        Validate\bottom   = GadgetList()\top + TextHeight(GetGadgetText(GadgetList()\GadgetNumber))
                        If Validate\right > GadgetList()\right : Validate\right = GadgetList()\right : EndIf
                        StopDrawing()
                     EndIf
                  EndIf
                  ValidateRect_(hWnd, @Validate)
               Default
                 
                  ; No DeFlicker at all
                 
            EndSelect
           
         Next
         
         BeginPaint_(hWnd, ps.PAINTSTRUCT)
         EndPaint_(hWnd, ps.PAINTSTRUCT)
         RedrawWindow_(hWnd,#Null,#Null,#RDW_INVALIDATE);
         
         CompilerIf #PB_Compiler_Debugger         ; need this Trick to get special Gadgets refreshed (like PanelGadget)
            DisableDebugger
            If ClearEventLoop
               While WindowEvent() : Wend
            EndIf
            EnableDebugger
         CompilerElse
            If ClearEventLoop
               While WindowEvent() : Wend
            EndIf
         CompilerEndIf

      Else
         Debug "Window Nr."+Str(Window)+" nicht gefunden."
      EndIf
   EndProcedure
   Procedure   EndResize(RefreshWindow=#True)
      SendMessage_(WindowID(LastResizedWindow),#WM_SETREDRAW,#True,0)
      If RefreshWindow : RefreshWindow(LastResizedWindow): EndIf
   EndProcedure
   
   Procedure   GetGadgetTypeDeFlicker(GadgetType)
      If GadgetType >= 0 And GadgetType <= #MaxGadgetTypes
         ProcedureReturn GadgetType_Default(GadgetType)
      EndIf
   EndProcedure
   Procedure   SetGadgetTypeDeFlicker(GadgetType, RefreshType)
      If GadgetType >= 0 And GadgetType <= #MaxGadgetTypes And RefreshType >= #DeFlicker_NO And RefreshType <= #DeFlicker_Full And RefreshType <> #DeFlicker_Region
         GadgetType_Default(GadgetType) = RefreshType
         ProcedureReturn #True
      EndIf
   EndProcedure
   
   Procedure   GetGadgetDeFlicker(Gadget)
      ForEach UserDefined_DeFlickerType()
         If UserDefined_DeFlickerType()\GadgetNumber = Gadget
            ProcedureReturn UserDefined_DeFlickerType()\DeFlicker_Type
         EndIf
      Next
   EndProcedure
   Procedure   SetGadgetDeFlicker(Gadget, RefreshType, xPos=#PB_Ignore, yPos=#PB_Ignore, Width=#PB_Ignore, Height=#PB_Ignore)
     
      If IsGadget(Gadget) And RefreshType >= #DeFlicker_NO And RefreshType <= #DeFlicker_Full
         
         Repeat
            ForEach UserDefined_DeFlickerType()
               If UserDefined_DeFlickerType()\GadgetNumber = Gadget
                  Break 2
               EndIf
            Next
           
            AddElement(UserDefined_DeFlickerType())
         Until #True
         
         With UserDefined_DeFlickerType()
            \GadgetNumber      = Gadget
            \DeFlicker_Type   = RefreshType
            If RefreshType   = #DeFlicker_Region
               \xPos            = xPos
               \yPos            = yPos
               \Width         = Width
               \Height         = Height
            EndIf
         EndWith
         
      EndIf
     
   EndProcedure
   
EndModule


; ========================================================================================
; ====                        Sample-Code with 124 Gadgets                            ====
; ========================================================================================


CompilerIf #PB_Compiler_IsMainFile
   
   EnableExplicit

   #winMain = 0
   Global   DeFlicker_enabled = #False
   Global   xCount = 8, yCount = 14
   Define   n
   
   Procedure   ResizeGadgets()      ; Dies ist die BindEvent-Routine zum resizen der Gadgets
     
      Protected   x,y, ActX, ActY, ActWidth.f, ActHeight.f
      Protected   ActWinWidth = WindowWidth(#winMain), ActWinHeight = WindowHeight(#winMain)
     
      ; =============================  just call StartResize() before you resize  ============================
     
      If DeFlicker_enabled
         DeFlicker::StartResize(#winMain)
      EndIf
     
      ; ======================================================================================================
     
         
      ; Resize Button-Area
     
      ActX = 8
      ActY = 28
      ActWidth = (ActWinWidth - ActX - 300 - (xCount-1) * 5) / xCount
      ActHeight = (ActWinHeight - ActY - 13 - (yCount-1) * 5) / yCount
     
      For x = 0 To xCount - 1
         For y = 0 To yCount - 1
            ResizeGadget(30 + x + y*xCount, ActX + x * (ActWidth + 5), ActY + y * (ActHeight + 5), ActWidth, ActHeight)
         Next
      Next
     
      ResizeGadget(1, ActWinWidth - 290, 10, 280, ActWinHeight/2 - 15)
      ResizeGadget(20,ActWinWidth - 270, 35, 250, 19)
      ResizeGadget(21,ActWinWidth - 270, 55, 250, 19)
      ResizeGadget(22,ActWinWidth - 270, 75, 250, 19)
      ResizeGadget(23,ActWinWidth - 275, 98, 250, ActWinHeight/2 - 143)
      ResizeGadget(24,ActWinWidth - 275, ActWinHeight/2 - 38, 250, 25)
     
      ResizeGadget(2, ActWinWidth - 290, ActWinHeight/2 + 5, 280, ActWinHeight/2 - 15)
      ResizeGadget(10,10,10,(GadgetWidth(2)-6)/2-15, (GadgetHeight(2)-50)/2)
      ResizeGadget(11,(GadgetWidth(2)-6)/2+5,10,(GadgetWidth(2)-6)/2-15, (GadgetHeight(2)-50)/2)
      ResizeGadget(12,10,(GadgetHeight(2)-50)/2 + 20,(GadgetWidth(2)-36)/2, (GadgetHeight(2)-50)/2-10)
      ResizeGadget(13,(GadgetWidth(2)-6)/2+5,(GadgetHeight(2)-50)/2 + 20,(GadgetWidth(2)-6)/2-15, (GadgetHeight(2)-50)/2-10)
     
      ; =============  just call EndResize() when you are finished with the Gadget resizing  =================
     
      If DeFlicker_enabled
         DeFlicker::EndResize()
      EndIf
     
      ; ======================================================================================================
     
   EndProcedure
   
   Procedure   CheckBox_EnableDeFlicker()
      If IsGadget(0)
         DeFlicker_enabled = GetGadgetState(0)
      EndIf
   EndProcedure
   
   OpenWindow(#winMain,0,0,800,600,"DeFlicker Hardcore-Sample", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
   WindowBounds(#winMain, 520, 360, #PB_Default, #PB_Default)
   
   BindEvent(#PB_Event_SizeWindow, @ResizeGadgets())
   
   CheckBoxGadget(0,10,5, 150, 20, "enable DeFlicker")      ; CheckBox um
   SetGadgetState(0, DeFlicker_enabled)
   BindGadgetEvent(0, @CheckBox_EnableDeFlicker())
   
   FrameGadget(1, 10,10,10,10," iFrame ")
   OptionGadget(20,10,10,10,10,"I use PB on Windows")
   OptionGadget(21,10,10,10,10,"I use PB on Linux")
   OptionGadget(22,10,10,10,10,"I use PB on MacOS")
   EditorGadget(23,10,10,10,10, #PB_Editor_WordWrap)
   ComboBoxGadget(24,10,10,10,10)
   
   PanelGadget(2, 10,10,10,10)
   AddGadgetItem(2, -1, "Panel 1")
   ButtonGadget(10, 10,10,80,80,"do")
   ButtonGadget(11, 100,10,80,80,"re")
   ButtonGadget(12, 10,100,80,80,"mi")
   ButtonGadget(13, 100,100,80,80,"fa")
   AddGadgetItem(2, -1, "Panel 2")
   AddGadgetItem(2, -1, "Panel 3")
   CloseGadgetList()
   
   For n = 30 To 29 + xCount * yCount
      ButtonGadget(n,10,10,10,10,"Btn:"+Str(n-29))
   Next
   
   ResizeGadgets()
   
   While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
   
CompilerEndIf

If it's of some use for you or if you locate some problems, just leave a message. :wink:

_________________
[Dynamic-Dialogs] - create complex GUIs the easy way
[DeFlicker] - easily deflicker your resizeable Windows
[WinFX] - Window Effects (incl. 'click-through' Window)


Top
 Profile  
Reply with quote  
 Post subject: Re: [Module] DeFlicker - easily deflicker resizeable Windows
PostPosted: Thu May 26, 2016 3:36 am 
Offline
Enthusiast
Enthusiast

Joined: Thu Nov 15, 2012 11:38 pm
Posts: 118
Location: Los Angeles
Verrry nice! Interestingly, the only flicker I get is when decreasing horizontally or vertically over PB's Procedure Browser pane. :? Even more curious is the flicker is more intense with DeFlicker on. :shock: None of this happens with any other pane.

Win 7 Ultimate, PB 5.42 LTS x64


Top
 Profile  
Reply with quote  
 Post subject: Re: [Module] DeFlicker - easily deflicker resizeable Windows
PostPosted: Thu May 26, 2016 6:24 am 
Offline
Enthusiast
Enthusiast

Joined: Fri Feb 19, 2010 3:42 am
Posts: 541
You should enable the checkbox as default.

This is great!!!!!!!

Thanks a lot!!!


Top
 Profile  
Reply with quote  
 Post subject: Re: [Module] DeFlicker - easily deflicker resizeable Windows
PostPosted: Mon May 30, 2016 10:54 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Mon Apr 16, 2007 3:57 am
Posts: 420
Location: Germany, NRW
HanPBF wrote:
This is great!!!!!!!
Thanks a lot!!!
You are welcome. :wink:

Jagermeister wrote:
..., the only flicker I get is when decreasing horizontally or vertically over PB's Procedure Browser pane. :?
What do you mean with "PB's Procedure Browser pane"? There is no Browser-Gadget in my example. Do you mean the Window, created by PB, titled "DeFlicker Hardcore-Sample"?

Jagermeister wrote:
Even more curious is the flicker is more intense with DeFlicker on. :shock:
Do you mean, it flickers more, if you check the Checkbox "enable DeFlicker" in the top-left? :shock:

Thanks and greets,
PL.

_________________
[Dynamic-Dialogs] - create complex GUIs the easy way
[DeFlicker] - easily deflicker your resizeable Windows
[WinFX] - Window Effects (incl. 'click-through' Window)


Top
 Profile  
Reply with quote  
 Post subject: Re: [Module] DeFlicker - easily deflicker resizeable Windows
PostPosted: Mon Sep 04, 2017 1:10 pm 
Offline
Addict
Addict

Joined: Mon Feb 16, 2015 2:49 pm
Posts: 1905
This is working great for me, PureLust. Thank you! :)

A quick question: do these constants need to be defined twice in the code?

Can I keep the ones inside the module instead, and remove the outside ones?

Code:
#DeFlicker_NO         = 1
#DeFlicker_Region      = 2
#DeFlicker_Top16      = 16
#DeFlicker_Top20      = 20
#DeFlicker_Full      = 1000


Top
 Profile  
Reply with quote  
 Post subject: Re: [Module] DeFlicker - easily deflicker resizeable Windows
PostPosted: Tue Sep 05, 2017 2:58 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4600
Location: Lyon - France
A little bit late "May 30, 2016" :oops:
But thanks to DUDE, i have see this splendid code, missed before :oops:
Thanks for sharing 8)

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: [Module] DeFlicker - easily deflicker resizeable Windows
PostPosted: Wed Sep 06, 2017 6:05 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Mon Apr 16, 2007 3:57 am
Posts: 420
Location: Germany, NRW
Dude wrote:
A quick question: do these constants need to be defined twice in the code?

Can I keep the ones inside the module instead, and remove the outside ones?[/code]

Hi Dude, ... the outside ones are just for easy access, if you do not use 'UseModule'.

E.g.: Without 'UseModule' you usually need to write:
- DeFlicker::GadgetType_Default(#PB_GadgetType_Splitter) = DeFlicker::#DeFlicker_NO

Because of the outside defined constants, you can save the 'DeFlicker::'-prefix for the Constants:
- DeFlicker::GadgetType_Default(#PB_GadgetType_Splitter) = #DeFlicker_NO

So .. DeFlicker does non need the Outside constants ... it's just to save some code.

But ... you only need these constants if you are not happy with DeFlickers Result with Default-Settings and want want to tweak DeFlickers output.
So, in most cases you may not use/need them at all and can get rid of the outside once anyway. ;)


Kwai chang caine wrote:
Thanks for sharing 8)

You are welcome. :mrgreen:

_________________
[Dynamic-Dialogs] - create complex GUIs the easy way
[DeFlicker] - easily deflicker your resizeable Windows
[WinFX] - Window Effects (incl. 'click-through' Window)


Top
 Profile  
Reply with quote  
 Post subject: Re: [Module] DeFlicker - easily deflicker resizeable Windows
PostPosted: Fri Sep 08, 2017 8:26 pm 
Offline
Enthusiast
Enthusiast

Joined: Thu Apr 14, 2011 6:07 pm
Posts: 342
Nice :D
Many thanks for sharing :D


Top
 Profile  
Reply with quote  
 Post subject: Re: [Module] DeFlicker - easily deflicker resizeable Windows
PostPosted: Sun Sep 24, 2017 7:54 am 
Offline
Addict
Addict

Joined: Mon Feb 16, 2015 2:49 pm
Posts: 1905
Jagermeister wrote:
more curious is the flicker is more intense with DeFlicker on. :shock:

I noticed today I don't need DeFlicker if I use SmartWindowRefresh(win,#True) and actioning the #WM_SIZING and #WM_WINDOWPOSCHANGED messages in a callback like so:

Code:
If Message=#WM_SIZING or Message=#WM_WINDOWPOSCHANGED
  UpdateWindow_(WindowID(win))
EndIf

Doing this has removed all flicker in my specific situation.


Last edited by Dude on Sat Jan 27, 2018 8:33 am, edited 3 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: [Module] DeFlicker - easily deflicker resizeable Windows
PostPosted: Mon Jan 01, 2018 8:46 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Mon Apr 16, 2007 3:57 am
Posts: 420
Location: Germany, NRW
Dude wrote:
Adding this simple #WM_SIZING check has removed all flicker in my specific situation.

Hi Dude, ... I've just tested your Version and it works excellent !!! Image

But whow ... I was never aware, how much SmartWindowRefresh slows down the resizing-process of a Window. :shock:

In the following test-code (it's just a conversion of the DeFlicker-Example-Window to your Version) you can enable and disable SmartWindowRefresh with the checkbox top-left.

Any idea, what SmartWindowRefresh does, that could cause such a dramatic performance dropdown?

Code:
EnableExplicit

#winMain = 0
Global   xCount = 8, yCount = 14
Define   n

Procedure   ResizeGadgets()      ; Dies ist die BindEvent-Routine zum resizen der Gadgets
   
   Protected   x,y, ActX, ActY, ActWidth.f, ActHeight.f
   Protected   ActWinWidth = WindowWidth(#winMain), ActWinHeight = WindowHeight(#winMain)
   
   ; Resize Button-Area
   
   ActX = 8
   ActY = 28
   ActWidth = (ActWinWidth - ActX - 300 - (xCount-1) * 5) / xCount
   ActHeight = (ActWinHeight - ActY - 13 - (yCount-1) * 5) / yCount
   
   For x = 0 To xCount - 1
      For y = 0 To yCount - 1
         ResizeGadget(30 + x + y*xCount, ActX + x * (ActWidth + 5), ActY + y * (ActHeight + 5), ActWidth, ActHeight)
      Next
   Next
   
   ResizeGadget(1, ActWinWidth - 290, 10, 280, ActWinHeight/2 - 15)
   ResizeGadget(20,ActWinWidth - 270, 35, 250, 19)
   ResizeGadget(21,ActWinWidth - 270, 55, 250, 19)
   ResizeGadget(22,ActWinWidth - 270, 75, 250, 19)
   ResizeGadget(23,ActWinWidth - 275, 98, 250, ActWinHeight/2 - 143)
   ResizeGadget(24,ActWinWidth - 275, ActWinHeight/2 - 38, 250, 25)
   
   ResizeGadget(2, ActWinWidth - 290, ActWinHeight/2 + 5, 280, ActWinHeight/2 - 15)
   ResizeGadget(10,10,10,(GadgetWidth(2)-6)/2-15, (GadgetHeight(2)-50)/2)
   ResizeGadget(11,(GadgetWidth(2)-6)/2+5,10,(GadgetWidth(2)-6)/2-15, (GadgetHeight(2)-50)/2)
   ResizeGadget(12,10,(GadgetHeight(2)-50)/2 + 20,(GadgetWidth(2)-36)/2, (GadgetHeight(2)-50)/2-10)
   ResizeGadget(13,(GadgetWidth(2)-6)/2+5,(GadgetHeight(2)-50)/2 + 20,(GadgetWidth(2)-6)/2-15, (GadgetHeight(2)-50)/2-10)
   
EndProcedure

Procedure MyWindowCallback(WindowID, Message, wParam, lParam)
   Protected   Result = #PB_ProcessPureBasicEvents
   
   If Message=#WM_SIZING
      UpdateWindow_(WindowID)
   EndIf
   
   ProcedureReturn Result
EndProcedure

Procedure   CheckBox_EnableSmartWindowRefresh()
   If IsGadget(0)
      SmartWindowRefresh(#winMain, GetGadgetState(0))
   EndIf
EndProcedure

OpenWindow(#winMain,0,0,800,600,"DeFlicker Hardcore-Sample", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
WindowBounds(#winMain, 520, 360, #PB_Default, #PB_Default)
SmartWindowRefresh(#winMain,#True)

BindEvent(#PB_Event_SizeWindow, @ResizeGadgets())

CheckBoxGadget(0,10,5, 150, 20, "enable SmartWindowRefresh")      ; CheckBox um
SetGadgetState(0, #True)
BindGadgetEvent(0, @CheckBox_EnableSmartWindowRefresh())

FrameGadget(1, 10,10,10,10," iFrame ")
OptionGadget(20,10,10,10,10,"I use PB on Windows")
OptionGadget(21,10,10,10,10,"I use PB on Linux")
OptionGadget(22,10,10,10,10,"I use PB on MacOS")
EditorGadget(23,10,10,10,10, #PB_Editor_WordWrap)
ComboBoxGadget(24,10,10,10,10)

PanelGadget(2, 10,10,10,10)
AddGadgetItem(2, -1, "Panel 1")
ButtonGadget(10, 10,10,80,80,"do")
ButtonGadget(11, 100,10,80,80,"re")
ButtonGadget(12, 10,100,80,80,"mi")
ButtonGadget(13, 100,100,80,80,"fa")
AddGadgetItem(2, -1, "Panel 2")
AddGadgetItem(2, -1, "Panel 3")
CloseGadgetList()

For n = 30 To 29 + xCount * yCount
   ButtonGadget(n,10,10,10,10,"Btn:"+Str(n-29))
Next

SetWindowCallback(@MyWindowCallback())   

ResizeGadgets()

While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
Ohh, ... btw: Image HAPPY NEW YEAR TO ALL OF YOU !!! :mrgreen:

_________________
[Dynamic-Dialogs] - create complex GUIs the easy way
[DeFlicker] - easily deflicker your resizeable Windows
[WinFX] - Window Effects (incl. 'click-through' Window)


Top
 Profile  
Reply with quote  
 Post subject: Re: [Module] DeFlicker - easily deflicker resizeable Windows
PostPosted: Mon Jan 01, 2018 9:46 pm 
Offline
Administrator
Administrator

Joined: Fri May 17, 2002 4:39 pm
Posts: 13683
Location: France
SmartWindowRefresh bascially create a clip region out of all sibling control, and apply it to the WM_ERASEBACKGROUND message, so the erase doesn't overwrite the controls with a solid color. So the more control you have in your root window, the worste it will perfom.


Top
 Profile  
Reply with quote  
 Post subject: Re: [Module] DeFlicker - easily deflicker resizeable Windows
PostPosted: Mon Jan 01, 2018 10:02 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Mon Apr 16, 2007 3:57 am
Posts: 420
Location: Germany, NRW
Fred wrote:
SmartWindowRefresh bascially create a clip region out of all sibling control, and apply it to the WM_ERASEBACKGROUND message, so the erase doesn't overwrite the controls with a solid color. So the more control you have in your root window, the worste it will perfom.
Hi Fred, thanks for clarifying.
So, in theory it does the same as my Deflicker-Routine.
But instead of using Clip-Regions, I just use InvalidateRect() and ValidateRect() to exclude all controls, which seems to be much faster.

Maybe it's worth to try this method on SmartWindowRefresh and include Dudes 'UpdateWindow_(WindowID(win))' to get a fast and perfect Result?

_________________
[Dynamic-Dialogs] - create complex GUIs the easy way
[DeFlicker] - easily deflicker your resizeable Windows
[WinFX] - Window Effects (incl. 'click-through' Window)


Top
 Profile  
Reply with quote  
 Post subject: Re: [Module] DeFlicker - easily deflicker resizeable Windows
PostPosted: Mon Jan 01, 2018 10:13 pm 
Offline
Enthusiast
Enthusiast

Joined: Fri Feb 19, 2010 3:42 am
Posts: 541
Thanks for all Your work!

But: hopefully PB team does not put so much time anymore in Win32 technology.
It's 2018... :wink:

(At Xojo site they work also around that annoying flicker problem; at the moment, this IDE is not usable for windows UI projects...)

O.k., maybe I am wrong. Is Win32 still used across PB community for UI? Not only little helper tools; for big projects?


Happy New Year 2018!!!!


Top
 Profile  
Reply with quote  
 Post subject: Re: [Module] DeFlicker - easily deflicker resizeable Windows
PostPosted: Mon Jan 01, 2018 10:19 pm 
Offline
Administrator
Administrator

Joined: Fri May 17, 2002 4:39 pm
Posts: 13683
Location: France
What's the alternative to win32 ?

@PureLust, I will give it a try.


Top
 Profile  
Reply with quote  
 Post subject: Re: [Module] DeFlicker - easily deflicker resizeable Windows
PostPosted: Mon Jan 01, 2018 10:53 pm 
Offline
Enthusiast
Enthusiast

Joined: Fri Feb 19, 2010 3:42 am
Posts: 541
http://www.cplusplus.com/forum/lounge/140601/

Unfortunately no true alternative...

Styling win32 is a mess.
So, combining canvasgadget with other gadgets seems indeed best solution at the moment.

Only better would be an embeddable WebKit or other HTML engine with true PureBasic interaction.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye