FbLayout

Started by James Fuller, June 02, 2016, 11:15:36 AM

Previous topic - Next topic

James Fuller

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   


José Roca

Thanks very much. As more options we have, the better.

James Fuller

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
'==============================================================================

James Fuller

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) _
    }