SplitterGadget with more than two gadgets
Re: SplitterGadget with more than two gadgets
Just tried chi example
It works fine with me
PB 6.1 x64 Windows 11 x64
What is your configurations ?
It works fine with me
PB 6.1 x64 Windows 11 x64
What is your configurations ?
Egypt my love
Re: SplitterGadget with more than two gadgets
Chi's example is using #PB_Event_SizeWindow, but that's not the issue. The issue is glitching when moving the splittergadget, not resizing the window.
Re: SplitterGadget with more than two gadgets
Maybe try updatewindow on splitter position change
Code: Select all
Global OldProc
Procedure SplitterProc(hWnd, uMsg, wParam, lParam)
Static SplitterPos
Select uMsg
Case #WM_NCDESTROY
Case #WM_PAINT
Protected Position = GetGadgetState(GetProp_(hWnd, "PB_ID"))
If SplitterPos <> Position
SplitterPos = Position
Else
ProcedureReturn #False
EndIf
EndSelect
ProcedureReturn CallWindowProc_(OldProc, hWnd, uMsg, wParam, lParam)
EndProcedure
Procedure BindSplitterV()
Static SplitterPos
Protected Position = GetGadgetState(EventGadget())
If SplitterPos <> Position
SplitterPos = Position
UpdateWindow_(GadgetID(0))
UpdateWindow_(GadgetID(1))
Debug "Vertical Splitter new position: " + Position
Else
Debug "Vertical Splitter Event received without position change: " + Position + " !"
EndIf
EndProcedure
Procedure BindSplitterH()
Static SplitterPos
Protected Position = GetGadgetState(EventGadget())
If SplitterPos <> Position
SplitterPos = Position
UpdateWindow_(GadgetID(3))
Debug "Horizontal Splitter new position: " + Position
Else
Debug "Horizontal Event received without position change: " + Position + " !"
EndIf
EndProcedure
Procedure WinResize()
ResizeGadget(4, #PB_Ignore, #PB_Ignore, WindowWidth(0)-10, WindowHeight(0)-10)
EndProcedure
OpenWindow(0, 0, 0, 400, 400, "Splitter", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_ScreenCentered|#PB_Window_Invisible)
ExplorerListGadget(0, 0, 0, 0, 0, GetUserDirectory(#PB_Directory_Desktop))
ExplorerListGadget(1, 0, 0, 0, 0, GetUserDirectory(#PB_Directory_Pictures))
SplitterGadget(2, 5, 5, 390, 390, 0, 1, #PB_Splitter_Vertical)
BindGadgetEvent(2, @BindSplitterV())
ExplorerListGadget(3, 0, 0, 0, 0, GetHomeDirectory())
SplitterGadget(4, 5, 5, 390, 390, 2, 3, #PB_Splitter_Separator)
BindGadgetEvent(4, @BindSplitterH())
SetGadgetState(4, 250)
; SubClass Splitter for WM_PAINT message can also help
;OldProc = GetWindowLongPtr_(GadgetID(4), #GWLP_WNDPROC)
;SetWindowLongPtr_(GadgetID(4), #GWLP_WNDPROC, @SplitterProc())
BindEvent(#PB_Event_SizeWindow, @WinResize())
HideWindow(0, #False)
While WaitWindowEvent() <> #PB_Event_CloseWindow : WendRe: SplitterGadget with more than two gadgets
For me, rashad example also works without problems.
Code what changed, which OS, which PB
Code what changed, which OS, which PB
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: SplitterGadget with more than two gadgets
Maybe it's because of the gadget edges? Try following code "as is" and then uncomment the 2 lines...
edit: If you comment this line: BindGadgetEvent(5, @GadResizeB(), #PB_EventType_Resize), is the problem gone?
Code: Select all
Procedure GadResizeT()
ResizeGadget(0, 0, 0, GadgetWidth(4)/2, GadgetHeight(4))
ResizeGadget(1, GadgetWidth(4)/2, 0, GadgetWidth(4)/2, GadgetHeight(4))
EndProcedure
Procedure GadResizeB()
ResizeGadget(2, 0, 0, GadgetWidth(5)/2, GadgetHeight(5))
ResizeGadget(3, GadgetWidth(5)/2, 0, GadgetWidth(5)/2, GadgetHeight(5))
EndProcedure
Procedure WinResize()
ResizeGadget(6, #PB_Ignore, #PB_Ignore, WindowWidth(0)-10, WindowHeight(0)-10)
EndProcedure
OpenWindow(0, 0, 0, 400, 400, "Splitter", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_ScreenCentered|#PB_Window_Invisible)
ContainerGadget(4, 0, 0, 0, 0, #PB_Container_Flat)
ExplorerListGadget(0, 0, 0, 0, 0, "c:\")
ExplorerListGadget(1, 0, 0, 0, 0, "c:\temp\")
CloseGadgetList()
SetWindowLongPtr_(GadgetID(4), #GWL_STYLE, GetWindowLongPtr_(GadgetID(4), #GWL_STYLE)|#WS_CLIPCHILDREN)
; SetWindowLongPtr_(GadgetID(0), #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID(0), #GWL_EXSTYLE)&~#WS_EX_CLIENTEDGE)
; SetWindowLongPtr_(GadgetID(1), #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID(1), #GWL_EXSTYLE)&~#WS_EX_CLIENTEDGE)
BindGadgetEvent(4, @GadResizeT(), #PB_EventType_Resize)
ContainerGadget(5, 0, 0, 0, 0, #PB_Container_Flat)
EditorGadget(2, 0, 0, 0, 0) : SetGadgetText(2, "c:\")
EditorGadget(3, 0, 0, 0, 0) : SetGadgetText(3, "c:\temp\")
CloseGadgetList()
SetWindowLongPtr_(GadgetID(5), #GWL_STYLE, GetWindowLongPtr_(GadgetID(5), #GWL_STYLE)|#WS_CLIPCHILDREN)
BindGadgetEvent(5, @GadResizeB(), #PB_EventType_Resize)
SplitterGadget(6, 5, 5, 390, 390, 4, 5, #PB_Splitter_Separator)
SetWindowLongPtr_(GadgetID(6), #GWL_STYLE, GetWindowLongPtr_(GadgetID(6), #GWL_STYLE)|#WS_CLIPCHILDREN)
SetGadgetState(6, 250)
BindEvent(#PB_Event_SizeWindow, @WinResize())
HideWindow(0, #False)
While WaitWindowEvent() <> #PB_Event_CloseWindow : WendEt cetera is my worst enemy
Re: SplitterGadget with more than two gadgets
Code: Select all
Procedure.i IDGadget( GadgetID.i ) ; Return the id of the gadget from the gadget handle
If GadgetID
Protected Gadget = GetProp_( GadgetID, "PB_ID" )
If IsGadget( Gadget ) And GadgetID( Gadget ) = GadgetID
ProcedureReturn Gadget
EndIf
ProcedureReturn - 1
Else
ProcedureReturn - 1
EndIf
EndProcedure
Procedure GadgetsClipCallBack( GadgetID, lParam )
; https://www.purebasic.fr/english/viewtopic.php?t=64799
;
; Для виндовс чтобы приклепить гаджеты на место
; надо вызывать процедуру в конце создания всех гаджетов
; надо вызвать после создания всех гаджетов
;
If GadgetID
Protected Gadget = IDGadget(GadgetID)
If GetWindowLongPtr_( GadgetID, #GWL_STYLE ) & #WS_CLIPSIBLINGS = #False
If IsGadget( Gadget )
Select GadgetType( Gadget )
Case #PB_GadgetType_Spin
Protected SpinNext = GetWindow_( GadgetID( gadget ), #GW_HWNDNEXT )
SetWindowLongPtr_( SpinNext, #GWL_STYLE, GetWindowLongPtr_( SpinNext, #GWL_STYLE ) | #WS_CLIPSIBLINGS | #WS_CLIPCHILDREN )
SetWindowPos_( SpinNext, #GW_HWNDFIRST, 0,0,0,0, #SWP_NOMOVE|#SWP_NOSIZE )
Case #PB_GadgetType_Panel
SetWindowLongPtr_( GadgetID( gadget ), #GWL_EXSTYLE, GetWindowLongPtr_( GadgetID( gadget ), #GWL_EXSTYLE ) | #WS_EX_COMPOSITED )
Case #PB_GadgetType_ComboBox
Protected Height = GadgetHeight( Gadget )
; Case #PB_GadgetType_Container
; ; Из-за бага когда устанавливаешь фоновый рисунок (например точки на кантейнер)
; SetGadgetColor( Gadget, #PB_Gadget_BackColor, GetSysColor_( #COLOR_BTNFACE ))
;
; Case #PB_GadgetType_Panel
; ; Для панел гаджета темный фон убирать
; If Not IsGadget( Gadget ) And (GetWindowLongPtr_(GadgetID, #GWL_EXSTYLE) & #WS_EX_TRANSPARENT) = #False
; SetWindowLongPtr_(GadgetID, #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID, #GWL_EXSTYLE) | #WS_EX_TRANSPARENT)
; EndIf
; ; SetClassLongPtr_(GadgetID, #GCL_HBRBACKGROUND, GetStockObject_(#NULL_BRUSH))
EndSelect
EndIf
SetWindowLongPtr_( GadgetID, #GWL_STYLE, GetWindowLongPtr_( GadgetID, #GWL_STYLE ) | #WS_CLIPSIBLINGS | #WS_CLIPCHILDREN )
If Height
ResizeGadget( Gadget, #PB_Ignore, #PB_Ignore, #PB_Ignore, Height )
EndIf
SetWindowPos_( GadgetID, #HWND_TOP, 0,0,0,0, #SWP_NOMOVE | #SWP_NOSIZE )
Else
If IsGadget( Gadget )
Select GadgetType( Gadget )
Case #PB_GadgetType_Panel
SetWindowLongPtr_( GadgetID, #GWL_EXSTYLE, GetWindowLongPtr_( GadgetID, #GWL_EXSTYLE ) | #WS_EX_COMPOSITED )
EndSelect
EndIf
EndIf
EndIf
ProcedureReturn GadgetID
EndProcedure
Procedure ClipGadgets( WindowID )
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
EnumChildWindows_( WindowID, @GadgetsClipCallBack(), 0 )
SetWindowLongPtr_( WindowID, #GWL_STYLE, GetWindowLongPtr_( WindowID, #GWL_STYLE ) | #WS_CLIPSIBLINGS | #WS_CLIPCHILDREN )
SetWindowPos_( WindowID, #HWND_TOP, 0,0,0,0, #SWP_NOMOVE|#SWP_NOSIZE )
CompilerEndIf
EndProcedure
OpenWindow(0,0,0,400,300,"SplitterGadget",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ExplorerListGadget(1,0,0,200,300,"c:\") ; Top left.
EditorGadget(4,0,0,200,300) : SetGadgetText(4,"c:\") ; Bottom left.
EditorGadget(5,200,0,200,300) : SetGadgetText(5,"c:\temp\") ; Bottom right.
SplitterGadget(2,0,0,400,300,4,5,#PB_Splitter_Vertical)
SplitterGadget(6,0,0,400,300,1,2,#PB_Splitter_Separator) ; Separate the top two gadgets from the bottom two.
ClipGadgets(UseGadgetList(0))
Repeat
EventID = WaitWindowEvent()
Until EventID = #PB_Event_CloseWindow
Re: SplitterGadget with more than two gadgets
Nope. Here's what I'm experiencing, which I'd love to avoid:chi wrote: Tue Apr 30, 2024 5:52 pmedit: If you comment this line: BindGadgetEvent(5, @GadResizeB(), #PB_EventType_Resize), is the problem gone?

BTW, I'm using PureBasic 6.10 on Windows 10 Pro, and also testing on Windows 11 Pro. Compiling as 64-bit only.
The visual glitches remain when dragging the SplitterGadget() bar, despite all code variations here to help (which I appreciate very much). But, in the end (for now anyway) I've decided to just have a little shrink/expand button between the two sets of four gadgets, and clicking it will just resize both sets of gadgets to a pre-set size instead (small/large). No glitches and an acceptable compromise.
@Fred: I wonder if there's anything you can do behind-the-scenes when the SplitterGadget() bar is being dragged?
Re: SplitterGadget with more than two gadgets
Since I myself run Window 10 Pro as a VM and do not have this problem, it must be due to your machine or graphics card.
What does your code look like?
When I pull extremely fast, I also experience this for a very short time.
So it must be due to windows and the computing power.
What does your code look like?
When I pull extremely fast, I also experience this for a very short time.
So it must be due to windows and the computing power.
Code: Select all
;-TOP
Procedure UpdateWindow()
Protected dx, dy
dx = WindowWidth(0)
dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
; Resize Gadgets
ResizeGadget(0, 5, 5, dx - 10, dy - 10)
EndProcedure
Procedure Main()
Protected dx, dy
#WinStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
If OpenWindow(0, #PB_Ignore, #PB_Ignore, 600, 400, "Test Window", #WinStyle)
; MenuBar
CreateMenu(0, WindowID(0))
MenuTitle("File")
; StatusBar
CreateStatusBar(0, WindowID(0))
AddStatusBarField(#PB_Ignore)
; Gadgets
dx = WindowWidth(0)
dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
ExplorerListGadget(1, 0, 0, 0, 0, GetUserDirectory(#PB_Directory_Documents))
ExplorerListGadget(2, 0, 0, 0, 0, GetUserDirectory(#PB_Directory_Downloads))
SplitterGadget(0, 5, 5, dx - 10, dy - 10, 1, 2)
; Bind Events
BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), 0)
; Main Loop
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Select EventWindow()
Case 0
Break
EndSelect
Case #PB_Event_Menu
Select EventMenu()
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
EndSelect
EndSelect
ForEver
EndIf
EndProcedure : Main()
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: SplitterGadget with more than two gadgets
That gif was from using Chi's code just above -> https://www.purebasic.fr/english/viewto ... 78#p620278
Damn, so it's just my crappy PCs and/or their video cards? On two different PCs? Great.mk-soft wrote:it must be due to windows and the computing power
Re: SplitterGadget with more than two gadgets
In all of the above examples, not only on your PCs, but also on my PCs, I'm experiencing the issue of afterimages(trailing images) on Windows 10 Home x64.BarryG wrote: Wed May 01, 2024 12:58 pm Damn, so it's just my crappy PCs and/or their video cards? On two different PCs? Great.![]()
This is especially bad when the window is maximized.
Even with subclassing to reduce flicker as much as possible, there are still some drawing issues depending on the child gadget type.
So, I tried using a container gadget to mimic a splitter gadget, but flickering and afterimages occurred there as well.
Anyway, because of this flicker and afterimage, I've been experimenting with 'DirectComposition' in my project and it seems to be working relatively well. It's just that the code has gotten longer and more complex.
Captured image with method 1 applied.

Captured image with method 2 applied. (the image file size is about 1.4 megabytes.)

Code: Select all
#OldWndProc$ = "OldWndProc"
Procedure WndProc_Splitter(hWnd, Message, wParam, lParam)
Protected old = GetProp_(hWnd, #OldWndProc$)
Protected iResult, Gadget, PrevPosXY.l
Select Message
Case #WM_LBUTTONDOWN
Gadget = GetWindowLongPtr_(hWnd, #GWLP_ID)
If GadgetID(Gadget) = hWnd
SetGadgetData(Gadget, lParam)
EndIf
Case #WM_LBUTTONUP
Gadget = GetWindowLongPtr_(hWnd, #GWLP_ID)
If GadgetID(Gadget) = hWnd
SetGadgetData(Gadget, -1)
EndIf
Case #WM_MOUSEMOVE
If wParam = #MK_LBUTTON
Gadget = GetWindowLongPtr_(hWnd, #GWLP_ID)
If GadgetID(Gadget) = hWnd
PrevPosXY = GetGadgetData(Gadget)
If PrevPosXY <> lParam
SetGadgetData(Gadget, lParam)
; Method 1
; Problem 1: When moving the separator on splitter gadget #4, the vertical scroll bar on gadget #0 has a slight afterimage.
; Problem 2: When moving the separator on splitter gadget #6, the bottom part of both editor gadgets draws slowly.
iResult = CallWindowProc_(old, hWnd, Message, wParam, lParam)
UpdateWindow_(hWnd)
; Method 2
; The problem 2 is solved, but the vertical scroll bar on gadget #0 has a bad afterimage, and the left part of gadget #1 draws slowly.
;SendMessage_(hWnd, #WM_SETREDRAW, 0, 0)
;iResult = CallWindowProc_(old, hWnd, Message, wParam, lParam)
;SendMessage_(hWnd, #WM_SETREDRAW, 1, 0)
;RedrawWindow_(hWnd, 0, 0, #RDW_ALLCHILDREN | #RDW_FRAME | #RDW_ERASE | #RDW_INVALIDATE | #RDW_UPDATENOW)
ProcedureReturn iResult
Else
ProcedureReturn 0
EndIf
EndIf
EndIf
Case #WM_NCDESTROY
RemoveProp_(hWnd, #OldWndProc$)
EndSelect
ProcedureReturn CallWindowProc_(old, hWnd, Message, wParam, lParam)
EndProcedure
Procedure WinResize()
ResizeGadget(6, #PB_Ignore, #PB_Ignore, WindowWidth(0)-10, WindowHeight(0)-10)
EndProcedure
OpenWindow(0, 0, 0, 400, 400, "Splitter", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_ScreenCentered|#PB_Window_Invisible)
ExplorerListGadget(0, 0, 0, 0, 0, "c:\")
SetGadgetItemAttribute(0, 0, #PB_Explorer_ColumnWidth, 800, 3)
ExplorerListGadget(1, 0, 0, 0, 0, "c:\")
EditorGadget(2, 0, 0, 0, 0) : SetGadgetText(2, "c:\")
EditorGadget(3, 0, 0, 0, 0) : SetGadgetText(3, "c:\temp\")
SplitterGadget(4, 0, 0, 400, 200, 0, 1, #PB_Splitter_Vertical)
SplitterGadget(5, 0, 200, 400, 200, 2, 3, #PB_Splitter_Vertical)
SplitterGadget(6, 5, 5, 390, 390, 4, 5, #PB_Splitter_Separator)
SetGadgetState(6, 250)
hWnd = GadgetID(4)
SetWindowLongPtr_(hWnd, #GWL_STYLE, GetWindowLongPtr_(hWnd, #GWL_STYLE) | #WS_CLIPCHILDREN)
SetProp_(hWnd, #OldWndProc$, SetWindowLongPtr_(hWnd, #GWLP_WNDPROC, @WndProc_Splitter()))
hWnd = GadgetID(5)
SetWindowLongPtr_(hWnd, #GWL_STYLE, GetWindowLongPtr_(hWnd, #GWL_STYLE) | #WS_CLIPCHILDREN)
SetProp_(hWnd, #OldWndProc$, SetWindowLongPtr_(hWnd, #GWLP_WNDPROC, @WndProc_Splitter()))
hWnd = GadgetID(6)
SetWindowLongPtr_(hWnd, #GWL_STYLE, GetWindowLongPtr_(hWnd, #GWL_STYLE) | #WS_CLIPCHILDREN)
SetProp_(hWnd, #OldWndProc$, SetWindowLongPtr_(hWnd, #GWLP_WNDPROC, @WndProc_Splitter()))
BindEvent(#PB_Event_SizeWindow, @WinResize())
HideWindow(0, #False)
SetWindowState(0, #PB_Window_Maximize)
While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
Re: SplitterGadget with more than two gadgets
Maybe try this one, when dragging the SplitterGadget(), the 2 Splitter child gadgets are replaced with captured images with WM_PRINT message
On left button up, the splitter's child gadgets are restored
On left button up, the splitter's child gadgets are restored
Code: Select all
Global ResizeSplitter
Procedure BindSplitter()
Static SplitterPos, ImgGadgetChild1, ImgChild1 = #PB_Default, ImgGadgetChild2, ImgChild2 = #PB_Default
Protected Position, hDC
Position = GetGadgetState(EventGadget())
If Not Position = SplitterPos
SplitterPos = Position
SendMessage_(GadgetID(EventGadget()), #WM_SETREDRAW, #True, 0)
If Not ResizeSplitter
If ImgChild1 = #PB_Default
ImgChild1 = CreateImage(#PB_Any, 1, 1)
ImgGadgetChild1 = ImageGadget(#PB_Any, 0, 0, 0, 0, 0)
EndIf
If ImgChild2 = #PB_Default
ImgChild2 = CreateImage(#PB_Any, 1, 1)
ImgGadgetChild2 = ImageGadget(#PB_Any, 0, 0, 0, 0, 0)
EndIf
HideGadget(0, #True) : HideGadget(3, #True)
SetGadgetAttribute(EventGadget(), #PB_Splitter_FirstGadget, ImgGadgetChild1)
SetGadgetAttribute(EventGadget(), #PB_Splitter_SecondGadget, ImgGadgetChild2)
HideGadget(ImgGadgetChild1, #False) : HideGadget(ImgGadgetChild2, #False)
ResizeSplitter = #True
EndIf
If GadgetWidth(ImgGadgetChild1) And GadgetHeight(ImgGadgetChild1)
ResizeGadget(0, #PB_Ignore, #PB_Ignore, GadgetWidth(ImgGadgetChild1), GadgetHeight(ImgGadgetChild1))
ResizeImage(ImgChild1, DesktopScaledX(GadgetWidth(ImgGadgetChild1)), DesktopScaledY(GadgetHeight(ImgGadgetChild1)))
ResizeGadget(1, 0, 0, GadgetWidth(ImgGadgetChild1)/2, GadgetHeight(ImgGadgetChild1))
ResizeGadget(2, GadgetWidth(1), 0, GadgetWidth(ImgGadgetChild1)-GadgetWidth(1), GadgetHeight(ImgGadgetChild1))
hDC = StartDrawing(ImageOutput(ImgChild1))
If hDC
SendMessage_(GadgetID(0), #WM_PRINT, hDC, #PRF_CHILDREN | #PRF_CLIENT | #PRF_NONCLIENT | #PRF_OWNED | #PRF_ERASEBKGND)
StopDrawing()
EndIf
SetGadgetState(ImgGadgetChild1, ImageID(ImgChild1))
Else
SetGadgetState(ImgGadgetChild1, 0)
EndIf
If GadgetWidth(ImgGadgetChild2) And GadgetHeight(ImgGadgetChild2)
ResizeGadget(3, #PB_Ignore, #PB_Ignore, GadgetWidth(ImgGadgetChild2), GadgetHeight(ImgGadgetChild2))
ResizeImage(ImgChild2, DesktopScaledX(GadgetWidth(ImgGadgetChild2)), DesktopScaledY(GadgetHeight(ImgGadgetChild2)))
ResizeGadget(4, 0, 0, GadgetWidth(ImgGadgetChild2)/2, GadgetHeight(ImgGadgetChild2))
ResizeGadget(5, GadgetWidth(4), 0, GadgetWidth(ImgGadgetChild2)-GadgetWidth(4), GadgetHeight(ImgGadgetChild2))
hDC = StartDrawing(ImageOutput(ImgChild2))
If hDC
SendMessage_(GadgetID(3), #WM_PRINT, hDC, #PRF_CHILDREN | #PRF_CLIENT | #PRF_NONCLIENT | #PRF_OWNED | #PRF_ERASEBKGND)
StopDrawing()
EndIf
SetGadgetState(ImgGadgetChild2, ImageID(ImgChild2))
Else
SetGadgetState(ImgGadgetChild2, 0)
EndIf
UpdateWindow_(GadgetID(EventGadget()))
Else
SendMessage_(GadgetID(EventGadget()), #WM_SETREDRAW, #False, 0)
;Debug "Event received with same Splitter position"
EndIf
EndProcedure
Procedure WinResize()
ResizeGadget(6, #PB_Ignore, #PB_Ignore, WindowWidth(0), WindowHeight(0))
EndProcedure
OpenWindow(0, 0, 0, 400, 300, "SplitterGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
ContainerGadget(0, 0, 0, 400, 150)
ExplorerListGadget(1, 0, 0, 200, 150, "c:\") ; Top left.
ExplorerListGadget(2, 200, 0, 200, 150, "c:\temp\") ; Top right.
CloseGadgetList()
;SetWindowLongPtr_(GadgetID(0), #GWL_STYLE, GetWindowLongPtr_(GadgetID(0), #GWL_STYLE) | #WS_CLIPCHILDREN)
ContainerGadget(3, 0, 150, 400, 150)
EditorGadget(4, 0, 0, 200, 150) : SetGadgetText(4, "c:\") ; Bottom left.
EditorGadget(5, 200, 0, 200, 150) : SetGadgetText(5, "c:\temp\") ; Bottom right.
CloseGadgetList()
;SetWindowLongPtr_(GadgetID(3), #GWL_STYLE, GetWindowLongPtr_(GadgetID(3), #GWL_STYLE) | #WS_CLIPCHILDREN)
SplitterGadget(6, 0, 0, 400, 300, 0, 3, #PB_Splitter_Separator) ; Separate the top two gadgets from the bottom two.
BindGadgetEvent(6, @BindSplitter())
BindEvent(#PB_Event_SizeWindow, @WinResize())
Repeat
EventID = WaitWindowEvent()
If ResizeSplitter = #True
;Better here than using #WM_LBUTTONUP when an event is sent following a resize, without a left button up
;32768 Or $8000: the most significant bit is set. If the high-order bit is 1, the key is down, otherwise, it is up.
If Not (GetKeyState_(#VK_LBUTTON) & 32768)
HideGadget(GetGadgetAttribute(6, #PB_Splitter_FirstGadget), #True)
HideGadget(GetGadgetAttribute(6, #PB_Splitter_SecondGadget), #True)
SetGadgetAttribute(6, #PB_Splitter_FirstGadget, 0)
SetGadgetAttribute(6, #PB_Splitter_SecondGadget, 3)
HideGadget(0, #False) : HideGadget(3, #False)
SendMessage_(GadgetID(6), #WM_SETREDRAW, #True, 0)
RedrawWindow_(GadgetID(6), #Null, #Null, #RDW_INVALIDATE | #RDW_ERASENOW | #RDW_ALLCHILDREN | #RDW_UPDATENOW)
ResizeSplitter = #False
EndIf
EndIf
Until EventID = #PB_Event_CloseWindow
Re: SplitterGadget with more than two gadgets
Both breeze4me's and ChrisR's new codes above have fixed it! No glitching anymore with either version. THANK YOU! 
Re: SplitterGadget with more than two gadgets
Your crappy PCs seem to be a racing beast, keep it, nothing better to test flickeringBarryG wrote: Wed May 01, 2024 12:58 pm Damn, so it's just my crappy PCs and/or their video cards? On two different PCs? Great.
I had also requested an improvement here: Less paint & events for the SplitterGadgetBarryG wrote: Wed May 01, 2024 11:27 am @Fred: I wonder if there's anything you can do behind-the-scenes when the SplitterGadget() bar is being dragged?
I think the SplitterGadget is receiving too many messages and there are too many redraws done,
It seems to be for all mouse movements, it seems to me that it shouldn't.
For a horizontal splitter, a horizontal mouse movement should not send an event, redraws (same for Vertical)
Also, no event should be sent if the mouse position is less than the minimum Splitter position or greater than the maximum Splitter value.
I think it could be improved with a message, redraw, only if the size of 1 of the 2 child gadgets has changed.
I don't know the internals and I may be wrong, otherwise it would be good for reducing flicker.
Re: SplitterGadget with more than two gadgets
Well I've got it solved with your new code above, so maybe it's not my PCs at all. Just too many SplitterGadget() events like you said.
Re: SplitterGadget with more than two gadgets
I wonder why ResizeGadget is so much slower than SetWindowPos...
Code: Select all
#USEWINAPI = 1
Procedure GadResizeT()
CompilerSelect #USEWINAPI
CompilerCase 0
ResizeGadget(0, 0, 0, GadgetWidth(4)/2, GadgetHeight(4))
ResizeGadget(1, GadgetWidth(4)/2, 0, GadgetWidth(4)/2, GadgetHeight(4))
CompilerCase 1
SetWindowPos_(GadgetID(0), 0, 0, 0, GadgetWidth(4)/2, GadgetHeight(4), #SWP_NOMOVE|#SWP_NOZORDER|#SWP_NOACTIVATE)
SetWindowPos_(GadgetID(1), 0, GadgetWidth(4)/2, 0, GadgetWidth(4)/2, GadgetHeight(4), #SWP_NOZORDER|#SWP_NOACTIVATE)
CompilerEndSelect
EndProcedure
Procedure GadResizeB()
CompilerSelect #USEWINAPI
CompilerCase 0
ResizeGadget(2, 0, 0, GadgetWidth(5)/2, GadgetHeight(5))
ResizeGadget(3, GadgetWidth(5)/2, 0, GadgetWidth(5)/2, GadgetHeight(5))
CompilerCase 1
SetWindowPos_(GadgetID(2), 0, 0, 0, GadgetWidth(5)/2, GadgetHeight(5), #SWP_NOMOVE|#SWP_NOZORDER|#SWP_NOACTIVATE)
SetWindowPos_(GadgetID(3), 0, GadgetWidth(5)/2, 0, GadgetWidth(5)/2, GadgetHeight(5), #SWP_NOZORDER|#SWP_NOACTIVATE)
CompilerEndSelect
EndProcedure
Procedure WinResize()
CompilerSelect #USEWINAPI
CompilerCase 0
ResizeGadget(6, #PB_Ignore, #PB_Ignore, WindowWidth(0)-10, WindowHeight(0)-10)
CompilerCase 1
SetWindowPos_(GadgetID(6), 0, 0, 0, WindowWidth(0)-10, WindowHeight(0)-10, #SWP_NOMOVE|#SWP_NOZORDER|#SWP_NOACTIVATE)
CompilerEndSelect
EndProcedure
OpenWindow(0, 0, 0, 750, 500, "Splitter", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_ScreenCentered|#PB_Window_Invisible)
ContainerGadget(4, 0, 0, 0, 0)
ExplorerListGadget(0, 0, 0, 0, 0, "c:\windows\")
ExplorerListGadget(1, 0, 0, 0, 0, "c:\program files\")
CloseGadgetList()
SetWindowLongPtr_(GadgetID(4), #GWL_STYLE, GetWindowLongPtr_(GadgetID(4), #GWL_STYLE)|#WS_CLIPCHILDREN)
BindGadgetEvent(4, @GadResizeT(), #PB_EventType_Resize)
ContainerGadget(5, 0, 0, 0, 0)
EditorGadget(2, 0, 0, 0, 0) : SetGadgetText(2, "c:\windows\")
EditorGadget(3, 0, 0, 0, 0) : SetGadgetText(3, "c:\program files\")
CloseGadgetList()
SetWindowLongPtr_(GadgetID(5), #GWL_STYLE, GetWindowLongPtr_(GadgetID(5), #GWL_STYLE)|#WS_CLIPCHILDREN)
BindGadgetEvent(5, @GadResizeB(), #PB_EventType_Resize)
SplitterGadget(6, 5, 5, 390, 390, 4, 5, #PB_Splitter_Separator)
SetWindowLongPtr_(GadgetID(6), #GWL_STYLE, GetWindowLongPtr_(GadgetID(6), #GWL_STYLE)|#WS_CLIPCHILDREN)
SetGadgetState(6, 250)
BindEvent(#PB_Event_SizeWindow, @WinResize())
HideWindow(0, #False)
While WaitWindowEvent() <> #PB_Event_CloseWindow : WendEt cetera is my worst enemy



