Well I finally got it.
As Jose mentioned the c code for the actual rendering was very "C" and would be
a large task to convert to FreeBasic. Instead I created a 64bit static library
using the same MinGW64 gcc that created Fb.
It is very flexible as can be attested by Dominic Mitchell's Layout32 Resize Library
for PowerBASIC which is based on the same code.
His demo at http://www.phnxthunder.com/files/layout32_demo.zip includes a very nice help file.
James
'==============================================================================
'Test FBLayout code
'==============================================================================
#define unicode
#inclib "fblayout"
#Include Once "windows.bi"
#Include Once "Afx/CWindow.inc"
#include Once "FbLayout.bi"
Using Afx.CWindowClass
'==============================================================================
#define IDD_LAYOUT 101
#define IDI_LAYOUT 102
#define IDC_B1 1001
#define IDC_B2 1002
#define IDC_B3 1003
#define IDC_E1 2001
#define IDC_E2 2002
#define IDC_G1 3001
#define IDC_STATIC -1
'------------------------------------------------------------------------------
DECLARE FUNCTION WinMain (BYVAL hInstance AS HINSTANCE, _
BYVAL hPrevInstance AS HINSTANCE, _
BYVAL szCmdLine AS ZSTRING PTR, _
BYVAL nCmdShow AS LONG) AS LONG
END WinMain(GetModuleHandleW(NULL), NULL, COMMAND(), SW_NORMAL)
'==============================================================================
Function WndProc (BYVAL hWnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT
Select Case uMsg
'Case WM_CREATE
Case WM_SIZE
Dim ruleptr As RULE Ptr = CAST(RULE Ptr,GetPropW(hWnd,"FBLAYOUT"))
If ruleptr Then
Layout_ComputeLayout(hWnd, ruleptr)
End If
Exit Function
Case WM_GETMINMAXINFO
' Set the pointer to the address of the MINMAXINFO structure
DIM ptmmi AS MINMAXINFO PTR = CAST(MINMAXINFO PTR, lParam)
' Set the minimum and maximum sizes that can be produced by dragging the borders of the window
DIM pWindow AS CWindow PTR = CAST(CWindow PTR, GetWindowLongPtr(hwnd, 0))
IF pWindow THEN
ptmmi->ptMinTrackSize.x = 389 * pWindow->rxRatio
ptmmi->ptMinTrackSize.y = 363 * pWindow->ryRatio
END IF
EXIT FUNCTION
Case WM_DESTROY
RemovePropW hWnd,"FBLAYOUT"
PostQuitMessage(0)
Exit Function
End Select
Function = DefWindowProc(hWnd, uMsg, wParam, lParam)
End Function
'==============================================================================
Function WinMain (BYVAL hInstance AS HINSTANCE, _
BYVAL hPrevInstance AS HINSTANCE, _
BYVAL szCmdLine AS ZSTRING PTR, _
BYVAL nCmdShow AS LONG) AS LONG
'------------------------------------------------------------------------------
' Action Act-On Relative-To Offset
'------------------------------------------------------------------------------
Dim rules(0 To 13) As RULE => _
{ _
(lMOVE, lRIGHT(IDC_B1), lRIGHT(lPARENT), -8), _
(lSTRETCH, lWIDTH(IDC_B1), lWIDTHOF(lPARENT, 15), +0), _
(lMOVE, lTOP(IDC_B2), lBOTTOM(IDC_B1), +8), _
(lMOVE, lLEFT(IDC_B2), lLEFT(IDC_B1), +0), _
(lSTRETCH, lWIDTH(IDC_B2), lWIDTH(IDC_B1), +0), _
(lVCENTER, lCHILD(IDC_B3), lCHILD(IDC_G1), +2), _
(lHCENTER, lCHILD(IDC_B3), lCHILD(IDC_G1), +0), _
(lVCENTER, lGROUP(IDC_B1,IDC_B2), lCHILD(IDC_E2), +0), _
(lSTRETCH, lWIDTH(IDC_E1), lWIDTHOF(IDC_E2, 50), +0), _
(lSTRETCH, lBOTTOM(IDC_E2), lBOTTOM(lPARENT), -8), _
(lSTRETCH, lRIGHT(IDC_E2), lLEFT(IDC_B1), -8), _
(lMOVE, lLEFT(IDC_G1), lRIGHT(IDC_E1), +8), _
(lSTRETCH, lRIGHT(IDC_G1), lRIGHT(lPARENT), -8), _
(lEND) _
}
' // Set process DPI aware
AfxSetProcessDPIAware
Dim As CWindow pWindow
pWindow.Create(NULL, "FbLayOut Test", @WndProc,0,0,389,363)
pWindow.AddControl("Label",pWindow.hWindow,IDC_STATIC,"E1:",12,20,51,16)
pWindow.AddControl("Edit",pWindow.hWindow,IDC_E1,"",12,42,140,24)
pWindow.AddControl("GroupBox",pWindow.hWindow,IDC_G1,"G1:",166,16,194,64)
pWindow.AddControl("Button",pWindow.hWindow,IDC_B3,"B3:",220,38,86,28)
pWindow.AddControl("Label",pWindow.hWindow,IDC_STATIC,"E2:",12,84,79,16)
pWindow.AddControl("EditMultiline",pWindow.hWindow,IDC_E2,"",12,106,280,203)
pWindow.AddControl("Button",pWindow.hWindow,IDC_B1,"B1",305,171,55,28)
pWindow.AddControl("Button",pWindow.hWindow,IDC_B2,"B2",305,215,55,28)
SetPropW pWindow.hWindow,"FBLAYOUT",@rules(0)
pWindow.Center
Function = pWindow.DoEvents(nCmdShow)
End Function
Thanks very much. As more options we have, the better.
Here is an updated FbLayout.bi with documentation
James
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
'FbLayout.bi
'Portions Copyright (c) 1995 Jeffrey Richter
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
'------------------------------------------------------------------------------
#define lPARENT 65536 'Special CHILD id for parent
'------------------------------------------------------------------------------
'////////////////////////////// Layout Part Types //////////////////////////////
'------------------------------------------------------------------------------
type lPART As long
enum
lpLEFT = 0 'Left side of control
lpTOP 'Top side of control
lpRIGHT 'Right side of control
lpBOTTOM 'Bottom side of control
lpWIDTH 'Width of control
lpHEIGHT 'Height of control
lpGROUP 'Group of one or more controls
End Enum
'------------------------------------------------------------------------------
'/////////////////////////////// Layout Actions ////////////////////////////////
'------------------------------------------------------------------------------
type lAction As long
enum
lSTRETCH = 0 'Metric should be stretched
lMOVE 'Control should be moved
lVCENTER 'Vertically center control/group
lHCENTER 'Horizontally center control/group
lEND 'Special flag for end of list
End Enum
'------------------------------------------------------------------------------
'/////////////////////////// Definition of an Action ///////////////////////////
'------------------------------------------------------------------------------
Type lActionInfo
union
nPart As long 'Name used only for group oriented actions
nMetric As long 'Name used only for metric oriented actions
nSide As long 'Name used only for side oriented actions
end union
union
idc As long 'Used for all actions except group actions
idcfirst As long 'Used for group actions
end union
union
nPercent As long 'Used only for width/height actions
idcLast As long 'Used for group actions
end union
End Type
'------------------------------------------------------------------------------
'//////////////////////////// Definition of a Rule /////////////////////////////
'------------------------------------------------------------------------------
Type RULE
Action As lACTION 'Layout action to take
ActOn As lACTIONINFO 'Data describing the part to act on
RelTo As lACTIONINFO 'Data for the part to position relative to
nOffset As long 'Additional offset (in dialog units)
fState As UINT 'INTERNAL USE: Rule application state flag
nPixelOffset As long 'INTERNAL USE: nOffset converted to pixels
End Type
'------------------------------------------------------------------------------
'////////////////////////// Macros for Defining Rules //////////////////////////
'// Part, Control id Percentage
'// metric or first id of control or
'// Macro or side in group last id in group
'// ----- ---- ------- ---------
'------------------------------------------------------------------------------
#define lLEFT(idc) lpLEFT, idc, 0
#define lTOP(idc) lpTOP, idc, 0
#define lRIGHT(idc) lpRIGHT, idc, 0
#define lBOTTOM(idc) lpBOTTOM, idc, 0
#define lWIDTH(idc) lpWIDTH, idc, 100
#define lHEIGHT(idc) lpHEIGHT, idc, 100
#define lWIDTHOF(idc, percent) lpWIDTH, idc, percent
#define lHEIGHTOF(idc, percent) lpHEIGHT, idc, percent
#define lCHILD(idc) lpGROUP, idc, idc
#define lGROUP(idcFirst, idcLast) lpGROUP, idcFirst, idcLast
'------------------------------------------------------------------------------
'//////////////////////////// Prototype for Layout ////////////////////////////
'------------------------------------------------------------------------------
Declare Function Layout_ComputeLayout Alias "Layout_ComputeLayout"(Byval hwndDlg As HWND, pRules As RULE Ptr ) As BOOL
'==============================================================================
Is there a way to use dynamic (NEW) allocation and assignment with this?
James
Dim rules(0 To 13) As RULE => _
{ _
(lMOVE, lRIGHT(IDC_B1), lRIGHT(lPARENT), -8), _
(lSTRETCH, lWIDTH(IDC_B1), lWIDTHOF(lPARENT, 15), +0), _
(lMOVE, lTOP(IDC_B2), lBOTTOM(IDC_B1), +8), _
(lMOVE, lLEFT(IDC_B2), lLEFT(IDC_B1), +0), _
(lSTRETCH, lWIDTH(IDC_B2), lWIDTH(IDC_B1), +0), _
(lVCENTER, lCHILD(IDC_B3), lCHILD(IDC_G1), +2), _
(lHCENTER, lCHILD(IDC_B3), lCHILD(IDC_G1), +0), _
(lVCENTER, lGROUP(IDC_B1,IDC_B2), lCHILD(IDC_E2), +0), _
(lSTRETCH, lWIDTH(IDC_E1), lWIDTHOF(IDC_E2, 50), +0), _
(lSTRETCH, lBOTTOM(IDC_E2), lBOTTOM(lPARENT), -8), _
(lSTRETCH, lRIGHT(IDC_E2), lLEFT(IDC_B1), -8), _
(lMOVE, lLEFT(IDC_G1), lRIGHT(IDC_E1), +8), _
(lSTRETCH, lRIGHT(IDC_G1), lRIGHT(lPARENT), -8), _
(lEND) _
}