Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Visual Forms Designer - progress

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Visual Forms Designer - progress

    This is incomplete but there has been some interest in progress so I'm posting it warts and all.

    In particular, the snap to grid processing has been revised, and the control right-click menu includes a Properties option, which enables font selection and styles selection to be done. Comments in the Windows forum, please.

    ** update 23-Dec-2007 **
    Now generates PB DDT code. You will need both the compiled program and the STYLES.TXT file (below)

    ** update 27-Dec-2007
    bug fixes in snap/size to grid and loading from .ftf file
    Code:
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Visual designer originally based upon Borje Hagsten's DrawRect sample
    ' of March 2003.
    ' Provides a floating menu and moveable "controls", being dialogs
    ' each with a single control to represent the eventual type style
    ' and placement of the control in the generated program.
    ' Generates ONE dialog with < 1000 controls.
    ' Control types are restricted to LABEL, TEXTBOX, CHECKBOX, LISTBOX, LISTVIEW, BUTTON.
    '
    ' CJH 6-DEC-2007
    '--------------------------------------------------------------------
    ' Change History
    '  6-Dec-2007 GUI design PoC accepted
    ' 17-Dec-2007 added properties, snap to grid revised
    ' 22-Dec-2007 save to file, export PB DDT source
    '--------------------------------------------------------------------
    ' Issues
    ' 1. No grab handles on controls. Not sure if this matters.
    ' 2. Help on styles is supposed to be by using a multiline tooltip - not done yet
    ' 3. Size to grid not working when a control is resized
    ' 4. No control group formatting functions eg L/R align block of controls, etc
    ' 5. Selected styles still not applied to controls in the designer
    '
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "commctrl.inc"
    #INCLUDE "WIN32API.INC"
    #INCLUDE "comdlg32.inc"
    
    '--------------------------------------------------------------------
    ' debug macro for use with dbgview.exe
    %enable_debug = %TRUE
    MACRO DP(st)
      #IF %ENABLE_DEBUG
          CALL OutputDebugString(st)
      #ENDIF
    END MACRO
    '--------------------------------------------------------------------
    ' timer related
    %TIMER_SNAP           = 99 ' timer for snapping CCs to grid
    %TIMER_REDRAW_GRID    = 98 ' timer for redrawing grid
    %TIMEOUT_SNAP         = 200 ' timer delay for snap to grid
    %TIMEOUT_REDRAW_GRID  = 500 ' timer delay for redrawing grid
    '--------------------------------------------------------------------
    %IDC_CHK1 = 121
    %IDC_CHK2 = 122
    %IDC_CHK3 = 128
    %IDC_CHK4 = 129
    %IDC_LAB1 = 123
    
    %IDC_LAB2 = 124
    %IDC_GRIDX_TB = 125
    %IDC_GRIDY_TB = 126
    %IDC_SHOWCONTROLS_LV = 127
    '--------------------------------------------------------------------
    ' popup CC menu ids
    %IDM_POPUP1 = 150
    %IDM_POPUP2 = 151
    %IDM_POPUP3 = 152
    '--------------------------------------------------------------------
    %our_typecontrol_base = 500
    %our_dialog_type      = 0
    %our_label_type       = 1
    %our_textbox_type     = 2
    %our_checkbox_type    = 3
    %our_listbox_type     = 4
    %our_listview_type    = 5
    %our_button_type      = 6
    '
    %IDC_GRIP = 700
    
    ' keep type identifier control declarations in a contiguous block
    %IDC_CTL1 = %our_typecontrol_base + %our_label_type
    %IDC_CTL2 = %our_typecontrol_base + %our_textbox_type
    %IDC_CTL3 = %our_typecontrol_base + %our_checkbox_type
    %IDC_CTL4 = %our_typecontrol_base + %our_listbox_type
    %IDC_CTL5 = %our_typecontrol_base + %our_listview_type
    %IDC_CTL6 = %our_typecontrol_base + %our_button_type
    
    ' -------------------------------------------------------------------
    ' PROPERTIES EQUATES
    %IDD_CP               =  101
    %IDC_TEXTBOX1         = 1001
    %IDC_LABEL1           = 1064
    %IDC_LABEL4           = 1067
    %IDC_CTRL_TYPE_LAB    = 1066
    %IDC_CTRL_NO_LAB      = 1065
    %IDC_TEXT_TB          = 1034
    %IDC_LABEL2           = 1084
    %IDC_STYLES_TB        = 1035
    %IDC_AV_STYLES_LV     = 1036
    %IDC_LABEL3           = 1085
    %IDC_LABEL21          = 1086
    %IDC_LABEL22          = 1087
    %IDC_FONT_BN          = 1037
    %IDC_FONTSIZE_LAB      = 1088
    %IDC_FONTATTS_LAB      = 1089
    %IDC_LINE1            = 1092
    %IDC_LINE2            = 1093
    %IDC_W_LAB            = 1097
    %IDC_H_LAB            = 1098
    %IDC_Y_LAB            = 1095
    %IDC_X_LAB            = 1094
    %IDC_SAVE_BN          = 1095
    %IDC_DEF_STYLES_BN    = 1101
    %IDC_BGCOLOR_BN       = 1102
    %IDC_ORG_STYLES_BN    = 1103
    '--------------------------------------------------
    ' Styles listview stuff
    %IDC_LV             = 1500
    %IDC_TB             = 1501
    %IDC_LV2TB          = 1502
    %IDC_TB2LV          = 1503
    
    
    %idc_CCID = 550
    %GRIDSIZEX = 10
    %GRIDSIZEY = 10
    ' project control stuff
    $STYLESDBPATH = "STYLES.TXT"
    $PBWINCMD = "C:\PBWIN80\bin\PBWIN"
    $PBWININCLUDES = " /IC:\PBWIN80\WINAPI"
    $ROOTDIR = "C:\chris\mcodegen"
    '------------------------------------------
    ' styles stuff for generated controls
    $DEFAULT_LAB_STYLES   = "WS_CHILD,WS_VISIBLE,SS_LEFT,WS_EX_LEFT,WS_EX_LTRREADING"
    $DEFAULT_TB_STYLES    = "WS_CHILD,WS_VISIBLE,WS_TABSTOP,ES_LEFT,ES_AUTOHSCROLL," _
                            + "WS_EX_CLIENTEDGE,WS_EX_LEFT,WS_EX_LTRREADING,WS_EX_RIGHTSCROLLBAR"
    $DEFAULT_CB_STYLES    = "WS_CHILD,WS_VISIBLE,BS_AUTO_CHECKBOX,BS_LEFT,BS_VCENTER,WS_EX_LEFT,WS_EX_LTRREADING"
    $DEFAULT_LB_STYLES    = "WS_CHILD,WS_TABSTOP,WS_VISIBLE,WS_VSCROLL,LBS_NOTIFY,WS_EX_CLIENTEDGE,WS_EX_LEFT,WS_EX_LTRREADING,WS_EX_RIGHTSCROLLBAR"
    $DEFAULT_BN_STYLES    = "WS_CHILD,WS_TABSTOP,WS_VISIBLE,BS_TEXT,BS_PUSHBUTTON,BS_CENTER,BS_VCENTER,WS_EX_LEFT,WS_EX_LTRREADING"
    $DEFAULT_LV_STYLES    = "WS_CHILD,WS_TABSTOP,WS_VISIBLE,LVS_SHOWSELALWAYS,LVS_REPORT," _
                       + "WS_EX_CLIENTEDGE,LVS_EX_LABELTIP,LVS_EX_INFOTIP,WS_EX_LEFT,WS_EX_RIGHTSCROLLBAR"
    $DEFAULT_DLG_STYLES   = "WS_SYSMENU,WS_VISIBLE,WS_CLIPCHILDREN,DS_NOFAILCREATE,DS_3DLOOK,DS_SETFONT,WS_EX_RIGHTSCROLLBAR"
    '-----------------------------------------
    ' styles stuff for this program's controls
    %DEFAULT_LV_STYLES = %ws_child OR %WS_TABSTOP OR %WS_VISIBLE OR %LVS_SHOWSELALWAYS OR %LVS_REPORT
    %DEFAULT_LV_EX_STYLES = %WS_EX_CLIENTEDGE OR %LVS_EX_LABELTIP OR %LVS_EX_INFOTIP OR %WS_EX_LEFT OR %WS_EX_RIGHTSCROLLBAR
    '--------------------------------------------------------------------
    ' numeric decode of control types
    '--------------------------------------------------------------------
    DECLARE CALLBACK FUNCTION DlgProc() AS LONG
    DECLARE FUNCTION MakeGridBrush (BYVAL hDlg AS DWORD) AS DWORD
    
    DECLARE SUB selRectBegin (BYVAL hWnd AS DWORD)
    DECLARE SUB selRectDraw  (BYVAL hWnd AS DWORD, BYVAL x AS LONG, BYVAL y AS LONG, RC AS RECT)
    DECLARE FUNCTION selRectEnd (BYVAL hWnd AS DWORD, RCT AS RECT) AS LONG
    DECLARE FUNCTION FloatMenu_dialog(BYVAL hParent AS DWORD) AS LONG
    DECLARE FUNCTION ShowCControls ( BYVAL hParent AS DWORD) AS LONG
    DECLARE FUNCTION ShowPROP(BYVAL hParent AS DWORD) AS LONG
    DECLARE SUB ExportPBSource(hD AS DWORD)
    DECLARE SUB LoadCCS(hD AS DWORD)
    DECLARE SUB SaveCCS(hD AS DWORD, sfile AS STRING)
    DECLARE SUB Snap2Grid ( hW AS DWORD )
    
    '--------------------------------------------------------------------
    TYPE  CPH ' control place holder
        hD          AS DWORD        ' dialog handle
        cid         AS LONG         ' control identifier used in generated code
        lCtrlType   AS LONG         ' numeric index to type being control id of type - %IDC_CTL1, q.v.
        sText       AS STRING * 256 ' text for this control
        sStyles     AS STRING * 400 ' list of styles for this control
        lFontSize   AS LONG
        sFont       AS STRING * 40  '
        sFontAtts   AS STRING * 80  ' combination of Bold, Italic, Underline, Strikethrough etc
        lFGColour   AS LONG         ' raw FG colour value
        lBGColour   AS LONG         ' raw BG Color value
        X           AS LONG
        Y           AS LONG
        W           AS LONG
        H           AS LONG
        sImgPath    AS STRING * 256       ' path to image, static controls only
        hFont       AS LONG
        lGridX      AS LONG          ' grid settings for reload - valid in row 0 only
        lGridY      AS LONG          ' grid settings for reload - valid in row 0 only
        ncontrols   AS LONG          ' highest index in use     - valid in row 0 only
        hcurs       AS LONG          ' cursor for ccontrol not for gen'd app
    END TYPE
    '--------------------------------------------------------------------
    GLOBAL gGridSizeX           AS LONG
    GLOBAL gGridSizeY           AS LONG
    GLOBAL gShowGrid            AS LONG
    GLOBAL gSnapToGrid          AS LONG
    GLOBAL gSize2Grid           AS LONG
    GLOBAL ghBit                AS DWORD
    GLOBAL ghBrush              AS DWORD
    GLOBAL gMemDC               AS DWORD
    GLOBAL gPt                  AS POINTAPI
    GLOBAL gRc                  AS RECT
    GLOBAL gCCX                 AS LONG  ' highest index to gCcontrol in use
    GLOBAL gCcontrols()         AS CPH
    GLOBAL ghMenuDialog         AS DWORD ' handle for floating menu dialog
    GLOBAL ghCCDialog           AS DWORD ' handle for current CCdialog
    GLOBAL ghSCDialog           AS DWORD ' handle for CControls table dialog
    GLOBAL ghMAINDD             AS DWORD   ' handle for main dialog on which CCs are drawn
    GLOBAL ghPROPDD             AS DWORD   ' handle for Properties dialog
    GLOBAL gSControlTypes       AS STRING
    GLOBAL gsDialogStyles       AS STRING ' global default styles for main dialog
    GLOBAL glDIALOGPROPERTIES   AS LONG ' %TRUE if editing DIALOG properties, else editing CONTROL properties
    GLOBAL G_APP_NAME           AS STRING' generated application filename
    '-------------------------------------------------------------------
    ' common functions
    '--------------------------------------------------------------------
    FUNCTION ChooseFontDlgHookProc(BYVAL hWnd AS LONG, BYVAL wMsg AS LONG, _
                                   BYVAL wParam AS LONG, BYVAL lParam AS LONG ) AS LONG
      LOCAL X AS LONG, Y AS LONG, R AS RECT
    
      SELECT CASE wMsg
         CASE %WM_INITDIALOG
                  'CENTER DIALOG IN PARENT
                  GetWindowRect GetParent(hWnd), R    'get parent's data
                  X = R.nLeft + ((R.nRight   - R.nLeft) \ 2)      'calculate parent's width
                  Y = R.nTop  + ((R.nBottom  - R.nTop)  \ 2)      'calculate parent's height
    
                  GetWindowRect hWnd, R               'get dialog's width and height
                  R.nLeft = X - (( R.nRight   - R.nLeft ) \ 2)
                  R.nTop = Y - (( R.nBottom  - R.nTop  ) \ 2)
    
                  SetWindowPos hWnd, %NULL, R.nLeft, R.nTop, 0, 0, %SWP_NOSIZE OR %SWP_NOZORDER 'set centered pos
       END SELECT
    END FUNCTION
    
    '------------------------------------------------------------------------------
    ' Choose Font for a control...
    '------------------------------------------------------------------------------
    FUNCTION ChooseQTPFont(BYVAL hDlg AS LONG) AS DWORD
        STATIC cf AS CHOOSEFONTAPI
        STATIC lf AS LOGFONT
    
        cf.lStructSize    = SIZEOF(cf)
        cf.lpLogFont      = VARPTR(lf)
        cf.hWndOwner      = hDlg
        cf.Flags          = %CF_SCREENFONTS OR  _
                            %CF_EFFECTS OR _
                            %CF_ENABLEHOOK  OR _
                            %CF_INITTOLOGFONTSTRUCT
        cf.rgbColors      = getsyscolor (%COLOR_WINDOWTEXT)
        cf.lpfnHook       = CODEPTR(ChooseFontDlgHookProc)
    
        IF ChooseFont(cf) THEN
            FUNCTION = VARPTR(cf)
        END IF
    END FUNCTION
    '--------------------------------------------------------------------
    SUB DummyListBox( hD AS DWORD, hC AS LONG, n AS LONG)
        LOCAL i AS LONG
    
        FOR i = 1 TO n
            LISTBOX ADD hD, hC, USING$("Example Item #", i)
        NEXT
    END SUB
    '---------------------------------------------------------------------
    SUB SampleListView(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lColCnt AS LONG, BYVAL lRowCnt AS LONG)
        LOCAL lCol   AS LONG
        LOCAL lRow   AS LONG
        LOCAL hCtl   AS DWORD
        LOCAL tLVC   AS LV_COLUMN
        LOCAL tLVI   AS LV_ITEM
        LOCAL szBuf  AS ASCIIZ * 32
        LOCAL lStyle AS LONG
    
        CONTROL HANDLE hDlg, lID TO hCtl
    
        lStyle = ListView_GetExtendedListViewStyle(hCtl)
        ListView_SetExtendedListViewStyle hCtl, lStyle OR %LVS_EX_FULLROWSELECT OR %LVS_EX_GRIDLINES
    
        ' Load column headers.
        tLVC.mask    = %LVCF_FMT OR %LVCF_TEXT OR %LVCF_SUBITEM
        tLVC.fmt     = %LVCFMT_LEFT
        tLVC.pszText = VARPTR(szBuf)
        FOR lCol = 0 TO lColCnt - 1
            szBuf       = USING$("Column #", lCol)
            tLVC.iOrder = lCol
            ListView_InsertColumn hCtl, lCol, tLVC
        NEXT lCol
    
        ' Load sample data.
        FOR lRow = 0 TO lRowCnt - 1
            tLVI.stateMask = %LVIS_FOCUSED
            tLVI.pszText   = VARPTR(szBuf)
            tLVI.iItem     = lRow
            FOR lCol = 0 TO lColCnt - 1
                szBuf         = USING$("Column # Row #", lCol, lRow)
                tLVI.iSubItem = lCol
                tLVI.lParam   = lRow
                IF lCol = 0 THEN
                    tLVI.mask = %LVIF_TEXT OR %LVIF_PARAM OR %LVIF_STATE
                    ListView_InsertItem hCtl, tLVI
                ELSE
                    tLVI.mask = %LVIF_TEXT
                    ListView_SetItem hCtl, tLVI
                END IF
            NEXT lCol
        NEXT lRow
    
        ' Auto size columns.
        FOR lCol = 0 TO lColCnt - 2
            ListView_SetColumnWidth hCtl, lCol, %LVSCW_AUTOSIZE
        NEXT lCol
        ListView_SetColumnWidth hCtl, lColCnt - 1, %LVSCW_AUTOSIZE_USEHEADER
    END SUB
    '----------------------------------------------------------------------
    ' return the index to the gCcontrols table which has .hD = window handle supplied
    FUNCTION CCIndexFromhW ( hW AS DWORD ) AS LONG
        LOCAL l AS LONG
    
        FOR l = 1 TO gCCX
            IF gCcontrols(l).hD = hW THEN
                FUNCTION = l
                EXIT FUNCTION
            END IF
        NEXT
    END FUNCTION
    '----------------------------------------------------------------------
    SUB RemoveCCFRomTable ( hW AS DWORD )
        LOCAL l AS LONG
    
        l = CCIndexFromhW(hW)
        gCcontrols(l).hD = 0
    END SUB
    '----------------------------------------------------------------------
    '
    SUB DrawRectAroundControl(BYVAL hDlg AS DWORD, BYVAL hWnd AS DWORD, BYVAL PenColor AS DWORD)
        LOCAL hDC    AS DWORD
        LOCAL hBrush AS DWORD
        LOCAL hPen   AS DWORD
        LOCAL rc     AS RECT
    
    
        GetWindowRect hWnd, rc              'Get control's pos and size on screen
        MapWindowPoints 0, hDlg, rc, 2      'Map rect to dialog
        InflateRect rc, -1, -1                'Increase slightly to draw around control
    
        hDC = GetDc(hDlg)                   'Use dialog's DC since we want to paint on dialog
        hPen = CreatePen(%PS_SOLID OR %PS_INSIDEFRAME, 1, PenColor) 'Create a pen for given color
        hPen = SelectObject(hDC, hPen)      'Select the new pen into the DC
        hBrush = SelectObject(hDC, GetStockObject(%NULL_BRUSH)) 'Use stock null brush for hollow rect
    
        Rectangle hDC, rc.nLeft, rc.nTop, rc.nRight, rc.nBottom 'Draw the rectangle
    
        SelectObject hDC, hBrush 'Return original pen and brush, then release DC
        DeleteObject SelectObject(hDC, hPen)
        ReleaseDc hDlg, hDC
    
    END SUB
    '----------------------------------------------------------------------
    ' add a new child dialog with a control of the specififed type & coords to ghMainDialog
    SUB AddCcontrol ( ControlType AS LONG, x AS LONG, y AS LONG, w AS LONG, h AS LONG )
    
        LOCAL s AS STRING
        LOCAL lcx AS LONG
        LOCAL sTXT AS STRING
        LOCAL hD AS DWORD
        GLOBAL gCcontrols() AS CPH
    
        DIALOG NEW ghMainDD, "", X, Y, W, H, _
            %WS_POPUP OR %WS_THICKFRAME OR %WS_CHILD OR _
            %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
            %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_TOOLWINDOW OR _
            %WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING TO hD
    
        '
        INCR gCCX
    '    on error resume next
    '    REDIM PRESERVE gCcontrols(gCCX) AS GLOBAL CPH
    '    IF ERR <> 0 THEN ? "REDIM FAILED: " + ERROR$
    
    
        SELECT CASE ControlType
            CASE %our_button_type
                  sTxt = "BN:" & FORMAT$(gCCX)
                  gCcontrols(gCCX).sStyles = $DEFAULT_BN_STYLES
                  CONTROL ADD BUTTON, hD, %IDC_CCID, "", 0,0,0,0,%BS_FLAT
    
            CASE %our_checkbox_type
                  sTxt = "CB:" & FORMAT$(gCCX)
                  gCcontrols(gCCX).sStyles = $DEFAULT_CB_STYLES
                  CONTROL ADD CHECKBOX, hD, %IDC_CCID, "", 0,0,0,0
    
            CASE %our_label_type
                  sTxt = "Ll:" & FORMAT$(gCCX)
                  gCcontrols(gCCX).sStyles = $DEFAULT_LAB_STYLES
                  CONTROL ADD LABEL, hD, %IDC_CCID, "", 0,0,0,0
    
            CASE %our_textbox_type
                  sTxt = "TB:" & FORMAT$(gCCX)
                  gCcontrols(gCCX).sStyles = $DEFAULT_TB_STYLES
                  CONTROL ADD TEXTBOX, hD, %IDC_CCID, "", 0,0,0,0
    
            CASE %our_listbox_type
                  sTxt = "LB:" & FORMAT$(gCCX)
                  gCcontrols(gCCX).sStyles = $DEFAULT_LB_STYLES
                  CONTROL ADD LISTBOX, hD, %IDC_CCID, , 0,0,0,0
                  DummyListBox ( hD, %IDC_CCID, 10)
    
            CASE %our_listview_type
                  'sTxt = "LV:" & FORMAT$(gCCX)
                  gCcontrols(gCCX).sStyles = $DEFAULT_LV_STYLES
                  CONTROL ADD "SysListView32", hD, %IDC_CCID, "", 0,0,0,0, %DEFAULT_LV_STYLES, %DEFAULT_LV_EX_STYLES
    
                  SampleListView ( hD, %IDC_CCID, 10, 10)
    
    
        END SELECT
        gCcontrols(gCCX).hD        = hD
        gCcontrols(gCCX).lCtrlType = ControlType 'lCtrlType - %our_typecontrol_base
        gCcontrols(gCCX).cid       = gCCX
        gCcontrols(gCCX).lFGColour = getsyscolor(%COLOR_WINDOWTEXT)
        gCcontrols(gCCX).lBGColour = getsyscolor(%COLOR_3DFACE)
        gCcontrols(gCCX).sText     = TRIM$(sTxt)
        gCcontrols(gCCX).sFont     = ""
        gCcontrols(gCCX).hFont     = 0
        gCcontrols(gCCX).sFontAtts = ""
        gCcontrols(gCCX).X         = X
        gCcontrols(gCCX).Y         = Y
        gCcontrols(gCCX).W         = W
        gCcontrols(gCCX).H         = H
    
        CONTROL SET TEXT hD, %IDC_CCID, TRIM$(sTxt)
        CONTROL SET LOC hD, %IDC_CCID, 0, 0
        DIALOG SHOW MODELESS hD, CALL CC_dialogProc 'TO lRslt
    
    END SUB
    '------------------------------------------------------------------------------
    ' returns %TRUE if control exists else %FALSE
    FUNCTION ControlExistsAt ( x AS LONG, y AS LONG ) AS LONG
        LOCAL i AS LONG
    
        FUNCTION = %FALSE
        FOR i = 1 TO UBOUND(gCcontrols)
            IF (gCControls(i).X = X) AND (gCcontrols(i).Y = Y) THEN
                FUNCTION = %true
                EXIT FUNCTION
            END IF
        NEXT
    END FUNCTION
    '------------------------------------------------------------------------------
    ' Copy a control and show it.
    ' %1 = handle for underlying dialog, %2 = handle for CControl dialog to copy
    FUNCTION CopyControl ( hD AS WORD,  hCC AS DWORD ) AS LONG
        LOCAL l, lrslt, n, x, y AS LONG
    '    LOCAL CC AS CPH ' to hold a copy of the copied ccontrol's properties
    
        l = CCIndexFromhW ( hCC )
        IF l = 0 THEN EXIT FUNCTION
    
        ' each copy is offset by gridsize from the last, so keep bumping loc by gridsize
        ' until no existing control is thus located, then add to gCcontrols table
        X = gCControls(l).X + gGridSizeX
        Y = gCControls(l).Y + gGridSizeY
        WHILE ControlExistsAt(x, y)
            X = X + gGridSizeX
            Y = Y + gGridSizeY
        WEND
        ' add a new control of the same type
        n = gCControls(l).lCtrlType
        AddCcontrol (gCControls(l).lCtrlType, X, Y, gCControls(l).W, gCControls(l).H )
        FUNCTION = lrslt
    END FUNCTION
    '--------------------------------------------------------------------
    ' snap upper left corner to grid. Leave height & width unchanged
    ' parameter is dialog handle of Ccontrol
    SUB Snap2Grid ( hW AS DWORD )
    
        LOCAL l, X, Y, H, W AS LONG
        l = CCIndexFromhW(hW)
        IF l = 0 THEN  EXIT SUB ' goodness knows how we got here!
        DIALOG GET LOC hW TO X, Y
        DIALOG GET SIZE hW TO W, H
        IF gSnaptoGrid THEN
            X = (X \ gGridSizeX) * gGridSizeX  ' if snap to grid, calculate "grid'd pos"
            Y = (Y \ gGridSizeY) * gGridSizeY  ' via multiply of integer divide result
            ' update controls table
            gCcontrols(l).X = X
            gCcontrols(l).Y = Y
        END IF
        IF gSize2Grid THEN
            W = ( W \ gGridSizeX) * gGridSizeX  ' if snap to grid, calculate "grid'd pos"
            H = ( H \ gGridSizeY) * gGridSizeY  ' via multiply of integer divide result
            IF W = 0 THEN W = gGridSizeX
            IF H = 0 THEN H = gGridSizeY    
            gCcontrols(l).W = W
            gCcontrols(l).H = H
        END IF
        DIALOG SET SIZE hW, W, H
        DIALOG SET LOC hw, X, Y
        DIALOG REDRAW hW
    END SUB
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Main entrance
    '--------------------------------------------------------------------
    FUNCTION PBMAIN () AS LONG
      LOCAL hDlg AS DWORD, lRes AS LONG
      DIM gCcontrols(200) AS GLOBAL CPH
    
        REDIM gSControlTypes(6) AS GLOBAL STRING
    
        gCcontrols(0).lGridX = %GRIDSIZEX
        gCcontrols(0).lGridY = %GRIDSIZEY
    
        gsControlTypes(%our_button_type)   = "Button"
        gsControlTypes(%our_checkbox_type) = "CheckBox"
        gsControlTypes(%our_label_type)    = "Label"
        gsControlTypes(%our_textbox_type)  = "TextBox"
        gsControlTypes(%our_listbox_type)  = "ListBox"
        gsControlTypes(%our_listview_type) = $DQ+ "SysListView32" + $DQ
    
        InitCommonControls
    
        DIALOG NEW 0, "One day...",,, 600, 400, _
                    %WS_CAPTION OR %WS_CLIPCHILDREN OR %WS_SYSMENU OR %WS_THICKFRAME, 0 TO ghMainDD
        SetTimer ghMAINDD, %TIMER_SNAP,        %TIMEOUT_SNAP,        %NULL
        SetTimer ghMAINDD, %TIMER_REDRAW_GRID, %TIMEOUT_REDRAW_GRID, %NULL
    
        DIALOG SHOW MODAL ghMAINDD CALL MAINDlgProc
    
    END FUNCTION
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Main callback
    '--------------------------------------------------------------------
    CALLBACK FUNCTION MAINDlgProc() AS LONG
      LOCAL l, X, Y , W, H AS LONG
      STATIC RC AS RECT
      STATIC hPopup, menuchoice AS LONG
      LOCAL p AS PointAPI
      LOCAL s, s1 AS STRING
    
      SELECT CASE CBMSG
         CASE %WM_INITDIALOG
            'DIM GCCONTROLS(1) AS GLOBAL cph
            STATIC hCur AS DWORD ' for static grid brush handle
            gGridSizeX  = %GRIDSIZEX     ' horizontal grid size
            gGridSizeY  = %GRIDSIZEY     ' vertical grid size
    
            gShowGrid   = 1      ' show grid at start
            gSnapToGrid = 1      ' snap drawing to grid at start
            hCur        = LoadCursor(0, BYVAL %IDC_CROSS) ' store handle of cursot to use at draw
            ghBrush     = MakeGridBrush (CBHNDL)           ' and create grid brush
            l           = FloatMenu_Dialog(CBHNDL)
            ' add dialog properties to gCcontrols table first entry
            gCcontrols(0).hd            = CBHNDL
            gCcontrols(0).cid           = 0
            gCcontrols(0).lCtrlType     = %our_dialog_type
            DIALOG GET TEXT CBHNDL TO s
            gCcontrols(0).sText         = s
            gCcontrols(0).sStyles       = gsDialogStyles
            gCcontrols(0).lFontSize     = 0
            gCcontrols(0).sFont         = ""
            gCcontrols(0).sFontAtts     = ""
            gCcontrols(0).lFGColour     = 0
            gCcontrols(0).lBGColour     = 0
            DIALOG GET LOC CBHNDL TO gCcontrols(0).X, gCcontrols(0).Y
            DIALOG GET SIZE CBHNDL TO gCcontrols(0).W, gCcontrols(0).H
            gCcontrols(0).sImgPath      = ""
            gCcontrols(0).hFont         = 0
    
            'ghandcur    = LoadCursorFromFile("handgrab.cur")
         CASE %WM_ERASEBKGND
            FUNCTION=0
            EXIT FUNCTION
    
         CASE %WM_CTLCOLORDLG ' paint grid if gShowGrid is on..
            IF gShowGrid AND ghBrush THEN FUNCTION = ghBrush
    
         CASE %WM_DESTROY 'delete what we created on exit, to avoid mem leaks
             IF ghBrush THEN DeleteObject ghBrush
             IF ghBit   THEN DeleteObject SelectObject(gMemDC, ghBit)
             IF gMemDC  THEN DeleteDC gMemDC  'should already be deleted, but to make sure..
    '        killtimer CBHNDL, %TIMER_SNAP
    '        killtimer CBHNDL, %TIMER_REDRAW_GRID
    
         CASE %WM_SETCURSOR
            ' If mouse button is pressed, over-ride default cursor and
            ' set "own", here cross cursor. Only shown during drawing the control.
            ' Note - in dialogs, we must return
            ' %TRUE to inform dialog engine we have taken charge. In SDK-style
            ' windows, we would have had to return zero and break out.
            IF CBWPARAM = CBHNDL AND HIWRD(CBLPARAM) = %WM_LBUTTONDOWN THEN
               IF GetCursor <> hCur THEN SetCursor hCur
               FUNCTION = 1
            END IF
    
         CASE %WM_LBUTTONDOWN, %WM_LBUTTONDBLCLK 'start selrect draw
            rc.ntop = 0: rc.nbottom = 0: rc.nleft = 0: rc.nright = 0
            selRectBegin CBHNDL
    
         CASE %WM_MOUSEMOVE
            IF (CBWPARAM AND %MK_LBUTTON) THEN 'if mouse button is down while moved, draw rect
               selRectDraw CBHNDL, LOWRD(CBLPARAM), HIWRD(CBLPARAM), RC
            END IF
    
        CASE %WM_MOUSEACTIVATE ' cursor in an inactive child window
                LOCAL p_CrsInSCreen, p_ClientOffset AS POINTAPI
                LOCAL hWndCtrl AS LONG
    
                IF iswindow(ghSCDialog) THEN
                    DIALOG END ghSCDialog, 0 ' kill off showcontrols dialog if it already exists
                END IF
    
                GetCursorPos( p_CrsInScreen )
                ClientToScreen( CBHNDL, p_ClientOffset )
                hWndCtrl = ChildWindowFromPoint( CBHNDL, p_CrsInScreen.X - p_ClientOffset.X, _
                                                         p_CrsInScreen.Y - p_ClientOffset.Y )
                ' exit if cursor is not in a valid Ccontrol!
                IF CCIndexFromhW ( hWndCtrl ) = 0 THEN
                    FUNCTION = 0
                    EXIT FUNCTION
                END IF
                ' exit if cursor is in menu
                'IF (hWndCtrl = ghMenuDialog) THEN
                '    FUNCTION = %MA_NOACTIVATEANDEAT
                '    EXIT FUNCTION
                'END IF
                '
                SELECT CASE HI(WORD, CBLPARAM) ' mouse message
                    CASE %WM_LBUTTONDOWN, %WM_LBUTTONDBLCLK
                        ' If the cursor is in the client area of the CC dialog, then force drag.
                        ' Otherwise, pass message through so dialog gets resived.
                        ' NB control is resized to dialog dimensions on %WM_EXITSIZEMOVE
                        ' in the callback for CCdialog.
    '                    if iswindow(ghCCDialog) then
    '                        DIALOG END ghCCDialog, 0 ' kill off showcontrols dialog if it already exists
    '                    end if
                        IF LO(WORD,CBLPARAM) <> %HTCLIENT THEN
                            ghCCDialog = hWndCtrl
                            FUNCTION = %MA_ACTIVATE                                ' NO, let message through for resize
                        ELSE
                            'setcursor hCur
                            PostMessage hWndCtrl, %WM_NCLBUTTONDOWN, %HTCAPTION, 0 ' YES, FORCE DRAG
                            ghCCDialog = hWndCtrl
                            FUNCTION = %MA_NOACTIVATEANDEAT
                            EXIT FUNCTION
                        END IF
    
                    CASE %WM_RBUTTONDOWN, %WM_RBUTTONDBLCLK
                        ghCCDialog = hWndCtrl
                        hPopup& = CreatePopupMenu
                        CALL InsertMenu(hPopup&, 0, %MF_BYCOMMAND              , 1, "Properties")
                        CALL InsertMenu(hPopup&, 0, %MF_BYCOMMAND OR %MF_GRAYED, 2, "Cut")
                        CALL InsertMenu(hPopup&, 0, %MF_BYCOMMAND,               3, "Copy")
                        CALL InsertMenu(hPopup&, 0, %MF_BYCOMMAND OR %MF_GRAYED, 4, "Paste")
                        CALL InsertMenu(hPopup&, 0, %MF_BYCOMMAND OR %MF_GRAYED, 5, "Select All")
                        CALL InsertMenu(hPopup&, 0, %MF_BYCOMMAND, 6, "Delete")
                        CALL GetCursorPos(BYREF p)
                        MenuChoice = TrackPopupMenuEx(hPopup&, %MF_ENABLED OR %MF_BYCOMMAND OR %TPM_RETURNCMD, p.x, p.y, CBHNDL, BYVAL %NULL)
                        CALL DestroyMenu(hPopup)
                        SELECT CASE menuchoice
    
                            CASE 1 ' Properties
                                glDIALOGPROPERTIES = %FALSE
                                ShowProp(CBHNDL)
    
                            CASE 3 ' Copy
                                CopyControl ( CBHNDL,  hWndCtrl )
    
                            CASE 6 ' Delete
                                CONTROL KILL CBHNDL, %idc_CCID ' kill control
                                RemoveCCFromTable(hWndCtrl)    ' remove from table
                                DIALOG END hwndCtrl, 0         ' kill dialog
                        END SELECT
                        FUNCTION = %MA_NOACTIVATEANDEAT ' that's all for right click
                END SELECT
    
         CASE  %WM_RBUTTONDOWN, %WM_RBUTTONDBLCLK
             IF iswindow(ghSCDialog) THEN
                 DIALOG END ghSCDialog, 0 ' kill off showcontrols dialog if it already exists
             END IF
             l = showCControls(CBHNDL)
    
         CASE %WM_LBUTTONUP 'mouse button released - end draw
            IF selRectEnd( CBHNDL, RC) = 0 THEN
                FUNCTION = 1
                EXIT FUNCTION
            END IF
            snap2grid(ghCCDialog)
            ' Now, when mouse button is released, global RECT (gRc)
            ' will hold coordinates of final drawn rect. If you
            ' for example want to select a group of controls or
            ' other objects, you can use IntersectRect API to see
            ' if parts of other RECT's are withing this global rect.
            ' Or use the coordinates to create a control/object of
            ' this size, whatever..
    
         CASE %WM_PAINT
    
         CASE %WM_CTLCOLORSTATIC
    
         CASE %WM_NCRBUTTONDOWN
             glDIALOGPROPERTIES = %TRUE
             hPopup& = CreatePopupMenu
             CALL InsertMenu(hPopup&, 0, %MF_BYCOMMAND              , 1, "Properties")
             CALL InsertMenu(hPopup&, 0, %MF_BYCOMMAND              , 2, "Save " + g_app_name)
             CALL InsertMenu(hPopup&, 0, %MF_BYCOMMAND              , 3, "Save as..")
             CALL InsertMenu(hPopup&, 0, %MF_BYCOMMAND              , 4, "Load")
             CALL InsertMenu(hPopup&, 0, %MF_BYCOMMAND              , 5, "Export PB source")
             CALL GetCursorPos(BYREF p)
             MenuChoice = TrackPopupMenuEx(hPopup&, %MF_ENABLED OR %MF_BYCOMMAND OR %TPM_RETURNCMD, p.x, p.y, CBHNDL, BYVAL %NULL)
             CALL DestroyMenu(hPopup)
             SELECT CASE menuchoice
    
                 CASE 1 ' Properties
                     glDIALOGPROPERTIES = %TRUE
                     ShowProp(CBHNDL)
                 CASE 2 ' Save
                     SaveCCs(CBHNDL, g_app_name)
                 CASE 3 ' Save As
                     SaveCCs(CBHNDL, "")
                 CASE 4 ' Load
                     LoadCCs(CBHNDL)
                 CASE 5 ' Export PB Source code
                     ExportPBSource(CBHNDL)
             END SELECT
             FUNCTION = %MA_NOACTIVATEANDEAT ' that's all for right click
        END SELECT
    END FUNCTION
    
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' initialize sel rect drawing
    ' Copy dialog to global "screen buffer" for use as base for flicker
    ' free drawing and later restore.
    '--------------------------------------------------------------------
    SUB selRectBegin (BYVAL hWnd AS DWORD)
      LOCAL hDC AS DWORD, hBit AS DWORD, pt AS POINTAPI, rc AS RECT
    
      SetCapture hWnd                 ' set capture to desired window
      GetClientRect hWnd, rc          ' get client size
      MapWindowPoints hWnd, 0, rc, 2  ' map client coordiantes to screen
      ClipCursor rc                   ' clip cursor to client coordinates
    
      GetCursorPos gPt                ' get cursor pos on screen
      ScreenToClient hWnd, gPt        ' convert to client coordinates
    
      IF gSnapToGrid THEN
          gPt.x = (gPt.x \ gGridSizeX) * gGridSizeX  ' if snap to grid, calculate "grid'd pos"
          gPt.y = (gPt.y \ gGridSizeY) * gGridSizeY  ' via multiply of integer divide result
      END IF
    
      GetClientRect hWnd, rc          'create a global memDC and copy window to it.
      hDC    = GetDc(hWnd)
      gMemDC = CreateCompatibleDC (hDC)
      ghBit  = CreateCompatibleBitmap(hDC, rc.nRight, rc.nBottom)
      ghBit  = SelectObject(gMemDC, ghBit)
    
      BitBlt gMemDC, 0, 0, rc.nRight, rc.nBottom, hDC, 0, 0, %SRCCOPY
      ReleaseDc hWnd, hDC
    
    END SUB
    
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' perform sel rect drawing
    '--------------------------------------------------------------------
    SUB selRectDraw (BYVAL hWnd AS DWORD, BYVAL x AS LONG, BYVAL y AS LONG, RCT AS RECT)
    
      LOCAL hDC AS DWORD, hBrush AS DWORD, hPen AS DWORD, rc AS RECT
      LOCAL memDC AS DWORD, hBit AS DWORD
    
      IF gSnapToGrid THEN
         ' MS cross cursor has mis-aligned hotspot - it should be at
         ' cross, but is upper-left corner. We should use own cross,
         ' but this is just a sample, so instead cheat and add 4 to pos..
         x = x + 4 '<- depends on where hotspot in cursor is..
         y = y + 4
         x = (x \ gGridSizeX) * gGridSizeX 'first integer divide, then multiply for "grid effect".
         y = (y \ gGridSizeY) * gGridSizeY
      END IF
    
      ' must make sure rect coordinates are correct,
      ' so right side always is larger than left, etc.
      IF (gPt.x <= x) AND (gPt.y >= y) THEN
         SetRect gRc, gPt.x, y, x, gPt.y
      ELSEIF (gPt.x > x) AND (gPt.y > y) THEN
         SetRect gRc, x, y, gPt.x, gPt.y
      ELSEIF (gPt.x >= x) AND (gPt.y <= y) THEN
         SetRect gRc, x, gPt.y, gPt.x, y
      ELSE
         SetRect gRc, gPt.x, gPt.y, x, y
      END IF
    
      GetClientRect hWnd, rc
      IF gRc.nLeft = gRc.nRight  THEN INCR gRc.nRight '<- ensure we never get a "null rect"
      IF gRc.nTop  = gRc.nBottom THEN INCR gRc.nBottom
    
      hDC = GetDc(hWnd)
      memDC  = CreateCompatibleDC (hDC) 'create temporary memDC to draw in
      hBit   = CreateCompatibleBitmap(hDC, rc.nRight, rc.nBottom)
      hBit   = SelectObject(memDC, hBit)
      hBrush = SelectObject(memDC, GetStockObject(%NULL_BRUSH)) 'for hollow rect
    
      BitBlt memDC, 0, 0, rc.nRight, rc.nBottom, gMemDC, 0, 0, %SRCCOPY 'copy original buffer to temp DC
    
      hPen = SelectObject(memDC, CreatePen(%PS_SOLID, 2, GetSysColor(%COLOR_3DSHADOW))) 'create pen
      Rectangle memDC, gRc.nLeft, gRc.nTop, gRc.nRight + 1, gRc.nBottom + 1             'draw rect
      SETRECT RCT, gRc.nLeft, gRc.nTop, gRc.nRight + 1, gRc.nBottom + 1
    
      DeleteObject SelectObject(memDC, hPen)
    
      BitBlt hDC, 0, 0, rc.nRight, rc.nBottom, memDC, 0, 0, %SRCCOPY 'copy temp DC to window
    
      SelectObject memDC, hBrush
      IF hBit  THEN DeleteObject SelectObject(memDC, hBit) 'clean up to avoid mem leaks
      IF memDC THEN DeleteDC memDC
      ReleaseDc hWnd, hDC
    
    END SUB
    '------------------------------------------------------------------------------
    ' this callback function assumes that the dialog has been added to the gCControls table
    ' it is used for all ccontrols, so should not use any statics or globals (except gCControls)
    '
    CALLBACK FUNCTION CC_dialogProc()
      LOCAL r AS rect
      LOCAL w, h, l, lCX, x, y AS LONG
    
        SELECT CASE AS LONG CBMSG
            CASE %WM_INITDIALOG
                ' Initialization handler
                Snap2Grid (CBHNDL)
                ghCCDialog = CBHNDL
                DIALOG GET CLIENT CBHNDL TO W, H
                DIALOG GET LOC CBHNDL TO X, Y
                CONTROL SET SIZE CBHNDL, %idc_ccID, w, h
                CONTROL SET LOC CBHNDL, %IDC_CCID, 0, 0
                l = CCindexfromhW ( CBHNDL)
                gCcontrols(l).hcurs = loadcursor(0, BYVAL %IDC_SIZEALL)
    
            CASE %WM_NCACTIVATE
                STATIC hWndSaveFocus AS DWORD
                IF ISFALSE CBWPARAM THEN
                    ' Save control focus
                    hWndSaveFocus = GetFocus()
                ELSEIF hWndSaveFocus THEN
                    ' Restore control focus
                    SetFocus(hWndSaveFocus)
                    hWndSaveFocus = 0
                END IF
    
            CASE %WM_EXITSIZEMOVE ' ccontrol has been dragged or sized AFTER first drawn
                DIALOG GET CLIENT CBHNDL TO W, H
                'DIALOG GET LOC CBHNDL TO X, Y
                CONTROL SET SIZE CBHNDL, %idc_ccID, w, h
                CONTROL SET LOC CBHNDL, %IDC_CCID, 0, 0
                snap2grid(CBHNDL)
    
            CASE %WM_NCLBUTTONDOWN
                lCX = CCIndexfromhW(CBHNDL)
                setcursor(gCcontrols(lCX).hCurs)
    
            CASE %WM_LBUTTONDOWN
                SendMessage CBHNDL, %WM_NCLBUTTONDOWN, %HTCAPTION, BYVAL %NULL  ' force drag
    
            CASE %WM_LBUTTONUP
                snap2grid(CBHNDL)
    
            CASE %WM_DESTROY 'delete what we created on exit, to avoid mem leaks
                lCX = CCIndexfromhW(CBHNDL)
                IF gCcontrols(lCX).hFont <> 0 THEN deleteObject gCcontrols(lCX).hFont
                IF gCcontrols(lCX).hCurs <> 0 THEN deleteObject gCcontrols(lCX).hcurs
        END SELECT
    END FUNCTION
    
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' end sel rect drawing
    ' Copy original window buffer back to screen to wipe out drawn
    ' rectangle, delete global memDC, release capture and clipped cursor.
    '--------------------------------------------------------------------
    
    FUNCTION selRectEnd (BYVAL hWnd AS DWORD, RCT AS RECT) AS LONG
        LOCAL hDC AS DWORD, rc AS RECT
        LOCAL hCCDD AS DWORD' dialog handle for control container
        LOCAL lCtrlType, lRslt, CheckState AS LONG
        LOCAL s, sTxt AS STRING
        LOCAL l, X, Y, W, H AS LONG ' new dialog coords in UNITS
        LOCAL lstyle AS LONG ' style attributes to add to window style acc to control type request
    
        ' assume tiny controls are accidental
        IF (rct.nright - rct.nleft) * (rct.nbottom-rct.ntop) < 4 THEN
            ReleaseCapture' or we are stuck with wrong cursor, etc
            EXIT FUNCTION
        END IF
        FUNCTION = %TRUE
        '
        hDC = GetDc(hWnd)
        GetClientRect hWnd, rc
        BitBlt hDC, 0, 0, rc.nRight, rc.nBottom, gMemDC, 0, 0, %SRCCOPY
        ReleaseDc hWnd, hDC
    
        IF ghBit  THEN DeleteObject SelectObject(gMemDC, ghBit) : ghBit  = 0
        IF gMemDC THEN DeleteDC gMemDC    : gMemDC = 0
        ReleaseCapture
    
        FOR lCtrlType = %IDC_CTL1 TO %IDC_CTL6
           CONTROL GET CHECK ghMenuDialog, lCtrlType TO CheCkState
           IF CheckSTate THEN
               ' create a dialog to contain the selected type of control
                DIALOG PIXELS hwnd, RCt.nleft, rct.ntop TO UNITS X, Y
                DIALOG PIXELS hwnd, rct.nright-rct.nleft, rct.nbottom-rct.ntop TO UNITS W, H
                AddCControl( lCtrlType - %our_typecontrol_base, X, Y, W, H)
           END IF
        NEXT lCtrlType
    
        ClipCursor BYVAL %NULL
    
    END FUNCTION
    
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Create a patterned brush for grid. By using this, grid draw becomes
    ' very quick, even on full size dialogs. Must warn though - in Win95,
    ' brush can be max 8x8 pixels. In Win98 and later, brush can be bigger,
    ' so never a problem there.
    '--------------------------------------------------------------------
    FUNCTION MakeGridBrush(BYVAL hDlg AS DWORD) AS DWORD
      LOCAL hDC AS DWORD, memDC AS DWORD, hBit AS DWORD, hBitOld AS DWORD, rc AS RECT
      LOCAL lpx, lpy AS LONG
      hDC     = GetDC(hDlg)
      memDC   = CreateCompatibleDC(hDC)
      DIALOG UNITS hdlg, gGridSizeX, gGridSizeY TO PIXELS lpX, lpY
      hBit    = CreateCompatibleBitmap(hDC, lpX, lpY)
      hBitOld = SelectObject(memDC, hBit)
    
      rc.nRight  = lpX
      rc.nBottom = lpY
      FillRect memDC, rc, GetSysColorBrush(%COLOR_3DFACE)
    
      SetPixelV memDC, 0, 0, 0      'paint "dots" in all four corners
      SetPixelV memDC, 0, lpY, 0
      SetPixelV memDC, lpX, 0, 0
      SetPixelV memDC, lpX, lpY, 0
    
      FUNCTION = CreatePatternBrush (hBit)
    
      SelectObject memDC, hBitOld 'clean up to avoid mem leaks
      DeleteObject hBit
      DeleteDC memDC
      ReleaseDC hDlg, hDC
    
    END FUNCTION
    '------------------------------------------------------------------------------
    CALLBACK FUNCTION FloatMenu_dialogProc()
      STATIC hmenu, hparent AS DWORD
      LOCAL r AS rect
      LOCAL s, s1 AS STRING
      LOCAL l AS LONG
    
        SELECT CASE AS LONG CBMSG
            CASE %WM_INITDIALOG
                ' Initialization handler
                ghMenuDialog = CBHNDL
                hParent = GetParent (CBHNDL)
                CONTROL GET CHECK CBHNDL, %idc_chk1 TO gSnapToGrid
                CONTROL GET CHECK CBHNDL, %idc_chk2 TO gShowgrid
                CONTROL GET CHECK CBHNDL, %idc_chk3 TO gSize2Grid
    
            CASE %WM_NCACTIVATE
                STATIC hWndSaveFocus AS DWORD
                IF ISFALSE CBWPARAM THEN
                    ' Save control focus
                    hWndSaveFocus = GetFocus()
                ELSEIF hWndSaveFocus THEN
                    ' Restore control focus
                    SetFocus(hWndSaveFocus)
                    hWndSaveFocus = 0
                END IF
    
            CASE %WM_LBUTTONDOWN
                SendMessage CBHNDL, %WM_NCLBUTTONDOWN, %HTCAPTION, BYVAL %NULL  ' force drag
    
            CASE %WM_DESTROY 'delete what we created on exit, to avoid mem leaks
    
            CASE %WM_COMMAND
            SELECT CASE CBCTL  ' <- look at control's id
               CASE %IDC_CHK1
                  IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                     CONTROL GET CHECK CBHNDL, CBCTL TO gSnapToGrid
                  END IF
    
               CASE %IDC_CHK2
                  IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                     CONTROL GET CHECK CBHNDL, CBCTL TO gShowGrid
                      IF gShowGrid <> 0 THEN
                          CONTROL GET TEXT CBHNDL, %IDC_gridX_tb TO s ' redraw grid
                          CONTROL GET TEXT CBHNDL, %IDC_gridY_tb TO s1
                          gGridSizeX = VAL(s)
                          gGridSizeY = VAL(s1)
                          gCcontrols(0).lGridX = gGridSizeX
                          gCcontrols(0).lGridY = gGridSizeY
                          IF ghBrush THEN DeleteObject ghBrush
                          ghBrush = MakeGridBrush (ghMainDD)           ' and create grid brush for main dialog
                          IF gSnapToGrid THEN
                              FOR l = 0 TO gCCX
                                  Snap2Grid ( gCControls(l).hD )
                              NEXT
                          END IF
                      END IF
                     RedrawWindow hparent, BYVAL %NULL, 0, %RDW_ERASE OR %RDW_INVALIDATE OR %RDW_UPDATENOW
                  END IF
    
               CASE %IDC_CHK1
                  IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                     CONTROL GET CHECK CBHNDL, CBCTL TO gSnapToGrid
                  END IF
    
               CASE %IDC_CHK3
                  IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                     CONTROL GET CHECK CBHNDL, CBCTL TO gSize2Grid
                  END IF
    
               CASE %IDC_gridx_tb
                  IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN 'end prog
    
                  END IF
            END SELECT
        END SELECT
    END FUNCTION
    
    '------------------------------------------------------------------------------
    FUNCTION FloatMenu_dialog(BYVAL hParent AS DWORD) AS LONG
        LOCAL lRslt AS LONG
        LOCAL hDlg  AS DWORD
    
        DIALOG NEW hParent, "", 570, 100, 65, 140, %WS_POPUP OR %WS_THICKFRAME OR _
            %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
            %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_TOOLWINDOW OR _
            %WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING TO hdlg
            'OR _
            '%WS_EX_RIGHTSCROLLBAR, TO hDlg
        DIALOG  SET COLOR   hDlg, -1, RGB(255, 255, 155)
        CONTROL ADD CHECKBOX, hDlg, %IDC_CHK1, "&Snap to grid ",    2,  5, 60, 10
        CONTROL ADD CHECKBOX, hDlg, %IDC_CHK2, "S&how grid ",       2, 15, 60, 10
        CONTROL ADD CHECKBOX, hDlg, %IDC_CHK3, "Si&ze to grid ",    2, 25, 60, 10
    
        CONTROL SET CHECK hDlg, %IDC_CHK1, 1
        CONTROL SET CHECK hDlg, %IDC_CHK2, 1
        CONTROL SET CHECK hDlg, %IDC_CHK3, 1
    
        CONTROL ADD LABEL, hDlg,  %IDC_LAB1,      "Grid size X"            , 2, 50, 38, 10
        CONTROL ADD TEXTBOX, hDlg, %IDC_gridx_tb, TRIM$(STR$(gGridSizeX))  ,45, 50, 16, 10, %ES_NUMBER
        CONTROL ADD LABEL, hDlg,  %IDC_LAB2,      "Grid size Y"            ,2 , 60, 38, 10
        CONTROL ADD TEXTBOX, hDlg, %IDC_gridy_tb, TRIM$(STR$(gGridSizeY))  ,45, 60, 16, 10, %ES_NUMBER
    
        CONTROL ADD OPTION, hDlg, %IDC_CTL1, "&Label",     2, 75, 60, 10
        CONTROL ADD OPTION, hDlg, %IDC_CTL2, "&Text Box",  2, 85, 60, 10
        CONTROL ADD OPTION, hDlg, %IDC_CTL3, "&CheckBox",  2, 95, 60, 10
        CONTROL ADD OPTION, hDlg, %IDC_CTL4, "&Listbox",   2, 105, 60, 10
        CONTROL ADD OPTION, hDlg, %IDC_CTL5, "List&view",  2, 115, 60, 10, %WS_GROUP
        CONTROL ADD OPTION, hDlg, %IDC_CTL6, "&Button",    2, 125, 60, 10
        CONTROL SET OPTION hDlg, %IDC_CTL1, %IDC_CTL1, %IDC_CTL3 ' set initial state
    
        DIALOG SHOW MODELESS hDlg, CALL FloatMenu_dialogProc TO lRslt
    
        FUNCTION = lRslt
    END FUNCTION
    '------------------------------------------------------------------------------
    ' turn col & row coords into data from the gCControls table
    FUNCTION get_x_item ( col AS LONG, row AS LONG ) AS STRING
        LOCAL s AS STRING
        LOCAL lrow AS LONG
    
        lrow = row '+ 1
        SELECT CASE AS LONG col
            CASE 0
                s = USING$("########", gCControls(lrow).hD)  ' HD
            CASE 1
                s = USING$("###", gCControls(lrow).Cid)  ' Control id
            CASE 2
                S = gsControlTypes(gCControls(lrow).lCtrlType)
            CASE 3
                s = gCControls(lrow).sText
            CASE 4
                s = gCControls(lrow).sStyles
            CASE 5
                s = USING$("##", gCControls(lrow).lFontSize)
            CASE 6
                s = gCControls(lrow).sFont
            CASE 7
                s = gCControls(lrow).sFontAtts
            CASE 8
                s = HEX$(gCControls(lrow).lFGColour, 6)  ' FGColour
            CASE 9
                s = HEX$(gCControls(lrow).lBGCOlour,6)   ' BGColour
            CASE 10
                s = USING$("####", gCControls(lrow).X)   ' X
            CASE 11
                s = USING$("####", gCControls(lrow).Y)   ' Y
            CASE 12
                s = USING$("####", gCControls(lrow).W)   ' W
            CASE 13
                s = USING$("####", gCControls(lrow).H)   ' H
        END SELECT
        FUNCTION = s
    END FUNCTION
    '--------------------------------------------------------------------------------
    ' from Stan Durham's source code posting Xmas 2006
    FUNCTION SDMakeFont(BYVAL sFontName AS STRING, BYVAL nPointSize AS LONG, BYVAL bIsBold AS LONG, BYVAL bIsItalic AS LONG, BYVAL bIsUnderline AS LONG ) AS LONG
        LOCAL hDC AS LONG, CyPixels AS LONG
    
        hDC = GetDC(%HWND_DESKTOP)
        CyPixels  = GetDeviceCaps(hDC, %LOGPIXELSY)
        ReleaseDC %HWND_DESKTOP, hDC
        nPointSize = (nPointSize * CyPixels) \ 72
    
        FUNCTION = CreateFont(0 - nPointSize, 0, 0, 0, IIF&(bIsBold, %FW_BOLD, %FW_NORMAL), bIsItalic, bIsUnderline, 0, _
                   %ANSI_CHARSET, %OUT_TT_PRECIS, %CLIP_DEFAULT_PRECIS, _
                   %DEFAULT_QUALITY, %FF_DONTCARE, BYCOPY sFontName)
    END FUNCTION
    '------------------------------------------------------------------------------
    ' ListView Custom Draw controls table
    FUNCTION LVCC ( BYVAL ptlvcd AS NMLVCUSTOMDRAW PTR ) AS LONG
    
      LOCAL szItem          AS ASCIIZ * %MAX_PATH   ' item text
      LOCAL trcItem         AS RECT                 ' bounding rectangle of item/subitem
      LOCAL tlv_item        AS LV_ITEM              ' listview item information
      LOCAL tlb             AS LOGBRUSH             ' specifies information used to create background brush
      LOCAL hWndHdr         AS DWORD                ' handle of header child control
      LOCAL hBrush          AS DWORD
      LOCAL hBrushOld       AS DWORD
      LOCAL hPenOld         AS DWORD
      LOCAL dwBackColor     AS DWORD
      LOCAL nBkModeOld      AS INTEGER
      LOCAL hfont AS LONG
    
      ' Get the item or subitem info
      tlv_item.mask       = %LVIF_TEXT OR %LVIF_IMAGE OR %LVIF_STATE
      tlv_item.stateMask  = %LVIS_FOCUSED OR %LVIS_SELECTED
      tlv_item.iItem      = @ptlvcd.nmcd.dwItemSpec
      tlv_item.iSubItem   = @ptlvcd.iSubItem
      tlv_item.pszText    = VARPTR(szItem)
      tlv_item.cchTextMax = %MAX_PATH
      SendMessage @ptlvcd.nmcd.hdr.hwndFrom, %LVM_GETITEM, 0, BYVAL VARPTR(tlv_item)
    
        ' set up font
        hFont = SDMakeFont("courier new",  9,  0,  0,  0)
        SendMessage @ptlvcd.nmcd.hdr.hwndFrom, %WM_SETFONT, hFont, 0
    
      ' Get the bounding rectangle of the subitem(cell)
      trcItem.nLeft = %LVIR_BOUNDS
      trcItem.nTop  = @ptlvcd.iSubItem
      SendMessage @ptlvcd.nmcd.hdr.hwndFrom, %LVM_GETSUBITEMRECT, @ptlvcd.nmcd.dwItemSpec, BYVAL VARPTR(trcItem)
    
      tlb.lbStyle = %BS_SOLID
      dwBackColor = RGB(236,189,147) ' salmon pink background
      tlb.lbColor = dwBackColor
      tlb.lbHatch = 0
      hBrush = CreateBrushIndirect(tlb)
      FillRect @ptlvcd.nmcd.hdc, trcItem, hBrush
      DeleteObject hBrush
    
      ' Draw the text
      nBkModeOld = SetBkMode(@ptlvcd.nmcd.hdc, %TRANSPARENT)
      DrawTextEx @ptlvcd.nmcd.hdc, szItem, LEN(szItem), trcItem, %DT_SINGLELINE OR %DT_LEFT OR %DT_VCENTER OR %DT_END_ELLIPSIS, BYVAL %NULL
      SetBkMode @ptlvcd.nmcd.hdc, nBkModeOld
    
      ' Draw focus rectangle
      ' Note: it is drawn when the last column is painted.
      IF (tlv_item.STATE AND %LVIS_FOCUSED) = %LVIS_FOCUSED THEN
        hWndHdr = SendMessage(@ptlvcd.nmcd.hdr.hwndFrom, %LVM_GETHEADER, 0, 0)
        IF @ptlvcd.iSubItem = SendMessage(hWndHdr, %HDM_GETITEMCOUNT, 0, 0) - 1 THEN
          ' Get the bounding rectangle of the entire item(this includes all subitems)
          trcItem.nLeft = %LVIR_BOUNDS
          SendMessage @ptlvcd.nmcd.hdr.hwndFrom, %LVM_GETITEMRECT, @ptlvcd.nmcd.dwItemSpec, BYVAL VARPTR(trcItem)
          ' Black pen 2 pixels thick
          hPenOld   = SelectObject(@ptlvcd.nmcd.hdc, CreatePen(%PS_SOLID, 3 * GetSystemMetrics(%SM_CXBORDER), &H8c08c08c0???))
          ' A hollow brush is used to avoid erasing what was painted already
          hBrushOld = SelectObject(@ptlvcd.nmcd.hdc, GetStockObject(%NULL_BRUSH))
    '      Rectangle @ptlvcd.nmcd.hdc, trcItem.nLeft, trcItem.nTop, trcItem.nRight, trcItem.nBottom
    '      modifed rectanlge to give an underscore
          rectangle @ptlvcd.nmcd.hdc, trcItem.nLeft, trcItem.nbottom-1, trcItem.nRight, trcItem.nBottom
          SelectObject @ptlvcd.nmcd.hdc, hBrushOld
          DeleteObject SelectObject(@ptlvcd.nmcd.hdc, hPenOld)
        END IF
      END IF
    
      FUNCTION = %CDRF_SKIPDEFAULT
    
    END FUNCTION
    '---------------------------------------------------------------------------------------
    SUB InitSCLV ( hD AS DWORD )
        LOCAL lCol, lRow, lcolcnt, lrowcnt, X, Y   AS LONG
        LOCAL hCtl, hSCDD   AS DWORD
        LOCAL tLVC   AS LV_COLUMN
        LOCAL tLVI   AS LV_ITEM
        LOCAL szBuf  AS ASCIIZ * 32
        LOCAL lStyle AS LONG
    
        CONTROL HANDLE hD, %IDC_SHOWCONTROLS_LV TO hCtl
        lStyle = ListView_GetExtendedListViewStyle(hCtl)
        lStyle = lStyle OR %LVS_EX_GRIDLINES OR %LVS_EX_FULLROWSELECT  OR %LVS_EX_UNDERLINEHOT _
                        OR %LVS_EX_ONECLICKACTIVATE OR %LVS_EX_LABELTIP 'OR %LVS_EX_FULLROWSELECT
        CALL SendMessage(hCTL, %LVM_SETEXTENDEDLISTVIEWSTYLE, 0, BYVAL lStyle)
    
        lcolcnt = 14 ' lucky for some
        lrowcnt = gCCX +1
    
        ' Load column headers.
        tLVC.mask    = %LVCF_FMT OR %LVCF_TEXT OR %LVCF_SUBITEM
        tLVC.fmt     = %LVCFMT_LEFT
        tLVC.pszText = VARPTR(szBuf)
        szBuf       = "handle"          :tLVC.iOrder = 0 : ListView_InsertColumn hCtl, 0, tLVC
        szBuf       = "Ctrl Id"         :tLVC.iOrder = 1 : ListView_InsertColumn hCtl, 2, tLVC
        szBuf       = "Ctrl Type"       :tLVC.iOrder = 2 : ListView_InsertColumn hCtl, 3, tLVC
        szBuf       = "Text"            :tLVC.iOrder = 3 : ListView_InsertColumn hCtl, 4, tLVC
        szBuf       = "Styles"          :tLVC.iOrder = 4 : ListView_InsertColumn hCtl, 5, tLVC
        szBuf       = "Font size"       :tLVC.iOrder = 5 : ListView_InsertColumn hCtl, 6, tLVC
        szBuf       = "Font Name"       :tLVC.iOrder = 6 : ListView_InsertColumn hCtl, 7, tLVC
        szBuf       = "Font Attributes" :tLVC.iOrder = 7 : ListView_InsertColumn hCtl, 8, tLVC
        szBuf       = "FG color"        :tLVC.iOrder = 8 : ListView_InsertColumn hCtl, 9, tLVC
        szBuf       = "BG color"        :tLVC.iOrder = 9 : ListView_InsertColumn hCtl, 10, tLVC
        szBuf       = "TopLeft X"       :tLVC.iOrder = 10 : ListView_InsertColumn hCtl, 11, tLVC
        szBuf       = "TopLeft Y"       :tLVC.iOrder = 11 : ListView_InsertColumn hCtl, 12, tLVC
        szBuf       = "Width"           :tLVC.iOrder = 12 : ListView_InsertColumn hCtl, 13, tLVC
        szBuf       = "Height"          :tLVC.iOrder = 13 : ListView_InsertColumn hCtl, 14, tLVC
        ' Auto size columns.
        FOR lCol = 0 TO lColCnt - 2
            ListView_SetColumnWidth hCtl, lCol, %LVSCW_AUTOSIZE_USEHEADER
        NEXT lCol
        ListView_SetColumnWidth hCtl, lColCnt - 1, %LVSCW_AUTOSIZE_USEHEADER
        '
        CONTROL SEND hD, %IDC_SHOWCONTROLS_LV, %LVM_DELETEALLITEMS ,0,0
        CONTROL SEND hD, %IDC_SHOWCONTROLS_LV, %LVM_SETITEMCOUNT, lrowcnt ,%LVSICF_NOINVALIDATEALL OR %LVSICF_NOSCROLL
    END SUB
    
    '------------------------------------------------------------------------------
    CALLBACK FUNCTION SC_dialogProc()
      STATIC hmenu, hparent AS DWORD
      LOCAL s, s1, squery AS STRING
        LOCAL l, X, Y AS LONG
        LOCAL pnmh AS NMHDR PTR
        LOCAL pnm AS NMLVCUSTOMDRAW PTR
        ' once again, one of those oh so easy to follow sturctures with sturctures
        ' inside them. The main thing here is that this will tell you what row & col
        ' is in need of filling. Row is iItem & col is iSubItem
        LOCAL lpLVDispInfo AS LV_DISPINFO PTR
    
        ' an asciiz string that windows expects when you tell
        ' it what to show in the listview
        LOCAL szString AS ASCIIZ * 256
    
        SELECT CASE AS LONG CBMSG
            CASE %WM_INITDIALOG
                ' Initialization handler
                hParent = GetParent (CBHNDL)
                ghSCDialog = CBHNDL
                DIALOG GET SIZE CBHNDL TO x, y
                CONTROL SET SIZE CBHNDL, %IDC_SHOWCONTROLS_LV, x-4, y-4
                InitSCLV(CBHNDL) ' set up listview header
                l = gCCX
                DIALOG SET TEXT CBHNDL, STR$(l)
                '
            CASE %WM_NCACTIVATE
                STATIC hWndSaveFocus AS DWORD
                IF ISFALSE CBWPARAM THEN
                    ' Save control focus
                    hWndSaveFocus = GetFocus()
                ELSEIF hWndSaveFocus THEN
                    ' Restore control focus
                    SetFocus(hWndSaveFocus)
                    hWndSaveFocus = 0
                END IF
    
            CASE %WM_NOTIFY
                pnmh = CBLPARAM
                SELECT CASE @pnmh.code
                    CASE %NM_CUSTOMDRAW
                        pnm = CBLPARAM
                        SELECT CASE @pnm.nmcd.dwDrawStage
                            CASE %CDDS_PREPAINT
                                ' The following statement ensures that the relevant
                                ' messages are coming back to Windows, so Windows
                                ' can respond appropriately.
                                SetWindowLong CBHNDL,%DWL_MSGRESULT,%CDRF_NOTIFYITEMDRAW
                                ' This statement makes the DDT engine happy:
                                FUNCTION = 1: EXIT FUNCTION
                            CASE %CDDS_ITEMPREPAINT
                                SetWindowLong CBHNDL,%DWL_MSGRESULT,%CDRF_NOTIFYSUBITEMDRAW
                                FUNCTION = 1: EXIT FUNCTION
                            CASE %CDDS_SUBITEM 'OR %CDDS_ITEMPREPAINT
                                IF @pnmh.idFrom = %IDC_SHOWCONTROLS_LV THEN
                                     FUNCTION = LVCC(BYVAL pnm)
                                     EXIT FUNCTION
                                END IF
                        END SELECT
                        '
                    CASE %LVN_GETDISPINFO    'Virtual ListView ask for Item text
                        lpLVDispInfo = CBLPARAM
                        IF (@lpLVDispInfo.item.mask AND %LVIF_TEXT) THEN
                            ' Specify text to be used
                            IF @pnmh.idFrom = %IDC_SHOWCONTROLS_LV THEN
                                szString =  get_x_item(@lpLVDispInfo.item.iSubItem, @lpLVDispInfo.item.iItem)
                            END IF
                            @lpLVDispInfo.item.pszText = VARPTR(szString)
                        END IF
                END SELECT
    
            CASE %WM_LBUTTONDOWN
                SendMessage CBHNDL, %WM_NCLBUTTONDOWN, %HTCAPTION, BYVAL %NULL  ' force drag
    
            CASE %WM_DESTROY 'delete what we created on exit, to avoid mem leaks
        END SELECT
    END FUNCTION
    '--------------------------------------------------------------------
    ' Popup to show the CControls table contents
    '--------------------------------------------------------------------
    FUNCTION ShowCControls ( BYVAL hParent AS DWORD) AS LONG
        LOCAL hDlg  AS DWORD
        LOCAL lrslt AS LONG
    
        DIALOG NEW hParent, "CCONTROLS DEBUG ", 40, 40, 500, 200, _
            %WS_POPUP _
            OR %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR %WS_CLIPSIBLINGS OR _
            %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
            %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _
            %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hdlg
    
        CONTROL ADD "SysListView32", hDlg, %IDC_SHOWCONTROLS_LV, "", 0,0,0,0, _
                     %DEFAULT_LV_STYLES OR %LVS_OWNERDATA,%DEFAULT_LV_EX_STYLES
    
        DIALOG SHOW MODELESS hDlg, CALL SC_dialogProc TO lRslt
    
        FUNCTION = lrslt
    END FUNCTION
    '----------------------------------------------------------------------------
    ' put the XYWH of current CControl into the global array
    SUB StoreCurrentCoords ( l AS LONG)
        DIALOG GET LOC  ghCCDialog TO gCcontrols(l).X, gCcontrols(l).Y
        DIALOG GET SIZE ghCCDialog TO gCcontrols(l).W, gCcontrols(l).H
    END SUB
    '-----------------------------------------------------------------------------------------------------------
    '  load global styles table to listview
    '
    '------------------------------------------------------------------------------
    SUB loadStyles2ListView  ( hD AS DWORD, lC AS LONG)
    '    LOCAL i, row, iPos AS LONG
        LOCAL lvhit AS LV_HITTESTINFO, lvi AS LV_ITEM, lvc AS LV_COLUMN
        LOCAL sz AS ASCIIZ * 1024, rc AS RECT
        LOCAL CtrlType, hfile, lrow, lcol, l, lstyle AS LONG
        LOCAL hCtl AS DWORD
        LOCAL s AS STRING
    
        CONTROL HANDLE hD, lC TO hCtl  ' get window handle from listview conrol
        listview_deleteallitems(hCtl)
        lStyle = ListView_GetExtendedListViewStyle(hCtl)
        ListView_SetExtendedListViewStyle hCtl, lStyle OR %LVS_EX_FULLROWSELECT OR %LVS_EX_GRIDLINES _
                                                OR %LVS_EX_LABELTIP
        ' find out what control type we are
        IF glDIALOGPROPERTIES THEN
            CtrlType = 0
        ELSE
            l = CCIndexFromhW ( ghCCDialog )
            CtrlType = gCcontrols( l ).LCtrlType
        END IF
        ' Set column info...
        sz       = "Style name"
        lvc.mask    = %LVCF_WIDTH OR %LVCF_TEXT
        lvc.pszText = VARPTR(sz)
        CONTROL SEND hD, lC, %LVM_INSERTCOLUMN, 0, VARPTR(lvc)
        sz       = "Help text"
        lvc.mask    = %LVCF_WIDTH OR %LVCF_TEXT
        lvc.pszText = VARPTR(sz)
        CONTROL SEND hD, lC, %LVM_INSERTCOLUMN, 1, VARPTR(lvc)
        LVI.stateMask = %LVIS_FOCUSED
        LVI.pszText   = VARPTR(sz)
        LVI.iItem     = lRow
        ' extract styles for current control type from STYLES.TXT
        hfile = FREEFILE
        lrow = 0
        OPEN $STYLESDBPATH FOR INPUT AS #hfile
        LINE INPUT #hfile, s
        WHILE NOT EOF(hfile)
            IF VAL(TRIM$(PARSE$(s, 1))) = CtrlType THEN
                sz           = PARSE$(s,2)  ' style name
                LVI.iSubItem = 0
                LVI.lParam   = lrow
                LVI.mask     = %LVIF_TEXT OR %LVIF_PARAM OR %LVIF_STATE
                ListView_InsertItem hCtl, LVI
                '
                sz = RIGHT$(s, LEN(s) - INSTR(s,$DQ)) ' help text
                LVI.iSubItem = 1
                LVI.mask     = %LVIF_TEXT
                ListView_SetItem hCtl, LVI
                INCR lrow
            END IF
            LINE INPUT #hfile, s
        WEND
        CLOSE #hfile
    
        ' Auto size columns.
        ListView_SetColumnWidth hCtl, 0, %LVSCW_AUTOSIZE_USEHEADER
        ListView_SetColumnWidth hCtl, 1, %LVSCW_AUTOSIZE_USEHEADER
    END SUB
    '------------------------------------------------------------------------------
    ' this adjusts the height of the textbox to receive the string S.
    ' It assumes that on entry S has the maximum height
    SUB SqueezeTB2Text ( hD AS DWORD, hC AS LONG, s AS STRING )
        LOCAL hWndTxt AS DWORD
        LOCAL rc, rcTxt1, rcTxt2 AS rect
        LOCAL NCHeight, row AS LONG
        'local txt as string
        LOCAL szText    AS ASCIIZ*1024
        LOCAL hDC       AS DWORD
        LOCAL hFont     AS LONG
        LOCAL nWidth    AS LONG
        LOCAL nHeight   AS LONG
        LOCAL hFontOld  AS LONG
        LOCAL x, y, xx, yy AS LONG
    
         CONTROL HANDLE hD, hC TO hWndTxt
         GetWindowRect hWndTXT, rcTxt1
         GetClientRect hWndTXT, rcTxt2
         MapWindowPoints %HWND_DESKTOP, hD, rcTxt1, 2
         MapWindowPoints %HWND_DESKTOP, hD, rcTxt2, 2
         NCHeight = (rcTxt1.nBottom-rcTxt1.nTop)-(rcTxt2.nBottom-rcTxt2.nTop)
         'CONTROL GET TEXT hD, hC TO txt
         IF s = "" THEN EXIT SUB
         szText = s
         hFont=SendMessage(hWndTXT, %WM_GETFONT, 0, 0)
         hDC=GetDC(hWndTXT)
         hFontOld=SelectObject(hDC, hFont)
         TYPE SET rc=rcTxt2
         DrawText hDC, szText, LEN(szText), rc, %DT_CALCRECT OR %DT_WORDBREAK
         SelectObject hDC, hFontOld
         ReleaseDC hWndTXT, hDC
         x=rcTxt1.nLeft
         y=rcTxt1.nTop
         xx=(rcTxt1.nRight-rcTxt1.nLeft)
         yy=(rc.nBottom-rc.nTop)+(NCHeight*2)
         IF (yy - (NCHeight*2)) < (rcTxt2.nbottom - rcTxt2.ntop) THEN
            MoveWindow hWndTXT, x, y, xx, yy, %TRUE
         END IF
         CONTROL SET TEXT hD, hC, s
    
    END SUB
    '--------------------------------------------------------------------
    ' select colour, return RGB code as atring
    FUNCTION SelColour( hD AS DWORD) AS STRING
    
            STATIC CCA      AS CHOOSECOLORAPI
            LOCAL lResult   AS LONG
            STATIC clrRef() AS DWORD ' colorref
    
            DIM clrRef(0 TO 16) AS STATIC DWORD 'colorref
    
            CCA.lStructSize   = LEN(CCA)
            CCA.hwndOwner  = hD
            CCA.lpCustColors = VARPTR(ClrRef())
            CCA.rgbResult     = getsyscolor(%color_3dface)
            CCA.Flags          = CCA.Flags OR %CC_RGBINIT 'or %CC_FULLOPEN
    
            lResult = ChooseColor(CCA)
    
            IF lResult <> 0 THEN 'check if user cancelled dialog ?
                FUNCTION = HEX$(CCA.rgbResult,6)
                'to get RGB sequence, use RIGHT$(ClrStr,2) + MID$(ClrStr,3,2) + LEFT$ (ClrStr,2)
            END IF
    
    END FUNCTION  
    '----------------------------------------------------------------------------
    SUB ReFont ( hD AS DWORD, hC AS LONG, hFont AS LONG, sFont AS STRING, lFontsize AS LONG, _
                 lBold AS LONG, lItalic AS LONG, lUnderline AS LONG, lFGcolour AS LONG, lBGColour AS LONG)
    
        IF hFont <> 0 THEN
            deleteObject hfont
        END IF
        hFont = SDMakeFont(sFont, lfontsize, lbold, litalic, lunderline)
        CONTROL SEND hD, hC, %WM_SETFONT, hFont, 0
        CONTROL SET COLOR hD, hC, lfgcolour, lbgcolour
        CONTROL REDRAW hD, hC
    END SUB
    '----------------------------------------------------------------------------
    ' parameters : dialog, listview Styles control, gCControls index, styles string
    ' if styles string is null, use default styles
    ' select rows in listview corresponding to default styles for current control
    ' return handle to listview
    FUNCTION SelDefaultStyles ( hD AS DWORD, lC AS LONG, lcx AS LONG, sTyles AS STRING) AS LONG
        LOCAL s AS STRING
        LOCAL i, hlistview, row AS LONG
        LOCAL lvf AS LVFindInfo
        LOCAL sz AS ASCIIZ * 1024
         CONTROL HANDLE hD, lC TO hListView
         FUNCTION = hListView
         IF sTyles = "" THEN ' use default styles
             SELECT CASE gCcontrols(lCX).lCtrlType
                 CASE %our_dialog_type
                     s = $DEFAULT_DLG_STYLES
                 CASE %our_label_type
                     s = $DEFAULT_LAB_STYLES
                 CASE %our_textbox_type
                     s = $DEFAULT_TB_STYLES
                 CASE %our_checkbox_type
                     s = $DEFAULT_CB_STYLES
                 CASE %our_listbox_type
                     s = $DEFAULT_LB_STYLES
                 CASE %our_listview_type
                     s = $DEFAULT_LV_STYLES
                 CASE %our_button_type
                     s = $DEFAULT_BN_STYLES
             END SELECT
         ELSE
             s = sTyles
         END IF
         ListView_SetItemState (hListView, -1, %NULL, %LVIS_SELECTED OR %LVIS_FOCUSED)' turn all off
         FOR i = 1 TO PARSECOUNT(s)
              sz = PARSE$(s,i)
              LVF.flags = %LVFI_STRING
              LVF.psz = VARPTR(sz)
              row = Listview_FindItem ( hListView, -1, LVF)
              IF row <> -1 THEN
                  ListView_SetItemState (hListView, row, %LVIS_SELECTED OR %LVIS_FOCUSED, %LVIS_SELECTED OR %LVIS_FOCUSED)
              END IF
         NEXT
         CONTROL SET FOCUS hD, lC
    END FUNCTION
    '----------------------------------------------------------------------------
    CALLBACK FUNCTION ShowPROPProc()
        STATIC lCX, row AS LONG
        LOCAL LVF AS lVFindInfo
        LOCAL s AS STRING
        STATIC hTBW, hListView AS LONG
        LOCAL lvhit AS LV_HITTESTINFO, lvi AS LV_ITEM, lvc AS LV_COLUMN
        LOCAL sz AS ASCIIZ * 1024, rc AS RECT
        STATIC hFont, i, lbgcolour, lfgcolour, lbold, litalic, lunderline, lfontsize AS LONG
        STATIC sfont AS STRING
        STATIC pCFS AS CHOOSEFONTAPI   POINTER
        STATIC pLF  AS LOGFONT         POINTER
        STATIC hParent AS DWORD
    
        SELECT CASE AS LONG CBMSG
            CASE %WM_INITDIALOG
                lFGColour = getsyscolor(%COLOR_WINDOWTEXT)
                lBGColour = getsyscolor(%COLOR_3dface)
                hParent = getParent(CBHNDL)
                ghPROPDD = CBHNDL
                IF glDIALOGPROPERTIES  = %TRUE THEN
                    lCX = 0
                ELSE
                    lCX = CCIndexfromhW ( ghCCDialog) ' get index to GCControls table
                END IF
                StoreCurrentCoords(lCX) ' put XYWH into gCcontrols()
                LoadStyles2ListView(CBHNDL, %IDC_AV_STYLES_LV)
                'CONTROL HANDLE CBHNDL, %IDC_STYLES_TB TO hTBW
                'CONTROL HANDLE CBHNDL, %IDC_AV_STYLES_LV TO hListView
                ' populate controls from CcControls table
                CONTROL SET TEXT CBHNDL, %IDC_TEXT_TB, TRIM$(gCcontrols(lCX).sText)
                '
                s = TRIM$(gCcontrols(lCX).sStyles)
                hListView = SelDefaultStyles ( CBHNDL, %IDC_AV_STYLES_LV, lCX, s )
                sFont = gCcontrols(lCX).sFont
                CONTROL SET TEXT CBHNDL, %IDC_FONT_BN,          sFont
                CONTROL SET TEXT CBHNDL, %IDC_LABEL1,           "Dialog Id " + STR$(gCcontrols(lCX).hD)
                CONTROL SET TEXT CBHNDL, %IDC_CTRL_NO_LAB,      "Control Number" + STR$(gCcontrols(lCX).Cid)
                CONTROL SET TEXT CBHNDL, %IDC_CTRL_TYPE_LAB,    "Type of Control " + gsControlTypes(gCcontrols(lCX).lCtrlType)
                lfontsize = gCcontrols(lCX).lFontSize
                CONTROL SET TEXT CBHNDL, %IDC_FONTSIZE_LAB,     STR$(lFontSize)
                s = gCcontrols(lCX).sFontAtts
                lunderline= %FALSE: litalic = %FALSE: lbold = %FALSE
                IF INSTR(s, "bold")      THEN lbold = %TRUE
                IF INSTR(s, "italic")    THEN litalic = %TRUE
                IF INSTR(s, "underline") THEN lunderline = %TRUE
                CONTROL SET TEXT CBHNDL, %IDC_FONTATTS_LAB,     s
                gCcontrols(lCX).lBGColour = lBGColour
                gCcontrols(lCX).lFGColour = lFGcolour
                CONTROL SET TEXT CBHNDL, %IDC_BGCOLOR_BN, "background:" + HEX$(gCcontrols(lCX).lBGColour,6)
                CONTROL SET TEXT CBHNDL, %IDC_FONTATTS_LAB,     gCcontrols(lCX).sFontAtts
                CONTROL SET TEXT CBHNDL, %IDC_X_LAB,            "X=" + STR$(gCcontrols(lCX).X)
                CONTROL SET TEXT CBHNDL, %IDC_Y_LAB,            "Y=" + STR$(gCcontrols(lCX).Y)
                CONTROL SET TEXT CBHNDL, %IDC_W_LAB,            "W=" + STR$(gCcontrols(lCX).W)
                CONTROL SET TEXT CBHNDL, %IDC_H_LAB,            "H=" + STR$(gCcontrols(lCX).H)
                hFont = gCcontrols(lCX).hFont
                ReFont (CBHNDL, %IDC_TEXT_TB, hFont, sFont, lFontSize, lbold, lItalic, lUnderline, lFGCOlour, lBGColour)
    
            CASE %WM_DESTROY
                ' don't delete the font here! do it in the callback function for the CCDialog!
    
            CASE %WM_NCACTIVATE
                STATIC hWndSaveFocus AS DWORD
                IF ISFALSE CBWPARAM THEN
                    hWndSaveFocus = GetFocus()
                ELSEIF hWndSaveFocus THEN
                    SetFocus(hWndSaveFocus)
                    hWndSaveFocus = 0
                END IF
    '
            CASE %WM_COMMAND
                SELECT CASE AS LONG CBCTL
                    CASE %IDC_DEF_STYLES_BN
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN 'end prog
                            LoadStyles2ListView(CBHNDL, %IDC_AV_STYLES_LV)
                            SelDefaultStyles ( CBHNDL, %IDC_AV_STYLES_LV, lCX, "")
                        END IF
                        
                    CASE %IDC_ORG_STYLES_BN
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN 'end prog
                            LoadStyles2ListView(CBHNDL, %IDC_AV_STYLES_LV)
                            s = TRIM$(gCcontrols(lCX).sStyles)
                            SelDefaultStyles ( CBHNDL, %IDC_AV_STYLES_LV, lCX, s )
                        END IF
    
                    CASE %IDC_SAVE_BN
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN 'end prog
                            ' copy changeable control texts back to global array
                            CONTROL GET TEXT CBHNDL, %IDC_TEXT_TB       TO s
                            gCcontrols(lCX).sText = TRIM$(s)
                            'save styles from LV
                            s = ""
                            i = 0
                            DO
                               i = ListView_GetNextItem(hListView,i,%LVNI_SELECTED)
                               IF i = -1 THEN
                                   squeezeTB2Text(CBHNDL, %IDC_STYLES_TB, s)
                                   FUNCTION  = 0
                                   EXIT LOOP
                               END IF
                               Listview_GetItemText ( hListView, i, 0, sz, 1024)
                               IF s = "" THEN
                                   s = sz
                               ELSE
                                   s = s + ", " + sz
                               END IF
                            LOOP
                            gCcontrols(lCX).sStyles = s
                            '
                            CONTROL GET TEXT CBHNDL, %IDC_FONT_BN       TO gCcontrols(lCX).sFont
                            CONTROL GET TEXT CBHNDL, %IDC_FONTATTS_LAB  TO gCcontrols(lCX).sFontAtts
                            CONTROL GET TEXT CBHNDL, %IDC_FONTSIZE_LAB  TO s
                            gCcontrols(lCX).lFontSize = VAL(s)
                            gCcontrols(lCX).lFGColour = lFGColour
                            gCcontrols(lCX).lBGColour = lBGColour
                            gCcontrols(lCX).hFont     = hFont
    
                            ' update CC control
                            IF Lcx > 0 THEN
                                CONTROL SET TEXT ghCCDialog, %IDC_CCID, TRIM$(gCcontrols(lCX).sText)
                                ReFont (ghCCDialog, %IDC_CCID, hFont, sFont, lFontSize, lbold, lItalic, lUnderline, lFGCOlour, lBGColour)
                            ELSE
                                DIALOG SET TEXT hparent, TRIM$(gCcontrols(lCX).sText)
                                deleteObject hfont
                                hFont = SDMakeFont(sFont, lfontsize, lbold, litalic, lunderline)
                                DIALOG SEND hParent, %WM_SETFONT, hFont, 0 ' parent dialog is the main one, not Ccontrols dialog!
                                DIALOG SET COLOR hParent, lfgcolour, lbgcolour
                                DIALOG REDRAW hParent
                            END IF
                        END IF
                        DIALOG END CBHNDL, 0
    '
                  CASE %IDC_BGCOLOR_BN
                      IF (CBCTLMSG = %BN_CLICKED) THEN
                          s = SelColour(CBHNDL)
                          CONTROL SET TEXT CBHNDL, %IDC_BGCOLOR_BN, "background: #" + s
                          lbgcolour = VAL("&H" + s)
                          ReFont (CBHNDL, %IDC_TEXT_TB, hFont, sFont, lFontSize, lbold, lItalic, lUnderline, lFGCOlour, lBGColour)
                      END IF
    '
                  CASE %IDC_FONT_BN
                      IF (CBCTLMSG = %BN_CLICKED) THEN
                          pCFS     = ChooseQTPFont( CBHNDL)
                          IF pCFS = 0 THEN
                              FUNCTION = 1
                              EXIT FUNCTION
                          END IF
                          pLF      = @pCFS.lplogfont
    
                          sfont = @pLF.lfFaceName
                          CONTROL SET TEXT CBHNDL, %IDC_FONT_BN, sfont
                          lFGColour = @pCFS.rgbcolors
                          lfontsize = @pCFS.ipointsize/10
                          CONTROL SET TEXT CBHNDL, %IDC_FONTSIZE_LAB, STR$(lfontsize)
                          s = ""
                          lbold = 0: lItalic = 0: lUnderLine = 0
                          litalic = @pLF.lfItalic
                          IF litalic <> 0 THEN
                              s = s + ", italic"
                          END IF
                          lUnderline = @pLF.lfUnderline
                          IF lUnderline <> 0 THEN s = s + ", underline"
                          IF @pLF.lfWeight > 699  THEN
                              s = s + ", bold"
                              lbold = %TRUE
                          END IF
                          'just ignoring strikeout.
                          IF LEFT$(s,1) = "," THEN s = MID$(s,3)
                          CONTROL SET TEXT CBHNDL, %IDC_FONTATTS_LAB, s
                          ReFont (CBHNDL, %IDC_TEXT_TB, hFont, sFont, lFontSize, lbold, lItalic, lUnderline, lFGCOlour, lBGColour)
                      END IF
                END SELECT
        END SELECT
    END FUNCTION
    
    '--------------------------------------------------------------------------------------------
    FUNCTION ShowPROP(BYVAL hParent AS DWORD) AS LONG
        LOCAL lRslt AS LONG
        LOCAL hfont AS LONG
        LOCAL hDlg  AS DWORD
    
        hFONT = GetStockObject(%SYSTEM_FIXED_FONT)
    
    
        DIALOG NEW hParent, "Control Properties", 85, 0, 455, 260, %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR _
            %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_ACCEPTFILES _
            OR %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
        CONTROL ADD TEXTBOX, hDlg, %IDC_TEXT_TB,        "",                     60,   45, 160,  25,%ES_MULTILINE
        CONTROL ADD LABEL,   hDlg, %IDC_LABEL1,         "Dialog Id",            10,    5, 135,  10
        CONTROL ADD LABEL,   hDlg, %IDC_CTRL_NO_LAB,    "Control Number",       10,   15, 135,  10
        CONTROL ADD LABEL,   hDlg, %IDC_CTRL_TYPE_LAB,  "type of Control: ",    10,   25, 135,  10
        CONTROL ADD LABEL,   hDlg, %IDC_LABEL4,         "Text",                 10,   35,  50,  10
        CONTROL ADD LABEL,   hDlg, %IDC_LABEL3,         "Font",                 10,   70,  50,  10
        CONTROL ADD BUTTON,  hDlg, %IDC_FONT_BN,        "",                     60,   70, 106,  15
        CONTROL ADD LABEL,   hDlg, %IDC_LABEL21,        "Font size",            10,   85,  50,  10
        CONTROL ADD LABEL,   hDlg, %IDC_LABEL22,        "Font Attributes",      10,   95, 100,  10
        CONTROL ADD LABEL,   hDlg, %IDC_FONTSIZE_LAB,   "",                     60,   85,  20,  10,%ES_NUMBER
        CONTROL ADD LABEL,   hDlg, %IDC_FONTATTS_LAB,   "",                     60,   95, 160,  10
        CONTROL ADD BUTTON,  hDlg, %IDC_BGCOLOR_BN,     "Background",           60,  110,  80,  10
        CONTROL ADD LINE,    hDlg, %IDC_LINE1,          "Line1",                10,  150, 205,  70
        CONTROL ADD LINE,    hDlg, %IDC_LINE2,          "Line2",                50,  165, 155,  45
        CONTROL ADD LABEL,   hDlg, %IDC_X_LAB,          "X",                    10,  175,  25,  10
        CONTROL ADD LABEL,   hDlg, %IDC_Y_LAB,          "Y",                    50,  150,  25,  10
        CONTROL ADD LABEL,   hDlg, %IDC_W_LAB,          "W",                   110,  165,  25,  10
        CONTROL ADD LABEL,   hDlg, %IDC_H_LAB,          "H",                   185,  185,  25,  10
        CONTROL ADD BUTTON,   hDlg, %IDC_SAVE_BN,       "OK",                   10,  225,  30,  10
        CONTROL ADD BUTTON,   hDlg, %IDC_DEF_STYLES_BN, "DEFAULT STYLES",       55,  225,  80,  10
        CONTROL ADD BUTTON,   hDlg, %IDC_ORG_STYLES_BN, "UNDO STYLES CHANGES",  55,  240,  90,  10
        CONTROL ADD $WC_LISTVIEW, hDlg, %IDC_AV_STYLES_LV, "",                 223,   25, 225, 220, _
                                        %ws_child OR %WS_TABSTOP _
                                        OR %WS_VISIBLE OR %LVS_SHOWSELALWAYS OR %LVS_REPORT, %WS_EX_CLIENTEDGE _
                                        OR %LVS_EX_LABELTIP OR %LVS_EX_INFOTIP
    
        DIALOG SHOW MODAL hDlg, CALL ShowPROPProc TO lRslt
    
        FUNCTION = lRslt
    END FUNCTION
    '---------------------------------------------------------------------------------------------------
    ' get a list of styles & concoct the styles part of a DDT control or dialog specification from it
    ' seperating out regular and extended components
    FUNCTION CCGetStylesList ( LCX AS LONG) AS STRING
        LOCAL l AS LONG
        LOCAL s, ss, sx AS STRING
    
    '   derive regular styles list for control
        s = "" ' styles list
        sx = "" ' extended styles list
        FOR l = 1 TO PARSECOUNT(gCcontrols(lcx).sStyles)
            ss = PARSE$(gCcontrols(lcx).sStyles, l)
            IF ss <> "" THEN
                IF ASC(MID$(ss,1)) <> 0 THEN ' as the source is a fixed length string inside a UDT, empty str can be all nulls.
                    IF INSTR(ss, "_EX_") = 0 THEN
                        s = s + " OR %" + TRIM$(PARSE$( gCcontrols(lcx).sStyles, l))
                    ELSE
                        sx = sx + " OR %" + TRIM$(PARSE$( gCcontrols(lcx).sStyles, l))
                    END IF
                END IF
            END IF
        NEXT
        s = MID$(s,5) ' get rid of leading 'OR '
        sx = MID$(sx,5) ' get rid of leading 'OR '
    
        FUNCTION = s + "," + sx
    END FUNCTION
    '------------------------------------------------------------------------------
    '  return a string of coordinates for the control whose index in cControls is passed in the parameter
    FUNCTION CCgetCoords( lcx AS LONG) AS STRING
    
        FUNCTION = STR$(gCControls(lcx).X) + "," _
                  + STR$(gCControls(lcx).Y) + "," _
                  + STR$(gCControls(lcx).W) + "," _
                  + STR$(gCControls(lcx).H)
    
    END FUNCTION
    '-------------------------------------------------------------------------------------
    ' return the control id for the i'th CControl.
    FUNCTION  GetCtrlId ( i AS LONG ) AS STRING
        FUNCTION = "CONTROLIDERROR!!"
        SELECT CASE gCControls(i).lCtrlType
            CASE %our_label_type, %our_textbox_type, %our_checkbox_type,%our_listbox_type,%our_button_type
                FUNCTION = "%IDC_" + gsControlTypes(gCControls(i).lCtrlType) + TRIM$(STR$(1005 + i))
            CASE %our_listview_type
                FUNCTION = "%IDC_" + "LV" + TRIM$(STR$(1005 + i))
        END SELECT
    END FUNCTION
    '------------------------------------------------------------------------------
    SUB OutPutSampleListView ( hfile AS LONG)
        PRINT #hfile, "SUB SampleListView(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lColCnt AS LONG, BYVAL lRowCnt AS LONG)
        PRINT #hfile, "    LOCAL lCol   AS LONG
        PRINT #hfile, "    LOCAL lRow   AS LONG
        PRINT #hfile, "    LOCAL hCtl   AS DWORD
        PRINT #hfile, "    LOCAL tLVC   AS LV_COLUMN
        PRINT #hfile, "    LOCAL tLVI   AS LV_ITEM
        PRINT #hfile, "    LOCAL szBuf  AS ASCIIZ * 32
        PRINT #hfile, "    LOCAL lStyle AS LONG
    
        PRINT #hfile, "    CONTROL HANDLE hDlg, lID TO hCtl
    
        PRINT #hfile, "    lStyle = ListView_GetExtendedListViewStyle(hCtl)
        PRINT #hfile, "    ListView_SetExtendedListViewStyle hCtl, lStyle OR %LVS_EX_FULLROWSELECT OR %LVS_EX_GRIDLINES
    
        PRINT #hfile,"    ' Load column headers.
        PRINT #hfile,"    tLVC.mask    = %LVCF_FMT OR %LVCF_TEXT OR %LVCF_SUBITEM
        PRINT #hfile,"    tLVC.fmt     = %LVCFMT_LEFT
        PRINT #hfile,"    tLVC.pszText = VARPTR(szBuf)
        PRINT #hfile,"    FOR lCol = 0 TO lColCnt - 1
        PRINT #hfile,"        szBuf       = USING$(" + $DQ + "Column #" + $DQ + ", lCol)
        PRINT #hfile,"        tLVC.iOrder = lCol
        PRINT #hfile,"        ListView_InsertColumn hCtl, lCol, tLVC
        PRINT #hfile,"    NEXT lCol
        PRINT #hfile,"
        PRINT #hfile,"    ' Load sample data.
        PRINT #hfile,"    FOR lRow = 0 TO lRowCnt - 1
        PRINT #hfile,"        tLVI.stateMask = %LVIS_FOCUSED
        PRINT #hfile,"        tLVI.pszText   = VARPTR(szBuf)
        PRINT #hfile,"        tLVI.iItem     = lRow
        PRINT #hfile,"        FOR lCol = 0 TO lColCnt - 1
        PRINT #hfile,"            szBuf         = USING$(" + $DQ + "Column # Row #" + $DQ + ", lCol, lRow)
        PRINT #hfile,"            tLVI.iSubItem = lCol
        PRINT #hfile,"            tLVI.lParam   = lRow
        PRINT #hfile,"            IF lCol = 0 THEN
        PRINT #hfile,"                tLVI.mask = %LVIF_TEXT OR %LVIF_PARAM OR %LVIF_STATE
        PRINT #hfile,"                ListView_InsertItem hCtl, tLVI
        PRINT #hfile,"            ELSE
        PRINT #hfile,"                tLVI.mask = %LVIF_TEXT
        PRINT #hfile,"                ListView_SetItem hCtl, tLVI
        PRINT #hfile,"            END IF
        PRINT #hfile,"        NEXT lCol
        PRINT #hfile,"    NEXT lRow
        PRINT #hfile,"
        PRINT #hfile,"    ' Auto size columns.
        PRINT #hfile,"    FOR lCol = 0 TO lColCnt - 2
        PRINT #hfile,"        ListView_SetColumnWidth hCtl, lCol, %LVSCW_AUTOSIZE
        PRINT #hfile,"    NEXT lCol
        PRINT #hfile,"    ListView_SetColumnWidth hCtl, lColCnt - 1, %LVSCW_AUTOSIZE_USEHEADER
        PRINT #hfile,"END SUB
    END SUB
    '------------------------------------------------------------------------------
    SUB ExportPBSource (hD AS DWORD)
        STATIC spath AS STRING
        LOCAL buf AS STRING
        LOCAL dwstyle AS DWORD
        LOCAL hfile, lcx, i, l, x, y, w, h AS LONG
        LOCAL s, sx, sfont, sdeclarefonts, sdeletefonts, smakefonts AS STRING
        LOCAL lbold, litalic, lunderline AS LONG
    
        '------------------------ get filename
        dwStyle = %OFN_EXPLORER OR %OFN_FILEMUSTEXIST OR %OFN_HIDEREADONLY
        Buf   = "unknown.bas"
    '    spath = gddlpath
        IF SaveFileDialog(hD, "Save as:", g_app_name, sPath, "*.bas", "bas", _
               %OFN_HIDEREADONLY OR %OFN_OVERWRITEPROMPT) = 0 THEN
           EXIT SUB
        END IF
        CHDIR spath
        hfile = FREEFILE
        OPEN g_app_name FOR OUTPUT AS hfile
    '        write header up to not inc ~PBFORMS END CONSTANTS
        PRINT #hfile, "#PBFORMS CREATED V1.51
        PRINT #hfile, "#COMPILE EXE
        PRINT #hfile, "#DIM ALL
        PRINT #hfile, ""
        PRINT #hfile, "#PBFORMS BEGIN INCLUDES
    '    PRINT #hfile, "%USEMACROS = 1
        PRINT #hfile, "#IF NOT %DEF(%WINAPI)
        PRINT #hfile, "    #INCLUDE ""WIN32API.INC""
        PRINT #hfile, "#ENDIF
        PRINT #hfile, "#INCLUDE ""PBForms.INC""
        PRINT #hfile, "#PBFORMS END INCLUDES
        PRINT #hfile, ""
        PRINT #hfile, "#IF NOT %DEF(%COMMCTRL_INC)
        PRINT #hfile, "    #INCLUDE ""COMMCTRL.INC""
        PRINT #hfile, "#ENDIF
    '    PRINT #hfile, "#INCLUDE ""comdlg32.inc""
        PRINT #hfile, ""
        PRINT #hfile, "#PBFORMS BEGIN CONSTANTS
        PRINT #hfile, "%IDD_DIALOG1         = 101
    '        write constants
        FOR lcx = 1 TO gCCX
            IF gCControls(lcx).lCtrlType = %our_listview_type THEN
                s = "%IDC_LV" + TRIM$(STR$(1005 + lcx)) + " = " + STR$(1005 + lcx)
            ELSE
                s = "%IDC_" + gsControlTypes(gCControls(lcx).lCtrlType) + TRIM$(STR$(1005 + lcx)) + " = " + STR$(1005 + lcx)
            END IF
            PRINT #hfile, s
        NEXT
    '        write body down to but not incl ~PBFORMS END DIALOG
        PRINT #hfile, "#PBFORMS END CONSTANTS
        PRINT #hfile, ""
        PRINT #hfile, "'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        PRINT #hfile, "$DEFAULT_LV_FONTNAME = ""courier new""
        PRINT #hfile, "%DEFAULT_LV_FONTSIZE = 10
        PRINT #hfile, "%DEFAULT_LV_FONTITALICS = 0
        PRINT #hfile, "%DEFAULT_LV_FONTBOLD = 0
        PRINT #hfile, "%DEFAULT_LV_FONTUNDERLINE = 0
        PRINT #hfile, "$Q = CHR$(34)
        PRINT #hfile, "'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        PRINT #hfile, "'
        PRINT #hfile, "GLOBAL scols AS STRING
        PRINT #hfile, "GLOBAL hlv AS LONG ' listbox handle
        PRINT #hfile, "DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
        PRINT #hfile, "DECLARE sub SampleListView(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL _
        PRINT #hfile, "    lColCnt AS LONG, BYVAL lRowCnt AS LONG)
        PRINT #hfile, "DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
        PRINT #hfile, ""
        PRINT #hfile, "#PBFORMS DECLARATIONS
        PRINT #hfile, "FUNCTION PBMAIN()
    
    
        PRINT #hfile, "    'DIM SCOLS(%MAX_COLUMNS_PER_TABLE) AS GLOBAL STRING
    
        PRINT #hfile, "    PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR _
        PRINT #hfile, "        %ICC_INTERNET_CLASSES)
    
        PRINT #hfile, "    ShowDIALOG1 %HWND_DESKTOP
        PRINT #hfile, "END FUNCTION
        OutputSampleListView(hfile)
        PRINT #hfile, "FUNCTION AFontMake(BYVAL sFontName AS STRING, BYVAL nPointSize AS LONG, BYVAL bIsBold AS LONG, BYVAL bIsItalic AS LONG, BYVAL bIsUnderline AS LONG ) AS LONG
        PRINT #hfile, "    LOCAL hDC AS LONG, CyPixels AS LONG
    
        PRINT #hfile, "    hDC = GetDC(%HWND_DESKTOP)
        PRINT #hfile, "    CyPixels  = GetDeviceCaps(hDC, %LOGPIXELSY)
        PRINT #hfile, "    ReleaseDC %HWND_DESKTOP, hDC
        PRINT #hfile, "    nPointSize = (nPointSize * CyPixels) \ 72
    
        PRINT #hfile, "    FUNCTION = CreateFont(0 - nPointSize, 0, 0, 0, IIF&(bIsBold, %FW_BOLD, %FW_NORMAL), bIsItalic, bIsUnderline, 0, _
        PRINT #hfile, "               %ANSI_CHARSET, %OUT_TT_PRECIS, %CLIP_DEFAULT_PRECIS, _
        PRINT #hfile, "               %DEFAULT_QUALITY, %FF_DONTCARE, BYCOPY sFontName)
        PRINT #hfile, "END FUNCTION
        PRINT #hfile, "' ------------------------------------------------
        PRINT #hfile, "CALLBACK FUNCTION ShowDIALOG1Proc()
        PRINT #hfile, "    STATIC rowrect AS RECT
        PRINT #hfile, "    STATIC hLV, lstyle AS LONG
        PRINT #hfile, "    LOCAL pnmh AS NMHDR PTR
        PRINT #hfile, "    LOCAL pnm AS NMLVCUSTOMDRAW PTR
        PRINT #hfile, "    LOCAL lpLVDispInfo AS LV_DISPINFO PTR
        PRINT #hfile, "    LOCAL szString AS ASCIIZ * 256
        PRINT #hfile, "    SELECT CASE AS LONG CBMSG
        PRINT #hfile, "        CASE %WM_INITDIALOG
        PRINT #hfile, "            ' Initialization handler
        PRINT #hfile, "        CASE %WM_NCACTIVATE
        PRINT #hfile, "            STATIC hWndSaveFocus AS DWORD
        PRINT #hfile, "            IF ISFALSE CBWPARAM THEN
        PRINT #hfile, "                ' Save control focus
        PRINT #hfile, "                hWndSaveFocus = GetFocus()
        PRINT #hfile, "            ELSEIF hWndSaveFocus THEN
        PRINT #hfile, "                ' Restore control focus
        PRINT #hfile, "                SetFocus(hWndSaveFocus)
        PRINT #hfile, "                hWndSaveFocus = 0
        PRINT #hfile, "            END IF
        PRINT #hfile, "        CASE %WM_COMMAND
        PRINT #hfile, "            SELECT CASE AS LONG CBCTL
        ' insert button catchers here
        FOR lcx = 1 TO gCCX
            IF gCcontrols(lcx).lCtrlType = %our_button_type THEN
                PRINT #hfile, "                case %IDC_" + gsControlTypes(gCControls(lcx).lCtrlType) + TRIM$(STR$(1005 + lcx))
                PRINT #hfile, "                    IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                PRINT #hfile, "                        ? " + $DQ + "it's %IDC_" + gsControlTypes(gCControls(lcx).lCtrlType) + TRIM$(STR$(1005 + lcx)) + $DQ
                PRINT #hfile, "                    end if
            END IF
        NEXT
    
        PRINT #hfile, "            END SELECT
        PRINT #hfile, "    END SELECT
        PRINT #hfile, "END FUNCTION
        PRINT #hfile, "FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
        PRINT #hfile, "    LOCAL lRslt AS LONG
        PRINT #hfile, ""
        PRINT #hfile, "#PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
        PRINT #hfile, "    LOCAL hDlg  AS DWORD
        PRINT #hfile, ""
        ' font stuff
        ' make up a block of code for declaring font handles, deleting fonts, and making fonts/send to controls
            FOR lcx = 1 TO gCCX
            sfont = gCControls(lcx).sFont
            IF (sfont <> "") AND (LEFT$(sfont,1) = CHR$(0)) THEN sfont = "" ' in case sfont is an uninitialised string of nulls
            IF (TRIM$(gCControls(lcx).sFont) <> "") OR (TRIM$(gCControls(lcx).sFontAtts) <> "") OR (gCControls(lcx).lFontsize <> 0) THEN
                sDeclareFonts = sDeclareFonts + "    local hfont" + TRIM$(STR$(lcx)) + " as long" + $CRLF
                sdeletefonts  = sdeletefonts  + "Deleteobject " + "hfont" + TRIM$(STR$(lcx)) + $CRLF
                s = TRIM$(gCcontrols(lCX).sFontAtts)
                lunderline= %FALSE: litalic = %FALSE: lbold = %FALSE
                IF INSTR(s, "bold")      THEN lbold = %TRUE
                IF INSTR(s, "italic")    THEN litalic = %TRUE
                IF INSTR(s, "underline") THEN lunderline = %TRUE
                smakefonts    = smakefonts    + "    hfont" + TRIM$(STR$(lcx))              _
                                              + " = Afontmake (" + $DQ + TRIM$(gCControls(lcx).sFont) + $DQ + "," _
                                              + STR$(gCControls(lcx).lFontSize)    + "," _
                                              + STR$(lbold)                        + "," _
                                              + STR$(litalic)                      + "," _
                                              + STR$(lunderline)                   + ")" _
                                              + $CRLF                                    _
                                              + "    CONTROL SEND hdlg, " + getCtrlId(lcx) _
                                              + ", %WM_SETFONT, hfont" + TRIM$(STR$(lcx)) + ", 0" + $CRLF
            END IF
        NEXT
        ' declare LONGs for font handles
        PRINT #hfile, sdeclarefonts
        ' get coordinates of dialog
        DIALOG GET LOC ghMainDD TO x, y
        DIALOG GET SIZE ghmainDD TO w, h
        s = STR$(x) + "," + STR$(y) + "," + STR$(w) + "," + STR$(h) + ","
        PRINT #hfile, "    DIALOG NEW hParent" + "," + $DQ + TRIM$(gCControls(0).sText) + $DQ + "," + s;
        PRINT #hfile, "    " + CCGetStylesList(0) + ", to hdlg "
    
    '        write CONTROL ADD statements for each Ccontrol
       FOR lcx = 1 TO gCCX
           SELECT CASE gCControls(lcx).lCtrlType
               CASE  %our_label_type, %our_textbox_type, %our_checkbox_type, %our_button_type
                   PRINT #hfile, "    CONTROL ADD " + gsControlTypes(gCControls(lcx).lCtrlType)+",hDlg,";
                   PRINT #hfile, "%IDC_" + gsControlTypes(gCControls(lcx).lCtrlType) + TRIM$(STR$(1005 + lcx)) + ",";
                   PRINT #hfile, $DQ + TRIM$(gCControls(lcx).sText) + $DQ+ ",";
                   PRINT #hfile, CCgetCoords(lcx) + "," + CCgetStylesList(lcx)
                   PRINT #hfile, "    control set color hdlg,%IDC_" + gsControlTypes(gCControls(lcx).lCtrlType) + TRIM$(STR$(1005 + lcx)) + ",";
                   PRINT # hfile, STR$(gCControls(lcx).lFGcolour) + "," + STR$(gCControls(lcx).lBGcolour)
               CASE %our_listbox_type
                   PRINT #hfile, "    CONTROL ADD LISTBOX,hDlg,";
                   PRINT #hfile, "%IDC_" + gsControlTypes(gCControls(lcx).lCtrlType) + TRIM$(STR$(1005 + lcx)) + ",,";
                   PRINT #hfile, CCgetCoords(lcx) + "," + CCgetStylesList(lcx)
               CASE %our_listview_type
                   PRINT #hfile, "    CONTROL ADD $WC_LISTVIEW, hDlg,";
                   PRINT #hfile, "%IDC_LV" + TRIM$(STR$(1005 + lcx)) + ",";
                   PRINT #hfile, $DQ + $DQ + "," + CCgetCoords(lcx) + "," + CCgetStylesList(lcx)
                   PRINT #hfile, "    SampleListView ( hDlg, %IDC_LV" + TRIM$(STR$(1005 + lcx)) + ", 10, 10)"
            END SELECT
        NEXT
    '   make fonts & send to controls
        PRINT #hfile, smakefonts
    '   write remainder of file
        PRINT #hfile, "#PBFORMS END DIALOG
        PRINT #hfile, ""
        PRINT #hfile, "    DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
        PRINT #hfile, ""
        PRINT #hfile, "#PBFORMS BEGIN CLEANUP %IDD_DIALOG1
        PRINT #hfile, ""
        PRINT #hfile, sdeletefonts
        PRINT #hfile, "#PBFORMS END CLEANUP
        PRINT #hfile, ""
        PRINT #hfile, "    FUNCTION = lRslt
        PRINT #hfile, "END FUNCTION
    
        CLOSE hfile
    END SUB
    '------------------------------------------------------------------------------
    SUB SaveCCs ( hD AS DWORD, sfile AS STRING)
        LOCAL hfile, l AS LONG
        LOCAL dwstyle AS DWORD
        LOCAL spath AS STRING
        GLOBAL gCcontrols() AS CPH
    
        ' store grid dimensions to 0'th element of array
        gCcontrols(0).lGridX = gGridSizeX
        gCcontrols(0).lGridY = gGridSizeY
        gCcontrols(0).ncontrols = gCCX
    
        IF sfile <> "" THEN
            g_app_name = sfile
        END IF
    
        '------------------------ get filename
        dwStyle = %OFN_EXPLORER OR %OFN_FILEMUSTEXIST OR %OFN_HIDEREADONLY
    '    Buf   = "unknown.ftf"
        IF SaveFileDialog(hD, "Save as:", g_app_name, sPath, "*.ftf", "ftf", _
               %OFN_HIDEREADONLY OR %OFN_OVERWRITEPROMPT) = 0 THEN
           EXIT SUB
        END IF
    
        CHDIR spath
        TRY
            KILL g_app_name
        CATCH
        END TRY
        ' save dialog coordinates
        DIALOG GET LOC ghMainDD TO gCcontrols(0).x, gCcontrols(0).y
        DIALOG GET SIZE ghmainDD TO gCcontrols(0).w, gCcontrols(0).h
    
        hfile = FREEFILE
    
        OPEN g_APP_NAME FOR BINARY AS #hfile
        PUT #hfile, 1, gCcontrols()
        CLOSE #hfile
        g_app_name = ""
    END SUB
    '----------------------------------------------------------------------
    ' load a control to the main dialog window from the gCcontrol array
    ' NB control number zero is the main dialog itself, so this sub doesn't expect it!
    SUB LoadControl ( lcx AS LONG )
    
        LOCAL s, sfont AS STRING
        LOCAL sTXT AS STRING
        LOCAL hD AS DWORD
    
        LOCAL lbold, leventcount, litalic, lunderline AS LONG
    
        IF gCcontrols(lcx).hD = 0 THEN EXIT SUB ' that control has been deleted before save
        
        DIALOG NEW ghMainDD, "", gCcontrols(lcx).X, gCcontrols(lcx).Y, gCcontrols(lcx).W, gCcontrols(lcx).H, _
            %WS_POPUP OR %WS_THICKFRAME OR %WS_CHILD OR _
            %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
            %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_TOOLWINDOW OR _
            %WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING TO hD
    
    
        SELECT CASE gCcontrols(lcx).lCtrlType
            CASE %our_button_type
                  CONTROL ADD BUTTON, hD, %IDC_CCID, "", 0,0,0,0,%BS_FLAT
    
            CASE %our_checkbox_type
                  CONTROL ADD CHECKBOX, hD, %IDC_CCID, "", 0,0,0,0
    
            CASE %our_label_type
                  CONTROL ADD LABEL, hD, %IDC_CCID, "", 0,0,0,0
    
            CASE %our_textbox_type
                  CONTROL ADD TEXTBOX, hD, %IDC_CCID, "", 0,0,0,0
    
            CASE %our_listbox_type
                  CONTROL ADD LISTBOX, hD, %IDC_CCID, , 0,0,0,0
                  DummyListBox ( hD, %IDC_CCID, 10)
    
            CASE %our_listview_type
                  CONTROL ADD "SysListView32", hD, %IDC_CCID, "", 0,0,0,0, _
                              %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %LVS_REPORT OR _
                              %LVS_SHOWSELALWAYS, %WS_EX_LEFT OR %WS_EX_CLIENTEDGE OR _
                              %WS_EX_RIGHTSCROLLBAR
                  SampleListView ( hD, %IDC_CCID, 10, 10)
    
        END SELECT
        sfont = gCControls(lcx).sFont
        IF (sfont <> "") AND (LEFT$(sfont,1) = CHR$(0)) THEN sfont = "" ' in case sfont is an uninitialised string of nulls
        IF (TRIM$(gCControls(lcx).sFont) <> "") OR (TRIM$(gCControls(lcx).sFontAtts) <> "") OR (gCControls(lcx).lFontsize <> 0) THEN
            s = TRIM$(gCcontrols(lCX).sFontAtts)
            lunderline= %FALSE: litalic = %FALSE: lbold = %FALSE
            IF INSTR(s, "bold")      THEN lbold = %TRUE
            IF INSTR(s, "italic")    THEN litalic = %TRUE
            IF INSTR(s, "underline") THEN lunderline = %TRUE
            gCcontrols(lcx).hfont = SDMakeFont (TRIM$(gCControls(lcx).sFont),gCControls(lcx).lFontSize, _
                                              lbold, litalic, lunderline)
            CONTROL SEND hD, %IDC_CCID, %WM_SETFONT, gCcontrols(lcx).hfont, 0
        END IF
        CONTROL SET COLOR hD, %IDC_CCID, gCcontrols(lcx).lFGColour, gCcontrols(lcx).lBGColour
        CONTROL SET TEXT hD, %IDC_CCID, TRIM$(gCcontrols(lcx).sText)
        CONTROL SET LOC hD, %IDC_CCID, 0, 0
        gCcontrols(lcx).hD = hD        ' replace the dialog handle used on the previous session with the current one
        DIALOG SHOW MODELESS hD, CALL CC_dialogProc 'TO lRslt
    END SUB
    
    '------------------------------------------------------------------------------
    SUB LoadCCs (hd AS DWORD)
        LOCAL i, hfile, l, x, y AS LONG
        LOCAL dwstyle AS DWORD
        LOCAL buf AS STRING
        LOCAL spath AS STRING
        GLOBAL gCcontrols() AS CPH
    
    
        dwStyle = %OFN_EXPLORER OR %OFN_FILEMUSTEXIST OR %OFN_HIDEREADONLY
        buf   = "FTF files (*.FTF)|*.FTF|"
        IF OpenFileDialog (hD, "Locate FTF file ", g_APP_NAME, spath, buf, "FTF", dwstyle) = 0 THEN
           EXIT SUB
        END IF
    
        ' delete any ccontrols as they will otherwise be orphaned
        FOR i = 1 TO gCCX
             IF gCcontrols(i).hFont <> 0 THEN
                  deleteobject gCcontrols(i).hFont
                  gCcontrols(i).hFont = 0
             END IF
             DIALOG SEND gCcontrols(i).hD, %WM_SYSCOMMAND, %SC_CLOSE, 0
    '         DIALOG END gCcontrols(i).hD, 0
             gCcontrols(i).hD = 0
        NEXT i
        '
        hfile = FREEFILE
        OPEN g_APP_NAME FOR BINARY AS #hfile
        GET #hfile, 1, gCcontrols() TO l
        CLOSE #hfile
        g_app_name = ""
        gCCX = gCcontrols(0).ncontrols
        x = gCcontrols(0).X
        y = gCcontrols(0).Y
        ' adjust main dialog
        DIALOG SET LOC hD,  gCcontrols(0).X, gCcontrols(0).Y
        DIALOG SET SIZE hD, gCcontrols(0).W, gCcontrols(0).H
        DIALOG SET TEXT hd, TRIM$(gCcontrols(0).sText)
        
        gGridSizeX = gCcontrols(0).lGridX
        gGridSizeY = gCcontrols(0).lGridY
        CONTROL SET TEXT ghMenuDialog, %IDC_GridX_tb, TRIM$(STR$( gGridSizeX))
        CONTROL SET TEXT ghMenuDialog, %IDC_GridY_tb, TRIM$(STR$( gGridSizeY))
        FOR i = 1 TO l
            ' draw controls from array
            LoadControl(i)
        NEXT
    END SUB
    '------------------------------------------------------------------------------
    Last edited by Chris Holbrook; 31 Dec 2007, 04:14 AM. Reason: SelColour function revised

    #2
    STYLES.TXT file

    Code:
    0,WS_POPUP,&H80000000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_OVERLAPPED,&H0,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_CHILD,&H40000000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_BORDER,&H00800000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_DLGFRAME,&H00400000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_THICKFRAME,&H00040000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_CAPTION,&H00C00000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_SYSMENU,&H00080000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_MINIMIZEBOX,&H00020000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_MAXIMIZEBOX,&H00010000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_CLIPSIBLINGS,&H04000000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_CLIPCHILDREN,&H02000000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_HSCROLL,&H00100000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_VSCROLL,STYLE %WS_VSCROLL NOT FOUND IN RULES TABLE,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_DISABLED,&H08000000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,DS_ABSALIGN,&H0001,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,DS_SYSMODAL,&H0002,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,DS_MODALFRAME,&H0080,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,DS_SETFOREGROUND,&H0200,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,DS_CONTROL,&H0400,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,DS_CENTER,&H0800,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,DS_CENTERMOUSE,&H1000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,DS_CONTEXTHELP,&H2000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,DS_3DLOOK,&H0004,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,DS_NOFAILCREATE,&H0010,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,DS_SETFONT,&H0040,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_CLIENTEDGE,&H00000200,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_STATICEDGE,&H00020000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_WINDOWEDGE,&H00000100,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_TRANSPARENT,&H00000020,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_ACCEPTFILES,&H00000010,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_CONTROLPARENT,&H00010000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_CONTEXTHELP,&H00000400,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_NOPARENTNOTIFY,&H00000004,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_TOOLWINDOW,&H00000080,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_TOPMOST,&H00000008,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_APPWINDOW,&H00040000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_MDICHILD,&H00000040,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_LEFT,&H00000000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_RIGHT,&H00001000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_LTRREADING,&H00000000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_RTLREADING,&H00002000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_RIGHTSCROLLBAR,&H00000000,help for the parent dialog has not yet been added to the STYLES.TXT file
    0,WS_EX_LEFTSCROLLBAR,&H00004000,help for the parent dialog has not yet been added to the STYLES.TXT file
    6,CONTROLNAME,STYLE %CONTROLNAME NOT FOUND IN RULES TABLE,99no help here mate
    6,WS_CHILD,&H40000000,99no help here mate
    6,WS_VISIBLE,STYLE %WS_VISIBLE NOT FOUND IN RULES TABLE,99no help here mate
    6,WS_DISABLED,&H08000000,99no help here mate
    6,WS_GROUP,&H00020000,99no help here mate
    6,WS_BORDER,&H00800000,99no help here mate
    6,WS_TABSTOP,&H00010000,99no help here mate
    6,BS_TEXT,&H0,99no help here mate
    6,BS_AUTOCHECKBOX,&H3,99no help here mate
    6,BS_PUSHLIKE,&H00001000,99no help here mate
    6,BS_MULTILINE,&H00002000,99no help here mate
    6,BS_DEFPUSHBUTTON,&H1,99no help here mate
    6,BS_PUSHBUTTON,&H0,99no help here mate
    6,BS_AUTO3STATE,&H6,99no help here mate
    6,BS_AUTORADIOBUTTON,&H9,99no help here mate
    6,BS_OWNERDRAW,&HB,99no help here mate
    6,BS_NOTIFY,&H00004000,99no help here mate
    6,BS_FLAT,&H00008000,99no help here mate
    6,BS_LEFT,&H100,99no help here mate
    6,BS_CENTER,&H300,99no help here mate
    6,BS_RIGHT,&H200,99no help here mate
    6,BS_TOP,&H400,99no help here mate
    6,BS_VCENTER,&HC00,99no help here mate
    6,BS_BOTTOM,&H800,99no help here mate
    6,WS_EX_CLIENTEDGE,&H00000200,99no help here mate
    6,WS_EX_STATICEDGE,&H00020000,99no help here mate
    6,WS_EX_DLGMODALFRAME,&H00000001,99no help here mate
    6,WS_EX_TRANSPARENT,&H00000020,99no help here mate
    6,WS_EX_ACCEPTFILES,&H00000010,99no help here mate
    6,WS_EX_LEFT,&H00000000,99no help here mate
    6,WS_EX_RIGHT,&H00001000,99no help here mate
    6,WS_EX_LTRREADING,&H00000000,99no help here mate
    6,WS_EX_RTLREADING,&H00002000,99no help here mate
    3,WS_CHILD,&H40000000,help for 3,WS_CHILD: for more help, edit the STYLES.TXT file!
    3,WS_VISIBLE,STYLE %WS_VISIBLE NOT FOUND IN RULES TABLE,help for 3,WS_VISIBLE: for more help, edit the STYLES.TXT file!
    3,WS_DISABLED,&H08000000,help for 3,WS_DISABLED: for more help, edit the STYLES.TXT file!
    3,WS_GROUP,&H00020000,help for 3,WS_GROUP: for more help, edit the STYLES.TXT file!
    3,WS_BORDER,&H00800000,help for 3,WS_BORDER: for more help, edit the STYLES.TXT file!
    3,WS_TABSTOP,&H00010000,help for 3,WS_TABSTOP: for more help, edit the STYLES.TXT file!
    3,BS_TEXT,&H0,help for 3,BS_TEXT: for more help, edit the STYLES.TXT file!
    3,BS_ICON,&H40,help for 3,BS_ICON: for more help, edit the STYLES.TXT file!
    3,BS_BITMAP,&H80,help for 3,BS_BITMAP: for more help, edit the STYLES.TXT file!
    3,BS_AUTOCHECKBOX,&H3,help for 3,BS_AUTOCHECKBOX: for more help, edit the STYLES.TXT file!
    3,BS_LEFTTEXT,&H20,help for 3,BS_LEFTTEXT: for more help, edit the STYLES.TXT file!
    3,BS_PUSHLIKE,&H00001000,help for 3,BS_PUSHLIKE: for more help, edit the STYLES.TXT file!
    3,BS_MULTILINE,&H00002000,help for 3,BS_MULTILINE: for more help, edit the STYLES.TXT file!
    3,BS_NOTIFY,&H00004000,help for 3,BS_NOTIFY: for more help, edit the STYLES.TXT file!
    3,BS_FLAT,&H00008000,help for 3,BS_FLAT: for more help, edit the STYLES.TXT file!
    3,BS_LEFT,&H100,help for 3,BS_LEFT: for more help, edit the STYLES.TXT file!
    3,BS_CENTER,&H300,help for 3,BS_CENTER: for more help, edit the STYLES.TXT file!
    3,BS_RIGHT,&H200,help for 3,BS_RIGHT: for more help, edit the STYLES.TXT file!
    3,BS_TOP,&H400,help for 3,BS_TOP: for more help, edit the STYLES.TXT file!
    3,BS_VCENTER,&HC00,help for 3,BS_VCENTER: for more help, edit the STYLES.TXT file!
    3,BS_BOTTOM,&H800,help for 3,BS_BOTTOM: for more help, edit the STYLES.TXT file!
    3,WS_EX_CLIENTEDGE,&H00000200,help for 3,WS_EX_CLIENTEDGE: for more help, edit the STYLES.TXT file!
    3,WS_EX_STATICEDGE,&H00020000,help for 3,WS_EX_STATICEDGE: for more help, edit the STYLES.TXT file!
    3,WS_EX_DLGMODALFRAME,&H00000001,help for 3,WS_EX_DLGMODALFRAME: for more help, edit the STYLES.TXT file!
    3,WS_EX_TRANSPARENT,&H00000020,help for 3,WS_EX_TRANSPARENT: for more help, edit the STYLES.TXT file!
    3,WS_EX_ACCEPTFILES,&H00000010,help for 3,WS_EX_ACCEPTFILES: for more help, edit the STYLES.TXT file!
    3,WS_EX_LEFT,&H00000000,help for 3,WS_EX_LEFT: for more help, edit the STYLES.TXT file!
    3,WS_EX_RIGHT,&H00001000,help for 3,WS_EX_RIGHT: for more help, edit the STYLES.TXT file!
    3,WS_EX_LTRREADING,&H00000000,help for 3,WS_EX_LTRREADING: for more help, edit the STYLES.TXT file!
    3,WS_EX_RTLREADING,&H00002000,help for 3,WS_EX_RTLREADING: for more help, edit the STYLES.TXT file!
    1,WS_GROUP,&H00020000,no help here, edit the STYLES.TXT file!
    1,WS_BORDER,&H00800000,no help here, edit the STYLES.TXT file!
    1,WS_TABSTOP,&H00010000,no help here, edit the STYLES.TXT file!
    1,SS_LEFT,&H00000000,no help here, edit the STYLES.TXT file!
    1,SS_CENTER,&H00000001,no help here, edit the STYLES.TXT file!
    1,SS_CENTERIMAGE,&H00000200,no help here, edit the STYLES.TXT file!
    1,SS_NOPREFIX,&H00000080,no help here, edit the STYLES.TXT file!
    1,SS_NOWORDWRAP,%SS_LEFTNOWORDWRAP,no help here, edit the STYLES.TXT file!
    1,SS_SIMPLE,&H0000000B,no help here, edit the STYLES.TXT file!
    1,SS_NOTIFY,&H00000100,no help here, edit the STYLES.TXT file!
    1,SS_SUNKEN,&H00001000,no help here, edit the STYLES.TXT file!
    1,WS_EX_CLIENTEDGE,&H00000200,no help here, edit the STYLES.TXT file!
    1,WS_EX_STATICEDGE,&H00020000,no help here, edit the STYLES.TXT file!
    1,WS_EX_DLGMODALFRAME,&H00000001,no help here, edit the STYLES.TXT file!
    1,WS_EX_TRANSPARENT,&H00000020,no help here, edit the STYLES.TXT file!
    1,WS_EX_ACCEPTFILES,&H00000010,no help here, edit the STYLES.TXT file!
    1,WS_EX_LEFT,&H00000000,no help here, edit the STYLES.TXT file!
    1,WS_EX_RIGHT,&H00001000,no help here, edit the STYLES.TXT file!
    1,WS_EX_LTRREADING,&H00000000,no help here, edit the STYLES.TXT file!
    1,WS_EX_RTLREADING,&H00002000,no help here, edit the STYLES.TXT file!
    4,CONTROLNAME,STYLE %CONTROLNAME NOT FOUND IN RULES TABLE,this is the help for 4,CONTROLNAME. For more help, edit STYLES.TXT!
    4,WS_CHILD,&H40000000,this is the help for 4,WS_CHILD. For more help, edit STYLES.TXT!
    4,WS_VISIBLE,STYLE %WS_VISIBLE NOT FOUND IN RULES TABLE,this is the help for 4,WS_VISIBLE. For more help, edit STYLES.TXT!
    4,WS_DISABLED,&H08000000,this is the help for 4,WS_DISABLED. For more help, edit STYLES.TXT!
    4,WS_GROUP,&H00020000,this is the help for 4,WS_GROUP. For more help, edit STYLES.TXT!
    4,WS_BORDER,&H00800000,this is the help for 4,WS_BORDER. For more help, edit STYLES.TXT!
    4,WS_TABSTOP,&H00010000,this is the help for 4,WS_TABSTOP. For more help, edit STYLES.TXT!
    4,LBS_MULTIPLESEL,&H8,this is the help for 4,LBS_MULTIPLESEL. For more help, edit STYLES.TXT!
    4,LBS_EXTENDEDSEL,&H800,this is the help for 4,LBS_EXTENDEDSEL. For more help, edit STYLES.TXT!
    4,LBS_NOSEL,&H00004000,this is the help for 4,LBS_NOSEL. For more help, edit STYLES.TXT!
    4,LBS_STANDARD,%LBS_NOTIFY OR %LBS_SORT OR %WS_VSCROLL OR %WS_BOR,this is the help for 4,LBS_STANDARD. For more help, edit STYLES.TXT!
    4,LBS_SORT,&H2,this is the help for 4,LBS_SORT. For more help, edit STYLES.TXT!
    4,LBS_NOTIFY,&H1,this is the help for 4,LBS_NOTIFY. For more help, edit STYLES.TXT!
    4,LBS_OWNERDRAWFIXED,&H10,this is the help for 4,LBS_OWNERDRAWFIXED. For more help, edit STYLES.TXT!
    4,LBS_OWNERDRAWVARIABLE,&H20,this is the help for 4,LBS_OWNERDRAWVARIABLE. For more help, edit STYLES.TXT!
    4,LBS_HASSTRINGS,&H40,this is the help for 4,LBS_HASSTRINGS. For more help, edit STYLES.TXT!
    4,LBS_NODATA,&H00002000,this is the help for 4,LBS_NODATA. For more help, edit STYLES.TXT!
    4,LBS_NOREDRAW,&H4,this is the help for 4,LBS_NOREDRAW. For more help, edit STYLES.TXT!
    4,LBS_USETABSTOPS,&H80,this is the help for 4,LBS_USETABSTOPS. For more help, edit STYLES.TXT!
    4,LBS_NOINTEGRALHEIGHT,&H100,this is the help for 4,LBS_NOINTEGRALHEIGHT. For more help, edit STYLES.TXT!
    4,LBS_MULTICOLUMN,&H200,this is the help for 4,LBS_MULTICOLUMN. For more help, edit STYLES.TXT!
    4,LBS_WANTKEYBOARDINPUT,&H400,this is the help for 4,LBS_WANTKEYBOARDINPUT. For more help, edit STYLES.TXT!
    4,LBS_DISABLENOSCROLL,&H00001000,this is the help for 4,LBS_DISABLENOSCROLL. For more help, edit STYLES.TXT!
    4,WS_EX_CLIENTEDGE,&H00000200,this is the help for 4,WS_EX_CLIENTEDGE. For more help, edit STYLES.TXT!
    4,WS_EX_STATICEDGE,&H00020000,this is the help for 4,WS_EX_STATICEDGE. For more help, edit STYLES.TXT!
    4,WS_EX_DLGMODALFRAME,&H00000001,this is the help for 4,WS_EX_DLGMODALFRAME. For more help, edit STYLES.TXT!
    4,WS_EX_TRANSPARENT,&H00000020,this is the help for 4,WS_EX_TRANSPARENT. For more help, edit STYLES.TXT!
    4,WS_EX_ACCEPTFILES,&H00000010,this is the help for 4,WS_EX_ACCEPTFILES. For more help, edit STYLES.TXT!
    4,WS_EX_LEFT,&H00000000,this is the help for 4,WS_EX_LEFT. For more help, edit STYLES.TXT!
    4,WS_EX_RIGHT,&H00001000,this is the help for 4,WS_EX_RIGHT. For more help, edit STYLES.TXT!
    4,WS_EX_LTRREADING,&H00000000,this is the help for 4,WS_EX_LTRREADING. For more help, edit STYLES.TXT!
    4,WS_EX_RTLREADING,&H00002000,this is the help for 4,WS_EX_RTLREADING. For more help, edit STYLES.TXT!
    4,WS_EX_RIGHTSCROLLBAR,&H00000000,this is the help for 4,WS_EX_RIGHTSCROLLBAR. For more help, edit STYLES.TXT!
    4,WS_EX_LEFTSCROLLBAR,&H00004000,this is the help for 4,WS_EX_LEFTSCROLLBAR. For more help, edit STYLES.TXT!
    5,WS_CHILD,&H40000000,help for 5,WS_CHILD: for more help, edit the STYLES.TXT file!
    5,WS_VISIBLE,STYLE %WS_VISIBLE NOT FOUND IN RULES TABLE,help for 5,WS_VISIBLE: for more help, edit the STYLES.TXT file!
    5,WS_DISABLED,&H08000000,help for 5,WS_DISABLED: for more help, edit the STYLES.TXT file!
    5,WS_GROUP,&H00020000,help for 5,WS_GROUP: for more help, edit the STYLES.TXT file!
    5,WS_BORDER,&H00800000,help for 5,WS_BORDER: for more help, edit the STYLES.TXT file!
    5,WS_TABSTOP,&H00010000,help for 5,WS_TABSTOP: for more help, edit the STYLES.TXT file!
    
    5,LVS_ICON,&H00000000,help for 5,LVS_ICON: for more help, edit the STYLES.TXT file! 
    5,LVS_REPORT,&H00000001,help for 5,LVS_REPORT: for more help, edit the STYLES.TXT file!
    5,LVS_SMALLICON,&H00000002,help for 5,LVS_SMALLICON: for more help, edit the STYLES.TXT file!
    5,LVS_LIST,&H00000003,help for 5,LVS_LIST: for more help, edit the STYLES.TXT file!
    5,LVS_TYPEMASK,&H00000003,help for 5,LVS_TYPEMASK: for more help, edit the STYLES.TXT file!
    5,LVS_TYPESTYLEMASK,&H0000FC00,help for 5,LVS_TYPESTYLEMASK: for more help, edit the STYLES.TXT file!
    5,LVS_ALIGNMASK,&H00000C00,help for 5,LVS_ALIGNMASK: for more help, edit the STYLES.TXT file!
    5,LVS_OWNERDRAWFIXED,&H00000400,help for 5,OWNERDRAFIXED: for more help, edit the STYLES.TXT file!
    5,lVS_SINGLESEL,&H00000004,help for 5,LVS_SINGLESEL: for more help, edit the STYLES.TXT file!
    5,LVS_SHOWSELALWAYS,&H00000008,help for 5,LVS_SHOWSELALWAYS: for more help, edit the STYLES.TXT file!
    5,LVS_SORTASCENDING,&H00000010,help for 5,LVS_SORTASCENDING: for more help, edit the STYLES.TXT file!
    5,LVS_SORTDESCENDING,&H00000020,help for 5,LVS_SORTDESCENDING: for more help, edit the STYLES.TXT file!
    5,LVS_SHAREIMAGELISTS,&H00000040,help for 5,LVS_SHAREIMAGELISTS: for more help, edit the STYLES.TXT file!
    5,LVS_NOLABELWRAP,&H00000080,help for 5,LVS_NOLABELWRAP: for more help, edit the STYLES.TXT file!
    5,LVS_AUTOARRANGE,&H00000100,help for 5,LVS_AUTOARRANGE: for more help, edit the STYLES.TXT file!
    5,LVS_EDITLABELS,&H00000200,help for 5,LVS_EDITLABELS: for more help, edit the STYLES.TXT file!
    5,LVS_OWNERDATA,&H00001000,help for 5,LVS_OWNERDATA: for more help, edit the STYLES.TXT file!
    5,LVS_NOSCROLL,&H00002000,help for 5,LVS_NOSCROLL: for more help, edit the STYLES.TXT file!
    5,LVS_ALIGNTOP,&H00000000,help for 5,LVS_ALIGNTOP: for more help, edit the STYLES.TXT file!
    5,LVS_ALIGNLEFT,&H00000800,help for 5,LVS_ALIGNLEFT: for more help, edit the STYLES.TXT file!
    5,LVS_NOCOLUMNHEADER,&H00004000,help for 5,LVS_NOCOLUMNHEADER: for more help, edit the STYLES.TXT file!
    5,LVS_NOSORTHEADER,&H00008000,help for 5,LVS_NOSORTHEADER: for more help, edit the STYLES.TXT file!
    
    5,WS_EX_CLIENTEDGE,&H00000200,help for 5,WS_EX_CLIENTEDGE: for more help, edit the STYLES.TXT file!
    5,WS_EX_STATICEDGE,&H00020000,help for 5,WS_EX_STATICEDGE: for more help, edit the STYLES.TXT file!
    5,WS_EX_DLGMODALFRAME,&H00000001,help for 5,WS_EX_DLGMODALFRAME: for more help, edit the STYLES.TXT file!
    5,WS_EX_TRANSPARENT,&H00000020,help for 5,WS_EX_TRANSPARENT: for more help, edit the STYLES.TXT file!
    5,WS_EX_ACCEPTFILES,&H00000010,help for 5,WS_EX_ACCEPTFILES: for more help, edit the STYLES.TXT file!
    5,WS_EX_LEFT,&H00000000,help for 5,WS_EX_LEFT: for more help, edit the STYLES.TXT file!
    5,WS_EX_RIGHT,&H00001000,help for 5,WS_EX_RIGHT: for more help, edit the STYLES.TXT file!
    5,WS_EX_LTRREADING,&H00000000,help for 5,WS_EX_LTRREADING: for more help, edit the STYLES.TXT file!
    5,WS_EX_RTLREADING,&H00002000,help for 5,WS_EX_RTLREADING: for more help, edit the STYLES.TXT file!
    5,WS_EX_RIGHTSCROLLBAR,&H00000000,help for 5,WS_EX_RIGHTSCROLLBAR: for more help, edit the STYLES.TXT file!
    5,WS_EX_LEFTSCROLLBAR,&H00004000,help for 5,WS_EX_LEFTSCROLLBAR: for more help, edit the STYLES.TXT file!
    2,WS_CHILD,&H40000000,help for 2,WS_CHILD: for more help, edit STYLES.TXT!
    2,WS_VISIBLE,STYLE %WS_VISIBLE NOT FOUND IN RULES TABLE,help for 2,WS_VISIBLE: for more help, edit STYLES.TXT!
    2,WS_DISABLED,&H08000000,help for 2,WS_DISABLED: for more help, edit STYLES.TXT!
    2,WS_GROUP,&H00020000,help for 2,WS_GROUP: for more help, edit STYLES.TXT!
    2,WS_BORDER,&H00800000,help for 2,WS_BORDER: for more help, edit STYLES.TXT!
    2,WS_TABSTOP,&H00010000,help for 2,WS_TABSTOP: for more help, edit STYLES.TXT!
    2,WS_HSCROLL,&H00100000,help for 2,WS_HSCROLL: for more help, edit STYLES.TXT!
    2,WS_VSCROLL,STYLE %WS_VSCROLL NOT FOUND IN RULES TABLE,help for 2,WS_VSCROLL: for more help, edit STYLES.TXT!
    2,ES_LEFT,&H0,help for 2,ES_LEFT: for more help, edit STYLES.TXT!
    2,ES_CENTER,&H1,help for 2,ES_CENTER: for more help, edit STYLES.TXT!
    2,ES_RIGHT,&H2,help for 2,ES_RIGHT: for more help, edit STYLES.TXT!
    2,ES_MULTILINE,&H4,help for 2,ES_MULTILINE: for more help, edit STYLES.TXT!
    2,ES_UPPERCASE,&H8,help for 2,ES_UPPERCASE: for more help, edit STYLES.TXT!
    2,ES_LOWERCASE,&H10,help for 2,ES_LOWERCASE: for more help, edit STYLES.TXT!
    2,ES_PASSWORD,&H20,help for 2,ES_PASSWORD: for more help, edit STYLES.TXT!
    2,ES_AUTOHSCROLL,&H80,help for 2,ES_AUTOHSCROLL: for more help, edit STYLES.TXT!
    2,ES_AUTOVSCROLL,&H40,help for 2,ES_AUTOVSCROLL: for more help, edit STYLES.TXT!
    2,ES_NOHIDESEL,&H100,help for 2,ES_NOHIDESEL: for more help, edit STYLES.TXT!
    2,ES_OEMCONVERT,&H400,help for 2,ES_OEMCONVERT: for more help, edit STYLES.TXT!
    2,ES_READONLY,&H800,help for 2,ES_READONLY: for more help, edit STYLES.TXT!
    2,ES_WANTRETURN,&H1000,help for 2,ES_WANTRETURN: for more help, edit STYLES.TXT!
    2,ES_NUMBER,&H2000,help for 2,ES_NUMBER: for more help, edit STYLES.TXT!
    2,WS_EX_CLIENTEDGE,&H00000200,help for 2,WS_EX_CLIENTEDGE: for more help, edit STYLES.TXT!
    2,WS_EX_STATICEDGE,&H00020000,help for 2,WS_EX_STATICEDGE: for more help, edit STYLES.TXT!
    2,WS_EX_DLGMODALFRAME,&H00000001,help for 2,WS_EX_DLGMODALFRAME: for more help, edit STYLES.TXT!
    2,WS_EX_TRANSPARENT,&H00000020,help for 2,WS_EX_TRANSPARENT: for more help, edit STYLES.TXT!
    2,WS_EX_ACCEPTFILES,&H00000010,help for 2,WS_EX_ACCEPTFILES: for more help, edit STYLES.TXT!
    2,WS_EX_LEFT,&H00000000,help for 2,WS_EX_LEFT: for more help, edit STYLES.TXT!
    2,WS_EX_RIGHT,&H00001000,help for 2,WS_EX_RIGHT: for more help, edit STYLES.TXT!
    2,WS_EX_LTRREADING,&H00000000,help for 2,WS_EX_LTRREADING: for more help, edit STYLES.TXT!
    2,WS_EX_RTLREADING,&H00002000,help for 2,WS_EX_RTLREADING: for more help, edit STYLES.TXT!
    2,WS_EX_RIGHTSCROLLBAR,&H00000000,help for 2,WS_EX_RIGHTSCROLLBAR: for more help, edit STYLES.TXT!

    Comment

    Working...
    X
    😀
    🥰
    🤢
    😎
    😡
    👍
    👎