Gadget Dock Include
- HeX0R
- Beiträge: 3042
- Registriert: 10.09.2004 09:59
- Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3 - Kontaktdaten:
{Home}.:|:.{Codes}.:|:.{Downloads}.:|:.{History Viewer Online}.:|:.{Bier spendieren}
lässt sich nicht ganz vergleichen, denn das Docking hat in diesem Fall DotNetHeX0R hat geschrieben:Kiffi hatte doch soetwas in der Art schon mal angefangen (*denk*)
übernommen und beim Speichern (ins PB-Format) wäre das es eh nicht
konvertiert worden.
Aber die Idee, ein bereits bestehendes Format (wie XAML) zu verwenden
(und kein neues Format zu erfinden), würde ich begrüssen.
Grüße ... Kiffi
a²+b²=mc²
Also irgendwo lag der Fehler in den DockLeft(...), DockRight(D...), Bottom(...), DockFill(...) - Befehlen. Wenn du die nochmal durchgehst oder bei meinem Code überprüfst, müsste dir da etwas auffallen. Ich hab im moment leider keine Zeit.milan1612 hat geschrieben:EDIT: Könntest du die Bugs die du gefunden hast mal kurz erläutern, dass
ich sie in meine Version mit einbauen kann?
sory
So, hab ganz vergessen das die 2. Version schon länger fertig ist.
Komplett neugeschrieben und (hoffentlich) ein bisschen schneller.
Das Grundkonzept bleibt das gleiche, allerdings ist die Bedienung jetzt etwas
komplizierter. Einfach mal das Beispiel anschauen oder die Include durchforsten.
Sollte einigermaßen gut kommentiert sein...
Die Include:
Und ein kleines Beispiel:
Bitte nicht hauen falls was nicht funktionieren sollte (ist schon ne Weile her) 
Komplett neugeschrieben und (hoffentlich) ein bisschen schneller.
Das Grundkonzept bleibt das gleiche, allerdings ist die Bedienung jetzt etwas
komplizierter. Einfach mal das Beispiel anschauen oder die Include durchforsten.
Sollte einigermaßen gut kommentiert sein...
Die Include:
Code: Alles auswählen
;PureBasic Dock Include
;Second Edition
;Copyright 2008 - milan1612
;milan1612@gmx.de
EnableExplicit
;-== Public Interface ======================================
Enumeration
#DockNone
#DockLeft
#DockRight
#DockTop
#DockBottom
#DockFill
EndEnumeration
Structure Dock
DockState.l
MarginLeft.l
MarginRight.l
MarginTop.l
MarginBottom.l
RedrawOnCall.l
AntiFlicker.l
EndStructure
DeclareDLL SetGadgetDock(Gadget.l, *Options.Dock)
DeclareDLL IsGadgetDocked(Gadget.l)
;-== Implementation =========================================
;Internal Declarations
Declare UpdateDockInfo(Gadget.l, *Options.Dock)
Declare DockSubclassParent(Gadget.l)
Declare DockWindowCallback(WindowID.l, Message.l, wParam.l, lParam.l)
Declare FreeGadgetInfoCallback(GadgetID.l, UnUsed.l)
Declare CalculateClientArea(WindowID.l, *Rect.RECT)
Declare StatusToolBarEnumCallback(WindowID.l, Parent.l)
Declare DockGadgets(WindowID.l)
Declare DockEnumCallback(GadgetID.l, *Rect.RECT)
;Main Initialization Procedure (see Dock Structure above)
ProcedureDLL SetGadgetDock(Gadget.l, *Options.Dock)
Protected *MemID.Dock
If *Options
If Not IsGadget(Gadget) : ProcedureReturn 0 : EndIf
If IsGadgetDocked(Gadget)
If *Options\DockState = #DockNone
*MemID = GetProp_(GadgetID(Gadget), @"_DockInfo")
If *MemID
FreeMemory(*MemID)
RemoveProp_(GadgetID(Gadget), @"_DockInfo")
EndIf
Else
UpdateDockInfo(Gadget, *Options)
EndIf
ProcedureReturn 1
EndIf
*MemID = AllocateMemory(SizeOf(Dock))
If *MemID
DockSubclassParent(Gadget)
CopyMemory(*Options, *MemID, SizeOf(Dock))
SetProp_(GadgetID(Gadget), @"_DockInfo", *MemID)
EnumChildWindows_(GetParent_(GadgetID(Gadget)), @StatusToolBarEnumCallback(), GetParent_(GadgetID(Gadget)))
If *Options\RedrawOnCall
SendMessage_(GetParent_(GadgetID(Gadget)), #WM_SIZE, 0, 0)
InvalidateRect_(GetParent_(GadgetID(Gadget)), 0, 0)
EndIf
If Not GetWindowLong_(GetParent_(GadgetID(Gadget)), #GWL_STYLE) & #WS_CLIPCHILDREN
SetWindowLong_(GetParent_(GadgetID(Gadget)), #GWL_STYLE, GetWindowLong_(GetParent_(GadgetID(Gadget)), #GWL_STYLE) | #WS_CLIPCHILDREN)
EndIf
If GadgetType(Gadget) = #PB_GadgetType_Frame3D
If Not GetWindowLong_(GadgetID(Gadget), #GWL_EXSTYLE) & #WS_EX_TRANSPARENT
SetWindowLong_(GadgetID(Gadget), #GWL_EXSTYLE, GetWindowLong_(GadgetID(Gadget), #GWL_EXSTYLE) | #WS_EX_TRANSPARENT)
EndIf
EndIf
If GadgetType(Gadget) = #PB_GadgetType_Panel
If Not GetWindowLong_(GadgetID(Gadget), #GWL_EXSTYLE) & #WS_EX_COMPOSITED
SetWindowLong_(GadgetID(Gadget), #GWL_EXSTYLE, GetWindowLong_(GadgetID(Gadget), #GWL_EXSTYLE) | #WS_EX_COMPOSITED)
EndIf
EndIf
EndIf
Else
ProcedureReturn 0
EndIf
ProcedureReturn 1
EndProcedure
;Checks if the gadget is docked, if true it returns the address to the stored dockinfo
ProcedureDLL IsGadgetDocked(Gadget.l)
If IsGadget(Gadget)
ProcedureReturn GetProp_(GadgetID(Gadget), @"_DockInfo")
Else
ProcedureReturn 0
EndIf
EndProcedure
;-== Internals ==============================================
;Updates the stored dockinfo
Procedure UpdateDockInfo(Gadget.l, *Options.Dock)
Protected *MemID.Dock
*MemID = GetProp_(GadgetID(Gadget), @"_DockInfo")
If *MemID
CopyMemory(*Options, *MemID, SizeOf(Dock))
EndIf
EndProcedure
;Subclasses (if necessary) the parent of the child
Procedure DockSubclassParent(Gadget.l)
Protected ParentHandle.l
Protected OldProc.l
ParentHandle = GetParent_(GadgetID(Gadget))
OldProc = GetProp_(ParentHandle, @"_OldProcAddress")
If Not OldProc
OldProc = SetWindowLong_(ParentHandle, #GWL_WNDPROC, @DockWindowCallback())
SetProp_(ParentHandle, @"_OldProcAddress", OldProc)
EndIf
EndProcedure
;The gadgets parent callback
Procedure DockWindowCallback(WindowID.l, Message.l, wParam.l, lParam.l)
Protected OldProc.l
Protected Result.l
Protected Buffer.s
OldProc = GetProp_(WindowID, @"_OldProcAddress")
Select Message
Case #WM_DESTROY
EnumChildWindows_(WindowID, @FreeGadgetInfoCallback(), 1)
Case #WM_NCDESTROY
RemoveProp_(WindowID, @"_OldProcAddress")
Case #WM_SIZE
DockGadgets(WindowID)
Case #WM_PARENTNOTIFY
If wParam & $FFFF = #WM_CREATE Or wParam & $FFFF = #WM_DESTROY
Buffer = Space(100)
If GetClassName_(lParam, @Buffer, 100)
Buffer = LCase(Buffer)
If Buffer = "toolbarwindow32"
If wParam & $FFFF = #WM_CREATE
SetProp_(WindowID, @"_ToolBarHandle", lParam)
Else
RemoveProp_(WindowID, @"_ToolBarHandle")
EndIf
ElseIf Buffer = "msctls_statusbar32"
If wParam & $FFFF = #WM_CREATE
SetProp_(WindowID, @"_StatusBarHandle", lParam)
Else
RemoveProp_(WindowID, @"_StatusBarHandle")
EndIf
EndIf
EndIf
EndIf
Default
Result = CallWindowProc_(OldProc, WindowID, Message, wParam, lParam)
EndSelect
ProcedureReturn Result
EndProcedure
;EnumChildWindows Callback to free the stored memory of the gadgets when destroyed
Procedure FreeGadgetInfoCallback(GadgetID.l, UnUsed.l)
Protected *DockID.Dock
*DockID = GetProp_(GadgetID, @"_DockInfo")
If *DockID
FreeMemory(*DockID)
RemoveProp_(GadgetID, @"_DockInfo")
EndIf
ProcedureReturn 1
EndProcedure
;Calculates the rectangle that is then used to position the gadgets
Procedure CalculateClientArea(WindowID.l, *Rect.RECT)
Protected StatusBar, ToolBar
Protected TempRect.RECT
GetClientRect_(WindowID, *Rect.RECT)
StatusBar = GetProp_(WindowID, @"_StatusBarHandle")
ToolBar = GetProp_(WindowID, @"_ToolBarHandle")
If ToolBar
GetWindowRect_(ToolBar, @TempRect)
*Rect\top + (TempRect\bottom - TempRect\top) + 2
SendMessage_(ToolBar, #WM_SIZE, 0, 0)
EndIf
If StatusBar
GetWindowRect_(StatusBar, @TempRect)
*Rect\bottom - (TempRect\bottom - TempRect\top)
SendMessage_(StatusBar, #WM_SIZE, 0, 0)
EndIf
EndProcedure
;EnumChildWindows Callback to find & identify possible status- and toolbars
Procedure StatusToolBarEnumCallback(WindowID.l, Parent.l)
Protected Buffer.s = Space(100)
If GetClassName_(WindowID, @Buffer, 100)
Buffer = LCase(Buffer)
If Buffer = "toolbarwindow32"
SetProp_(Parent, @"_ToolBarHandle", WindowID)
ElseIf Buffer = "msctls_statusbar32"
SetProp_(Parent, @"_StatusBarHandle", WindowID)
EndIf
EndIf
ProcedureReturn 1
EndProcedure
;Handles the entire dock process
Procedure DockGadgets(WindowID.l)
Protected Rect.RECT
LockWindowUpdate_(WindowID)
CalculateClientArea(WindowID, @Rect)
EnumChildWindows_(WindowID, @DockEnumCallback(), @Rect)
LockWindowUpdate_(0)
UpdateWindow_(WindowID)
EndProcedure
;EnumChildWindows Callback to dock the gadgets
;Warning: Enumerates Child-childs as well (todo)
Procedure DockEnumCallback(GadgetID.l, *Rect.RECT)
Protected *Info.Dock
Protected GadgetX, GadgetY, GadgetW, GadgetH
Protected GadgetRect.RECT
*Info = GetProp_(GadgetID, @"_DockInfo")
If *Info
GetWindowRect_(GadgetID, @GadgetRect)
If *Info\AntiFlicker
SendMessage_(GadgetID, #WM_SETREDRAW, 0, 0)
EndIf
Select *Info\DockState
Case #DockLeft
GadgetX = *Rect\left + *Info\MarginLeft
GadgetY = *Rect\top + *Info\MarginTop
GadgetW = GadgetRect\right - GadgetRect\left
GadgetH = *Rect\bottom - *Rect\top - *Info\MarginTop - *Info\MarginBottom
*Rect\left = *Rect\left + *Info\MarginLeft + (GadgetRect\right - GadgetRect\left) + *Info\MarginRight
Case #DockRight
GadgetX = (*Rect\right - (GadgetRect\right - GadgetRect\left)) - *Info\MarginRight
GadgetY = *Rect\top + *Info\MarginTop
GadgetW = GadgetRect\right - GadgetRect\left
GadgetH = (*Rect\bottom - *Rect\top) - (*Info\MarginTop + *Info\MarginBottom)
*Rect\right = *Rect\right - (*Info\MarginRight + *Info\MarginLeft) - (GadgetRect\right - GadgetRect\left)
Case #DockTop
GadgetX = *Rect\left + *Info\MarginLeft
GadgetY = *Rect\top + *Info\MarginTop
GadgetW = (*Rect\right - *Rect\left) - (*Info\MarginLeft + *Info\MarginRight)
GadgetH = GadgetRect\bottom - GadgetRect\top
*Rect\top = *Rect\top + *Info\MarginTop + (GadgetRect\bottom - GadgetRect\top) + *Info\MarginBottom
Case #DockBottom
GadgetX = *Rect\left + *Info\MarginLeft
GadgetY = *Rect\bottom - (GadgetRect\bottom - GadgetRect\top) - *Info\MarginBottom
GadgetW = *Rect\right - *Rect\left - *Info\MarginLeft - *Info\MarginRight
GadgetH = (GadgetRect\bottom - GadgetRect\top)
*Rect\bottom = *Rect\bottom - (*Info\MarginBottom + *Info\MarginTop + (GadgetRect\bottom - GadgetRect\top))
Case #DockFill
GadgetX = *Rect\left + *Info\MarginLeft
GadgetY = *Rect\top + *Info\MarginTop
GadgetW = *Rect\right - *Rect\left - *Info\MarginLeft - *Info\MarginRight
GadgetH = *Rect\bottom - *Rect\top - *Info\MarginTop - *Info\MarginBottom
EndSelect
MoveWindow_(GadgetID, GadgetX, GadgetY, GadgetW, GadgetH, 1)
If *Info\AntiFlicker
SendMessage_(GadgetID, #WM_SIZE, 0, 0)
SendMessage_(GadgetID, #WM_SETREDRAW, 1, 0)
InvalidateRect_(GadgetID, 0, 0)
EndIf
EndIf
ProcedureReturn 1
EndProcedure
Code: Alles auswählen
;IncludeFile "Dock.pb"
#Flags = #PB_Window_MaximizeGadget|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_SystemMenu
OpenWindow(0, 0, 0, 630, 480, "Dock Example", #Flags)
CreateGadgetList(WindowID(0))
ButtonGadget(0, 0, 0, 80, 20, "Left")
ButtonGadget(1, 0, 0, 80, 20, "Right")
ButtonGadget(2, 0, 0, 80, 40, "Top")
ButtonGadget(3, 0, 0, 80, 40, "Bottom")
ButtonGadget(4, 0, 0, 80, 20, "Fill")
Define info.Dock
info\DockState = #DockLeft
info\MarginLeft = 2
info\MarginTop = 2
info\MarginBottom = 2
info\AntiFlicker = 1
SetGadgetDock(0, @info)
ZeroMemory_(@info, SizeOf(Dock))
info\DockState = #DockRight
info\MarginRight = 2
info\MarginTop = 2
info\MarginBottom = 2
info\AntiFlicker = 1
SetGadgetDock(1, @info)
ZeroMemory_(@info, SizeOf(Dock))
info\DockState = #DockTop
info\MarginLeft = 2
info\MarginRight = 2
info\MarginTop = 2
info\AntiFlicker = 1
SetGadgetDock(2, @info)
ZeroMemory_(@info, SizeOf(Dock))
info\DockState = #DockBottom
info\MarginLeft = 2
info\MarginRight = 2
info\MarginBottom = 2
info\AntiFlicker = 1
SetGadgetDock(3, @info)
ZeroMemory_(@info, SizeOf(Dock))
info\DockState = #DockFill
info\MarginLeft = 2
info\MarginRight = 2
info\MarginBottom = 2
info\MarginTop = 2
info\RedrawOnCall = 1
info\AntiFlicker = 1
SetGadgetDock(4, @info)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Bin nur noch sehr selten hier, bitte nur noch per PN kontaktieren
da komme ich doch glatt mal mit meinem Code, den ich auch schonmilan1612 hat geschrieben:So, hab ganz vergessen das die 2. Version schon länger fertig ist.
beim letzten Test verwendet habe:
Code: Alles auswählen
TreeGadget (1, 0, 0, 100, 40)
ListViewGadget(2, 0, 0, 80, 100)
EditorGadget (3, 0, 0, 80, 50)
Define info.Dock
info\DockState = #DockLeft
info\MarginLeft = 2
info\MarginTop = 2
info\MarginBottom = 2
info\AntiFlicker = 1
SetGadgetDock(1, @info)
ZeroMemory_(@info, SizeOf(Dock))
info\DockState = #DockTop
info\MarginRight = 2
info\MarginTop = 2
info\MarginBottom = 2
info\AntiFlicker = 1
SetGadgetDock(2, @info)
ZeroMemory_(@info, SizeOf(Dock))
info\DockState = #DockFill
info\MarginLeft = 2
info\MarginRight = 2
info\MarginTop = 2
info\AntiFlicker = 1
SetGadgetDock(3, @info)

BTW: AntiFlicker = 1 -> Ich kann mir jetzt nicht vorstellen, dass das
jemand freiwillig auf 0 stellt. Ich würde es als Parameter rausnehmen und
generell mit AntiFlicker arbeiten

Grüße ... Kiffi
a²+b²=mc²
Ist ja auch logisch weil du RedrawOnCall bei deinem letzten Gadget vergessen hastKiffi hat geschrieben: also, irgendwie sieht das ein wenig merkwürdig aus...![]()

Dieses Flag hab ich eingebaut damit wenn man mehrere Gadgets "dockt" nicht bei
jedem Aufruf neu gezeichnet werden muss.
Da es bei verschiedenen Gadgets noch Probleme mit dem Flackern gibt, lass ichKiffi hat geschrieben: BTW: AntiFlicker = 1 -> Ich kann mir jetzt nicht vorstellen, dass das
jemand freiwillig auf 0 stellt. Ich würde es als Parameter rausnehmen und
generell mit AntiFlicker arbeiten
es erstmal noch drin, damit man notfalls selbst Hand anlegen kann...
Milan
Bin nur noch sehr selten hier, bitte nur noch per PN kontaktieren
- FGK
- Beiträge: 249
- Registriert: 09.01.2005 14:02
- Computerausstattung: i5-4430 CPU / 8GB RAM
GeForce GT630
Windows 10 Home / 64-bit - Wohnort: Augsburg
@milan1612
Geniale Sache dein Include
Aber, kann es sein daß Panelgadgets nicht richtig redrawed werden?
oder hab ich was falsch angegeben?
Gruß FGK
Geniale Sache dein Include

Aber, kann es sein daß Panelgadgets nicht richtig redrawed werden?
oder hab ich was falsch angegeben?
Code: Alles auswählen
IncludeFile "Dock.pb"
#Flags = #PB_Window_MaximizeGadget|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_SystemMenu
OpenWindow(0, 0, 0, 630, 480, "Dock Example", #Flags)
CreateGadgetList(WindowID(0))
TreeGadget (1, 0, 0, 100, 40)
ListViewGadget(2, 0, 0, 80, 100)
ContainerGadget(4,0,0,300,50)
SetGadgetColor(4,#PB_Gadget_BackColor,RGB(0,255,100))
ButtonGadget (3, 0, 0, 80, 25,"Hallo")
CloseGadgetList()
ButtonGadget (5, 0, 0, 80, 50,"Hallo 2")
Define info.Dock
info\DockState = #DockLeft
info\MarginLeft = 2
info\MarginTop = 2
info\MarginBottom = 2
info\AntiFlicker = 1
SetGadgetDock(1, @info)
ZeroMemory_(@info, SizeOf(Dock))
info\DockState = #DockTop
info\MarginRight = 2
info\MarginTop = 2
info\MarginBottom = 2
info\AntiFlicker = 1
SetGadgetDock(2, @info)
ZeroMemory_(@info, SizeOf(Dock))
info\DockState = #DockBottom
info\MarginLeft = 10
info\MarginRight = 10
info\MarginTop = 10
info\AntiFlicker = 1
info\RedrawOnCall = 1
SetGadgetDock(4, @info)
ZeroMemory_(@info, SizeOf(Dock))
info\DockState = #DockRight
info\MarginLeft = 2
info\MarginRight = 2
info\MarginTop = 2
info\AntiFlicker = 1
SetGadgetDock(3, @info)
ZeroMemory_(@info, SizeOf(Dock))
info\DockState = #DockFill
info\MarginLeft = 2
info\MarginRight = 2
info\MarginTop = 2
info\AntiFlicker = 1
info\RedrawOnCall = 1
SetGadgetDock(5, @info)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow