Page 1 of 1

Reduce tab control flickering (WINDOWS ONLY)

Posted: Wed Dec 02, 2009 2:57 pm
by LuckyLuke
Using double buffering to reduce flickering during resize.

Code: Select all

Global hinstance = GetModuleHandle_(#Null)
Global OldProc = #Null

Procedure Tab_CB(hWnd, uMsg, wparam, lparam)
  Protected ps.PAINTSTRUCT

  Select uMsg
    Case #WM_ERASEBKGND
      ProcedureReturn 1
    Case #WM_PAINT
      If wparam 
        ProcedureReturn CallWindowProc_(OldProc, hWnd, uMsg, wparam, lparam)
      EndIf            
      hdc = BeginPaint_(hWnd, ps)
      memDC = CreateCompatibleDC_(hdc)
      hBMP = CreateCompatibleBitmap_(hdc, ps\rcPaint\right, ps\rcPaint\bottom)
      hOldBMP = SelectObject_(memDC, hBMP)

      CallWindowProc_(OldProc, hWnd, #WM_ERASEBKGND, memDC, 0)
      CallWindowProc_(OldProc, hWnd, #WM_PRINT, memDC, #PRF_CLIENT)

      BitBlt_(hdc, ps\rcPaint\left, ps\rcPaint\top, ps\rcPaint\right, ps\rcPaint\bottom, memDC, ps\rcPaint\left, ps\rcPaint\top, #SRCCOPY)
        
      ;Cleanup  
      SelectObject_(memDC, hOldBMP)        
      DeleteObject_(hBMP)
      DeleteDC_(memDC)
        
      EndPaint_(hwin, ps)
      ProcedureReturn 0
    Default
      ProcedureReturn CallWindowProc_(OldProc, hWnd, uMsg, wparam, lparam) 
    EndSelect 
EndProcedure

OpenWindow(0,0,0,640,480,"void",#WS_OVERLAPPEDWINDOW | #WS_CLIPCHILDREN )

hwndPanel = CreateWindowEx_(0,"SysTabControl32",0,#WS_CHILD | #WS_CLIPCHILDREN | #WS_VISIBLE,0,0,0,0,WindowID(0),0,0,0)
OldProc = SetWindowLongPtr_(hwndPanel, #GWLP_WNDPROC, @Tab_CB())
 
tci.TC_ITEM
tci\mask = #TCIF_TEXT
tci\pszText = @"Tab 1"
a = SendMessage_(hwndPanel,#TCM_INSERTITEM,0,tci)
UseGadgetList(hwndPanel)
ButtonGadget(0, 20, 30, 200, 20, "Standard Button")

tci\pszText = @"Tab 2"
SendMessage_(hwndPanel,#TCM_INSERTITEM,1,tci)

Repeat
   EventID = WaitWindowEvent()

   If EventID = #PB_Event_SizeWindow
      MoveWindow_(hwndPanel,10,10,WindowWidth(0)-20,WindowHeight(0)-20,1)
   EndIf
Until EventID = #PB_Event_CloseWindow

Re: Reduce tab control flickering (WINDOWS ONLY)

Posted: Wed Dec 02, 2009 7:17 pm
by Mistrel
Is this only useful on controls? I can't seem to use it on the main window:

Code: Select all

Enumeration
   #Main
   #Main_Combo
   #Main_List
   #Main_Container
   #Main_Splitter
   #Main_Panel
EndEnumeration

Global OldProc

Procedure WinCallback(hWnd, uMsg, wParam, lParam)
  Protected ps.PAINTSTRUCT
  Select uMsg
    Case #WM_ERASEBKGND
      ProcedureReturn 1
    Case #WM_PAINT
      If wparam
        ProcedureReturn CallWindowProc_(OldProc, hWnd, uMsg, wparam, lparam)
      EndIf           
      hdc = BeginPaint_(hWnd, ps)
      memDC = CreateCompatibleDC_(hdc)
      hBMP = CreateCompatibleBitmap_(hdc, ps\rcPaint\right, ps\rcPaint\bottom)
      hOldBMP = SelectObject_(memDC, hBMP)

      CallWindowProc_(OldProc, hWnd, #WM_ERASEBKGND, memDC, 0)
      CallWindowProc_(OldProc, hWnd, #WM_PRINT, memDC, #PRF_CLIENT)

      BitBlt_(hdc, ps\rcPaint\left, ps\rcPaint\top, ps\rcPaint\right, ps\rcPaint\bottom, memDC, ps\rcPaint\left, ps\rcPaint\top, #SRCCOPY)
       
      ;Cleanup 
      SelectObject_(memDC, hOldBMP)       
      DeleteObject_(hBMP)
      DeleteDC_(memDC)
       
      EndPaint_(hwin, ps)
      ProcedureReturn 0
    Case #WM_WINDOWPOSCHANGED
       ResizeGadget(#Main_Splitter,#PB_Ignore,#PB_Ignore,WindowWidth(#Main)-10,WindowHeight(#Main)-10)
       ResizeGadget(#Main_Combo,#PB_Ignore,#PB_Ignore,GadgetWidth(#Main_Container),#PB_Ignore)
       ResizeGadget(#Main_List,#PB_Ignore,#PB_Ignore,GadgetWidth(#Main_Container),GadgetHeight(#Main_Container)-25)
    Default
      ProcedureReturn CallWindowProc_(OldProc, hWnd, uMsg, wparam, lparam)
    EndSelect
EndProcedure

If OpenWindow(#Main,#False,#False,420,235,"Test",#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget)
   PanelGadget(#Main_Panel,0,0,0,0)
   AddGadgetItem(#Main_Panel,-1,"Sub-Panel 1")
   AddGadgetItem(#Main_Panel,-1,"Sub-Panel 2")
   AddGadgetItem(#Main_Panel,-1,"Sub-Panel 3")

   CloseGadgetList()
   ContainerGadget(#Main_Container,0,0,0,0)
   ComboBoxGadget(#Main_Combo,0,0,160,200)
   ListIconGadget(#Main_List,0,25,160,200,"Test",70,#PB_ListIcon_FullRowSelect|#PB_ListIcon_HeaderDragDrop)
   AddGadgetColumn(#Main_List,1,"Test2",160)
   AddGadgetColumn(#Main_List,2,"Test3",60)
   For i=0 To 100
      AddGadgetItem(#Main_List,-1,"HelloHello"+#LF$+"HelloHelloHelloHello"+#LF$+"Hello")
   Next
   CloseGadgetList()
   SplitterGadget(#Main_Splitter,5,5,410,225,#Main_Panel,#Main_Container,#PB_Splitter_Vertical)
EndIf

ResizeGadget(#Main_Splitter,#PB_Ignore,#PB_Ignore,WindowWidth(#Main)-10,WindowHeight(#Main)-10)
ResizeGadget(#Main_Combo,#PB_Ignore,#PB_Ignore,GadgetWidth(#Main_Container),#PB_Ignore)
ResizeGadget(#Main_List,#PB_Ignore,#PB_Ignore,GadgetWidth(#Main_Container),GadgetHeight(#Main_Container)-25)

OldProc=GetWindowLongPtr_(WindowID(#Main),#GWL_WNDPROC)
SetWindowCallback(@WinCallback(),#Main)

Repeat
Until WaitWindowEvent()=#WM_CLOSE