Post by Walt Decker on Jan 25, 2021 13:06:19 GMT -5
I have solved two problems. With the exception of a tab that contains a composite window (a composite window is one that has two or more windows embedded in it) the windows can be closed in any order without generating error 16r591. If there is a composite window that window must be closed AFTER its embedded windows.
To solve the LB style problem I created method "SetWinStyle". While doing so I added methods "FN_GetTabCount", "DeleteTab", and "CloseTab".
The parameters and notes concerning each method are in "TAB_CONTROL.txt" which is included in the attached ZIP file.
I have found that, while in the LB code editor, on closing the tab control handle, e. g. CLOSE #TAB, the dll is not actually released (DLL_PROCESS_DETACH is not sent) until the editor is closed. The tab control is released when its parent is closed with the system kill button. This might cause a problem if too many instances of the dll are loaded. I do not know if the problem exists when running a .TKN.
At some point a window with controls will probably be required that the tab control cannot fully accomodate. This can be allieviated by using the Windows system scroll bars. Since LB has no method to allow the programmer to monitor the system scroll bars I have included the "SCROLLWIDG" dll in the attached zip file. Methods for using are included in "TAB_CONTROL.txt."
TABCTL_DLL_UPDATE.ZIP (49.3 KB)
To solve the LB style problem I created method "SetWinStyle". While doing so I added methods "FN_GetTabCount", "DeleteTab", and "CloseTab".
The parameters and notes concerning each method are in "TAB_CONTROL.txt" which is included in the attached ZIP file.
I have found that, while in the LB code editor, on closing the tab control handle, e. g. CLOSE #TAB, the dll is not actually released (DLL_PROCESS_DETACH is not sent) until the editor is closed. The tab control is released when its parent is closed with the system kill button. This might cause a problem if too many instances of the dll are loaded. I do not know if the problem exists when running a .TKN.
At some point a window with controls will probably be required that the tab control cannot fully accomodate. This can be allieviated by using the Windows system scroll bars. Since LB has no method to allow the programmer to monitor the system scroll bars I have included the "SCROLLWIDG" dll in the attached zip file. Methods for using are included in "TAB_CONTROL.txt."
TABCTL_DLL_UPDATE.ZIP (49.3 KB)
The following code illustrates the used of "SetWinStyle", how to create a composit window, and attach that window to a tab in the tab control.
'
NOMAINWIN
WS.OVERLAPPED = HEXDEC("&H00000000")
WS.POPUP = HEXDEC("&H80000000")
WS.CHILD = HEXDEC("&H40000000")
WS.MINIMIZE = HEXDEC("&H20000000")
WS.VISIBLE = HEXDEC("&H10000000")
WS.DISABLED = HEXDEC("&H08000000")
WS.CLIPSIBLINGS = HEXDEC("&H04000000")
WS.CLIPCHILDREN = HEXDEC("&H02000000")
WS.MAXIMIZE = HEXDEC("&H01000000")
WS.CAPTION = HEXDEC("&H00C00000") ' WS.BORDER OR WS.DLGFRAME
WS.BORDER = HEXDEC("&H00800000")
WS.DLGFRAME = HEXDEC("&H00400000")
WS.VSCROLL = HEXDEC("&H00200000")
WS.HSCROLL = HEXDEC("&H00100000")
WS.SYSMENU = HEXDEC("&H00080000")
WS.THICKFRAME = HEXDEC("&H00040000")
WS.GROUP = HEXDEC("&H00020000")
WS.TABSTOP = HEXDEC("&H00010000")
WS.MINIMIZEBOX = HEXDEC("&H00020000")
WS.MAXIMIZEBOX = HEXDEC("&H00010000")
WS.OVERLAPPEDWINDOW = (WS.OVERLAPPED _
OR WS.CAPTION _
OR WS.SYSMENU _
OR WS.THICKFRAME _
OR WS.MINIMIZEBOX _
OR WS.MAXIMIZEBOX)
STRUCT tRect, _
X AS LONG, _
Y AS LONG, _
X1 AS LONG, _
Y1 AS LONG
STRUCT tTab, _
TabStyle AS ULONG, _
X AS LONG, _
Y AS LONG, _
X1 AS LONG, _
Y1 AS LONG
OPEN "gdi32" FOR DLL AS #GDI
OPEN "User32" FOR DLL AS #USER
OPEN "E:\PBWIN10\DLLS\TABCTL" FOR DLL AS #TAB
GLOBAL TabHndl
Hndl = 0
WinColor = 0
RetVal = 0
Clx = 0
Cly = 0
Cszx = 0
Cszy = 0
Style = WS.CLIPCHILDREN OR WS.VISIBLE 'WS.POPUP OR
RemStyle = WS.OVERLAPPEDWINDOW
UpperLeftX = 1
UpperLeftY = 1
WindowWidth = 700
WindowHeight = 500
OPEN "TAB TEST" FOR WINDOW AS #WINMN
Hndl = HWND(#WINMN)
CALLDLL #USER, "GetClientRect", Hndl AS ULONG, tRect AS STRUCT, RetVal AS VOID
CALLDLL #USER, "MapWindowPoints", Hndl AS ULONG, 0 AS ULONG, tRect AS STRUCT, _
2 AS LONG, RetVal AS VOID
Clx = tRect.X.struct
Cly = tRect.Y.struct
Cszx = tRect.X1.struct - tRect.X.struct - 6
Cszy = tRect.Y1.struct - tRect.Y.struct - 10
BUTTON #TAB1.BFLS, "FILES", BUTTONCB, UL, 2, 2, 35, 15
BUTTON #TAB1.BED, "EDIT", BUTTONCB, UL, 40, 2, 35, 15
TEXTEDITOR #TAB1.ED, 2, 20, 650, 450
'STYLEBITS #TAB1, Style, RemStyle, 0, 0
UpperLeftX = Clx
UpperLeftY = Cly
WindowWidth = Cszx
WindowHeight = Cszy
OPEN "TAB1" FOR WINDOW AS #TAB1
BUTTON #TAB2.BFLS, "FILES", BUTTONCB, UL, 2, 2, 35, 15
GRAPHICBOX #TAB2.GFX, 2, 20, 650, 450
UpperLeftX = UpperLeftX + 10
UpperLeftY = UpperLeftY + 30
OPEN "TAB2" FOR WINDOW AS #TAB2
TEXTBOX #TAB3.TBX1, 2, 2, 70, 20
TEXTBOX #TAB3.TBX2, 2, 30, 70, 20
TEXTBOX #TAB3.TBX3, 2, 58, 70, 20
UpperLeftX = UpperLeftX + 10
UpperLeftY = UpperLeftY = 30
OPEN "TAB3" FOR WINDOW AS #TAB3
WinColor = HEXDEC("&HCBC0FF")
CALL Create.Main
Hndl = HWND(#WIN)
CALL ColorIt Hndl, WinColor
CALL Create.Left
CALL Create.Right
CALL FitEm
PRINT #WINMN, "TRAPCLOSE End.It"
PRINT #WINMN, "RESIZEHANDLER SIZEMAIN"
PRINT #TAB1, "TRAPCLOSE End.It"
PRINT #TAB2, "TRAPCLOSE End.It"
PRINT #TAB3, "TRAPCLOSE End.It"
Hndl = HWND(#WINMN)
CALLDLL #USER, "GetClientRect", Hndl AS ULONG, tRect AS STRUCT, RetVal AS VOID
tTab.TabStyle.struct = 0
tTab.X.struct = 5
tTab.Y.struct = 5
tTab.X1.struct = tRect.X1.struct - tRect.X.struct - 6
tTab.Y1.struct = tRect.Y1.struct - tRect.Y.struct - 30
Ttl.1$ = "Editor with Buttons"
Ttl.2$ = "Graphic Box With Button"
Ttl.3$ = "Edit Boxes"
Ttl.4$ = "Embedded Windows"
Tab.1Hndl = HWND(#TAB1)
Tab.2Hndl = HWND(#TAB2)
Tab.3Hndl = HWND(#TAB3)
Tab.4Hndl = HWND(#WIN)
CALLDLL #TAB, "FN_InitTab", Hndl AS ULONG, tTab AS STRUCT, TabHndl AS ULONG
CALLDLL #TAB, "FN_AddTab", TabHndl AS ULONG, Tab.1Hndl AS ULONG, _
0 AS ULONG, Ttl.1$ AS STRUCT, Idx AS LONG
CALLDLL #TAB, "FN_AddTab", TabHndl AS ULONG, Tab.2Hndl AS ULONG, _
0 AS ULONG, Ttl.2$ AS STRUCT, Idx AS LONG
CALLDLL #TAB, "FN_AddTab", TabHndl AS ULONG, Tab.3Hndl AS ULONG, _
0 AS ULONG, Ttl.3$ AS STRUCT, Idx AS LONG
CALLDLL #TAB, "FN_AddTab", TabHndl AS ULONG, Tab.4Hndl AS ULONG, _
0 AS ULONG, Ttl.4$ AS STRUCT, Idx AS LONG
Style = WS.CLIPCHILDREN OR WS.VISIBLE OR WS.DLGFRAME
CALLDLL #TAB, "SetWinStyle", TabHndl AS ULONG, 0 AS LONG, _
Style AS ULONG, 0 AS ULONG, Idx AS VOID
CALLDLL #TAB, "SetWinStyle", TabHndl AS ULONG, 3 AS LONG, _
Style AS ULONG, 0 AS ULONG, Idx AS VOID
CALLDLL #TAB, "SetWinStyle", TabHndl AS ULONG, 2 AS LONG, _
Style AS ULONG, 0 AS ULONG, Idx AS VOID
Style = Style OR WS.THICKFRAME
CALLDLL #TAB, "SetWinStyle", TabHndl AS ULONG, 1 AS LONG, _
Style AS ULONG, 0 AS ULONG, Idx AS VOID
WAIT
END
'-----------------------------------------------------------------------
'-----------------------------------------------------------------------
SUB SIZEMAIN Hndl$
RetVal = 0
CALLDLL #TAB, "UpdateTab", TabHndl AS ULONG, RetVal AS VOID
END SUB
'-----------------------------------------------------------------------
'-----------------------------------------------------------------------
SUB BUTTONCB Handl$
END SUB
'-----------------------------------------------------------------------
'-----------------------------------------------------------------------
SUB Create.Main
WinHndl = 0
BkColor = 0
UpperLeftX = 100
UpperLeftY = 100
WindowWidth = 300
WindowHeight = 300
OPEN "Win Test" FOR WINDOW AS #WIN
PRINT #WIN, "resizehandler ResizeIt"
PRINT #WIN, "trapclose End.It"
END SUB
'-------------------------------------------------------------------
'-------------------------------------------------------------------
SUB Create.Left
WS.OVERLAPPED = HEXDEC("&H00000000")
WS.VISIBLE = HEXDEC("&H10000000")
WS.CHILD = HEXDEC("&H40000000")
WS.VISIBLE = HEXDEC("&H10000000")
WS.CLIPSIBLINGS = HEXDEC("&H04000000")
WS.CLIPCHILDREN = HEXDEC("&H02000000")
WS.MAXIMIZE = HEXDEC("&H01000000")
WS.CAPTION = HEXDEC("&H00C00000") ' WS.BORDER OR WS.DLGFRAME
WS.BORDER = HEXDEC("&H00800000")
WS.SYSMENU = HEXDEC("&H00080000")
WS.THICKFRAME = HEXDEC("&H00040000")
WS.MINIMIZEBOX = HEXDEC("&H00020000")
WS.MAXIMIZEBOX = HEXDEC("&H00010000")
WS.OVERLAPPEDWINDOW = (WS.OVERLAPPED _
OR WS.CAPTION _
OR WS.SYSMENU _
OR WS.THICKFRAME _
OR WS.MINIMIZEBOX _
OR WS.MAXIMIZEBOX)
WS.EX.DLGMODALFRAME = HEXDEC("&H00000001")
WS.EX.WINDOWEDGE = HEXDEC("&H00000100")
WS.EX.STATICEDGE = HEXDEC("&H00020000")
WS.EX.CONTROLPARENT = HEXDEC("&H00010000")
UpperLeftX = 0
UpperLeftY = 0
WindowWidth = 150
WindowHeight = 300
Styl = WS.VISIBLE OR WS.CLIPCHILDREN OR WS.DLGFRAME OR WS.VISIBLE 'OR _
'WS.THICKFRAME
ExStyle = WS.EX.STATICEDGE OR WS.EX.DLGMODALFRAME OR WS.EX.CONTROLPARENT
RemStyle = WS.OVERLAPPEDWINDOW
RemExStyle = WS.EX.WINDOWEDGE
hMain = 0
hChild = 0
BkColor = 0
STYLEBITS #LFT, Styl, RemStyle, ExStyl, RemExStyle
TEXTEDITOR #LFT.ED, 0, 0, 100, 200
OPEN "LFT CHILD" FOR WINDOW AS #LFT
hMain = HWND(#WIN)
hChild = HWND(#LFT)
CallDLL #USER, "SetParent",_
hChild as ULONG,_
hMain as ULONG,_
ret as LONG
CALLDLL #USER, "GetWindowLongA",_
hChild as ULONG,_
_GWL_STYLE as LONG,_
Style as LONG
Style = Styl OR WS.CHILD
CALLDLL #USER, "SetWindowLongA",_
hChild as ULONG,_
_GWL_STYLE as LONG,_
Style as LONG,_
ret as LONG
CALLDLL #USER, "GetClientRect", hMain AS ULONG, tRect AS STRUCT, RetVal AS VOID
Wide = INT(tRect.X1.struct / 2)
High = tRect.Y1.struct
CALLDLL #USER, "MoveWindow", hChild AS ULONG, 0 AS LONG, 0 AS LONG, _
Wide AS LONG, High AS LONG, RetVal AS VOID
END SUB
'-------------------------------------------------------------------
'-------------------------------------------------------------------
SUB Create.Right
WS.OVERLAPPED = HEXDEC("&H00000000")
WS.VISIBLE = HEXDEC("&H10000000")
WS.CHILD = HEXDEC("&H40000000")
WS.VISIBLE = HEXDEC("&H10000000")
WS.CLIPSIBLINGS = HEXDEC("&H04000000")
WS.CLIPCHILDREN = HEXDEC("&H02000000")
WS.MAXIMIZE = HEXDEC("&H01000000")
WS.CAPTION = HEXDEC("&H00C00000") ' WS.BORDER OR WS.DLGFRAME
WS.BORDER = HEXDEC("&H00800000")
WS.SYSMENU = HEXDEC("&H00080000")
WS.THICKFRAME = HEXDEC("&H00040000")
WS.MINIMIZEBOX = HEXDEC("&H00020000")
WS.MAXIMIZEBOX = HEXDEC("&H00010000")
WS.OVERLAPPEDWINDOW = (WS.OVERLAPPED _
OR WS.CAPTION _
OR WS.SYSMENU _
OR WS.THICKFRAME _
OR WS.MINIMIZEBOX _
OR WS.MAXIMIZEBOX)
WS.EX.DLGMODALFRAME = HEXDEC("&H00000001")
WS.EX.WINDOWEDGE = HEXDEC("&H00000100")
WS.EX.STATICEDGE = HEXDEC("&H00020000")
WS.EX.CONTROLPARENT = HEXDEC("&H00010000")
hMain = 0
hChild = 0
UpperLeftX = 0
UpperLeftY = 0
WindowWidth = 150
WindowHeight = 300
Styl = WS.VISIBLE OR WS.CLIPCHILDREN OR WS.DLGFRAME OR WS.VISIBLE OR _
WS.THICKFRAME
ExStyle = WS.EX.STATICEDGE OR WS.EX.DLGMODALFRAME OR WS.EX.CONTROLPARENT
RemStyle = WS.OVERLAPPEDWINDOW
RemExStyle = WS.EX.WINDOWEDGE
STYLEBITS #RGT, Styl, RemStyle, ExStyl, RemExStyle
GRAPHICBOX #RGT.GFX, 0, 0, 100, 200
OPEN "CHILD" FOR WINDOW AS #RGT
PRINT #RGT, "resizehandler ResizeIt"
hMain = hwnd(#WIN)
hChild = hwnd(#RGT)
CallDLL #USER, "SetParent",_
hChild as ULONG,_
hMain as ULONG,_
ret as LONG
CALLDLL #USER, "GetWindowLongA",_
hChild as ULONG,_
_GWL_STYLE as LONG,_
Style as LONG
Style = Styl OR WS.CHILD
CALLDLL #USER, "SetWindowLongA",_
hChild as ULONG,_
_GWL_STYLE as LONG,_
Style as LONG,_
ret as LONG
END SUB
'--------------------------------------------------------------------------
'--------------------------------------------------------------------------
SUB End.It WinHndl$
CLOSE #WIN
CLOSE #RGT
CLOSE #LFT
CLOSE #USER
CLOSE #GDI
CLOSE #TAB1
CLOSE #TAB2
CLOSE #TAB3
CLOSE #WINMN
CLOSE #TAB
END SUB
'-------------------------------------------------------------------
'-------------------------------------------------------------------
SUB ResizeIt WinHndl$
CALL FitEm
END SUB
'-------------------------------------------------------------------
'-------------------------------------------------------------------
SUB SizeRight RgtHandle$
CALL FitEm
END SUB
'-------------------------------------------------------------------
'-------------------------------------------------------------------
SUB ColorIt Hndl, BkColor
WinHndl = 0
BackClr = 0
R = 0
WinHndl = Hndl
BackClr = BkColor
CALLDLL #GDI, "CreateSolidBrush", BackClr AS ULONG, BrushHndl AS ULONG
CALLDLL #USER, "GetClientRect", WinHndl AS ULONG, tRect AS STRUCT, R AS LONG
CALLDLL #USER, "GetDC", WinHndl AS ULONG, WinDC AS ULONG
CALLDLL #USER, "FillRect", WinDC AS ULONG, tRect AS STRUCT, BrushHndl AS ULONG, _
R AS LONG
CALLDLL #USER, "ReleaseDC", WinHndl AS ULONG, WinDC AS ULONG, R AS VOID
CALLDLL #GDI, "DeleteObject", BrushHndl AS ULONG, R AS VOID
END SUB
'-------------------------------------------------------------------
'-------------------------------------------------------------------
SUB FitEm
WM.SIZE = HEXDEC("&H0005")
SIZE.RESTORED = 0
SW.HIDE = 0
SW.SHOW = 5
Wx = 0
Wy = 0
Wx1 = 0
Wy1 = 0
Cx = 0
Cy = 0
Cx1 = 0
Cy1 = 0
WinHndl = 0
LftHndl = 0
RgtHndl = 0
RetVal = 0
WinColor = 0
LftColor = 0
RgtColor = 0
WinColor = HEXDEC("&HCBC0FF")
LftColor = HEXDEC("&HEE82EE")
RgtColor = HEXDEC("&HE6E0B0")
WinHndl = HWND(#WIN)
LftHndl = HWND(#LFT)
RgtHndl = HWND(#RGT)
CALLDLL #USER, "GetClientRect", WinHndl AS ULONG, tRect AS STRUCT, RetVal AS VOID
Wx = tRect.X.struct
Wy = tRect.Y.struct
Wx1 = tRect.X1.struct
Wy1 = tRect.Y1.struct
CALLDLL #USER, "GetWindowRect", RgtHndl AS ULONG, tRect AS STRUCT, RetVal AS VOID
CALLDLL #USER, "MapWindowPoints", 0 AS ULONG, WinHndl AS ULONG, tRect AS STRUCT, _
2 AS SHORT, RetVal AS VOID
Cx = tRect.X.struct
Cy = tRect.Y.struct
IF Cx < 25 THEN Cx = 25
IF Cx > Wx1 - 25 THEN Cx = Wx1 - 25
Cx1 = Cx
Wide = Wx1 - Cx
High = Wy1
CALLDLL #USER, "MoveWindow", RgtHndl AS ULONG, Cx AS LONG, 0 AS LONG, _
Wide AS LONG, High AS LONG, 1 AS BOOLEAN, RetVal AS LONG
Wide = Cx1 - 4
High = High - 4
CALLDLL #USER, "MoveWindow", LftHndl AS ULONG, 0 AS LONG, 0 AS LONG, _
Wide AS LONG, High AS LONG, 1 AS BOOLEAN, RetVal AS VOID
LftHndl = HWND(#LFT.ED)
WinHndl = HWND(#LFT)
CALLDLL #USER, "GetClientRect", WinHndl AS ULONG, tRect AS STRUCT, RetVal AS VOID
Cx = tRect.X1.struct - 2
Cy = tRect.Y1.struct - 4
CALLDLL #USER, "MoveWindow", LftHndl AS ULONG, 0 as LONG, 0 AS LONG, _
Cx AS LONG, Cy AS LONG, RetVal AS VOID
RgtHndl = HWND(#RGT.GFX)
WinHndl = HWND(#RGT)
CALLDLL #USER, "GetClientRect", WinHndl AS ULONG, tRect AS STRUCT, RetVal AS VOID
Cx = tRect.X1.struct - 2
Cy = tRect.Y1.struct - 2
CALLDLL #USER, "MoveWindow", RgtHndl AS ULONG, 0 as LONG, 0 AS LONG, _
Cx AS LONG, Cy AS LONG, RetVal AS VOID
CALL ColorIt, WinHndl, WinColor
END SUB
'