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

Listview with movable vertical and horizontal splitter windows

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

  • Erik Christensen
    replied
    ' Listview with movable vertical and horizontal splitter windows
    '
    ' Version 4 (Virtual Listview - custom drawn)
    '
    ' This version with drawn splitter bars uses virtual listviews
    ' AND custom drawing. The listviews should have the %LVS_OWNERDATA
    ' style. The data for the listviews are held in the DataArray and
    ' are provided to the listviews in the %LVN_GETDISPINFO part of
    ' the callback function. Custom drawing is used as well, so you
    ' can also as in version 3 provide the font, background color
    ' and foreground color for the listviews.
    '
    ' The column headers in the lower panels are omitted as in version 3.
    '
    ' The custom drawing and the virtual character of the listviews mean
    ' that this version is reacting a little bit slower. Version 2 is
    ' the fastest with the least flicker, I think.
    '
    ' Best regards,
    '
    ' Erik Christensen ---------- September 16, 2005
    Code:
    #COMPILE EXE
    #DIM ALL
    #REGISTER NONE
    '
    #INCLUDE "WIN32API.INC"
    #INCLUDE "COMMCTRL.INC"
    '------------------------------------------------------------------------------
    %IDD_DIALOG1         =  101
    %IDC_SYSLISTVIEW32_1 = 1001
    %IDC_SYSLISTVIEW32_2 = 1002
    %IDC_SYSLISTVIEW32_3 = 1003
    %IDC_SYSLISTVIEW32_4 = 1004
    '------------------------------------------------------------------------------
    FUNCTION SampleListView(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lColCnt _
        AS LONG, BYVAL lRowCnt AS LONG) 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)
        szBuf        = "Individual No."
        tLVC.iOrder  = 0
        ListView_InsertColumn(hCtl, 0, tLVC)
    
        FOR lCol = 1 TO lColCnt-1
            szBuf       = USING$("Variable #", lCol)
            tLVC.iOrder = lCol
            ListView_InsertColumn(hCtl, lCol, tLVC)
        NEXT lCol
        szBuf       = ""
        tLVC.iOrder = lColCnt
        ListView_InsertColumn(hCtl, lCol, tLVC)
    
        ' size columns.
        FOR lCol = 0 TO lColCnt - 1
            SendMessage(hCtl, %LVM_SETCOLUMNWIDTH, lCol, MAKLNG(110, 0))
        NEXT lCol
        SendMessage(hCtl, %LVM_SETCOLUMNWIDTH, lColCnt, MAKLNG(500, 0))
        ListView_DeleteAllItems hCtl
        ListView_SetItemCountEx hCtl, lRowCnt, %LVSICF_NOINVALIDATEALL
    END FUNCTION
    '------------------------------------------------------------------------------
    SUB SynchronizeWindows(BYVAL h1 AS DWORD, BYVAL h2 AS DWORD, BYVAL h3 AS DWORD, _
                           BYVAL h4 AS DWORD, BYREF ColWidth() AS LONG, BYVAL Cols AS LONG)
        LOCAL rc1 AS RECT, rc2 AS RECT, i AS LONG, j AS INTEGER
        FOR i = 0 TO Cols
            j = SendMessage(h1, %LVM_GETCOLUMNWIDTH, i, 0)
            IF j <> ColWidth(i) THEN
                ColWidth(i) = j
                SendMessage h2, %LVM_SETCOLUMNWIDTH, i, MAKLNG(j, 0)
                SendMessage h3, %LVM_SETCOLUMNWIDTH, i, MAKLNG(j, 0)
                SendMessage h4, %LVM_SETCOLUMNWIDTH, i, MAKLNG(j, 0)
            END IF
        NEXT
        rc1.nLeft = %LVIR_BOUNDS : SendMessage h1, %LVM_GETITEMRECT, 0, VARPTR(rc1)
        rc2.nLeft = %LVIR_BOUNDS : SendMessage h2, %LVM_GETITEMRECT, 0, VARPTR(rc2)
        SendMessage h2, %LVM_SCROLL, 0, rc2.nTop - rc1.nTop
        rc2.nLeft = %LVIR_BOUNDS : SendMessage h3, %LVM_GETITEMRECT, 0, VARPTR(rc2)
        SendMessage h3, %LVM_SCROLL, rc2.Nleft - rc1.nLeft, 0
    END SUB
    '------------------------------------------------------------------------------
    SUB SizeWindows(BYVAL h1 AS DWORD, BYVAL h2 AS DWORD, BYVAL h3 AS DWORD, BYVAL h4 AS DWORD, _
                    BYVAL x AS LONG, BYVAL y AS LONG, BYVAL xMid AS LONG, BYVAL yMid AS LONG)
        MoveWindow h1,  3,        3,      xMid-6,     yMid-6,     %TRUE
        MoveWindow h2,  xMid+3,   3,      x-xMid-6,   yMid-6,     %TRUE
        MoveWindow h3,  3,        yMid+3, xMid-6,     y-yMid-6,   %TRUE
        MoveWindow h4,  xMid+3,   yMid+3, x-xMid-6,   y-yMid-6,   %TRUE
    END SUB
    '------------------------------------------------------------------------------
    SUB DrawSplitter(BYVAL hBr AS LONG, BYVAL FV AS LONG, BYVAL FH AS LONG, BYREF Ci AS LONG, BYVAL x AS LONG,  _
                     BYVAL y AS LONG, BYVAL xMid AS LONG, BYVAL yMid AS LONG, BYVAL hWnd AS LONG)
        LOCAL rc AS RECT, hDC AS LONG, pt AS POINTAPI
        DIM co(1 TO 4) AS STATIC LONG
        hDC = GetDC(%HWND_DESKTOP)
        SelectObject hDC, hBr
        IF Ci = 1 THEN PatBlt hDC, co(1), co(2), co(3), co(4), %PATINVERT
        ClientToScreen hWnd, pt
        IF FH = 1 THEN         ' horizontal movement of vertical splitter
            rc.nTop = 3 :       rc.nBottom = y-3 :      rc.nLeft = xMid-3 : rc.nRight = xMid+3
        ELSEIF FV = 1 THEN     ' vertical movement of horizontal splitter
            rc.nTop = yMid-3 :  rc.nBottom = yMid+3 :   rc.nLeft = 3 :      rc.nRight = x-3
        END IF
        co(1) = rc.nLeft + pt.x : co(2) = rc.nTop + pt.y : co(3) = rc.nRight - rc.nLeft : co(4) = rc.nBottom - rc.nTop
        PatBlt hDC, co(1), co(2), co(3), co(4), %PATINVERT
        ReleaseDC hWnd, hDC
        Ci = 1
    END SUB
    '------------------------------------------------------------------------------
    CALLBACK FUNCTION ShowDIALOG1Proc()
        STATIC x AS LONG, y AS LONG, xMid AS LONG, yMid AS LONG
        STATIC xPos AS LONG, yPos AS LONG
        STATIC h1 AS DWORD, h2 AS DWORD, h3 AS DWORD, h4 AS DWORD
        STATIC rc AS RECT
        STATIC PrevTime AS DOUBLE
        DIM ColWidth(0 TO 10) AS STATIC LONG
        STATIC i AS LONG, j AS LONG
        STATIC HorzFlag AS LONG, VertFlag AS LONG
        LOCAL pnmh AS NMHDR PTR
        LOCAL lpLVDispInfo AS LV_DISPINFO PTR
        LOCAL pnm AS NMLVCUSTOMDRAW PTR
        LOCAL szString AS ASCIIZ * 256
        STATIC hDC      AS LONG
        LOCAL memDC     AS LONG
        LOCAL hbitmap   AS LONG
        STATIC hBrush   AS LONG
        STATIC hBrush2  AS LONG
        LOCAL oldBmp    AS LONG
        STATIC Ci       AS LONG
        STATIC hFatFont AS LONG, hOldFont AS LONG
        LOCAL LogPixelsY AS LONG, FontTypeSize AS LONG, FH AS LONG
        DIM DataArray(0 TO 10, 0 TO 60) AS STATIC STRING
        '
        SELECT CASE AS LONG CBMSG
            CASE %WM_INITDIALOG
                '
                SystemParametersInfo %SPI_GETWORKAREA, 0, BYVAL VARPTR(rc), 0
                MoveWindow CBHNDL,rc.nLeft, rc.nTop,rc.nRight - rc.nLeft,rc.nBottom - rc.nTop,%TRUE
                DIALOG SET COLOR CBHNDL, 0, RGB(160,200,200)
                '
                CONTROL ADD "SysListView32", CBHNDL, %IDC_SYSLISTVIEW32_1, _
                    "SysListView32_1", 0, 0, 0, 0, %WS_CHILD OR %WS_VISIBLE OR _
                    %WS_TABSTOP OR %LVS_REPORT OR %LVS_SHOWSELALWAYS OR %LVS_OWNERDATA, %WS_EX_CLIENTEDGE _
                    OR %WS_EX_LEFT OR %WS_EX_RIGHTSCROLLBAR
                CONTROL ADD "SysListView32", CBHNDL, %IDC_SYSLISTVIEW32_2, _
                    "SysListView32_2", 0, 0, 0, 0, %WS_CHILD OR %WS_VISIBLE OR _
                    %WS_TABSTOP OR %LVS_REPORT OR %LVS_SHOWSELALWAYS OR %LVS_OWNERDATA, %WS_EX_LEFT OR _
                    %WS_EX_CLIENTEDGE OR %WS_EX_RIGHTSCROLLBAR
                CONTROL ADD "SysListView32", CBHNDL, %IDC_SYSLISTVIEW32_3, _
                    "SysListView32_3", 0, 0, 0, 0, %WS_CHILD OR %WS_VISIBLE OR %LVS_NOCOLUMNHEADER OR _
                    %WS_TABSTOP OR %LVS_REPORT OR %LVS_SHOWSELALWAYS OR %LVS_OWNERDATA, %WS_EX_LEFT OR _
                    %WS_EX_CLIENTEDGE OR %WS_EX_RIGHTSCROLLBAR
                CONTROL ADD "SysListView32", CBHNDL, %IDC_SYSLISTVIEW32_4, _
                    "SysListView32_4", 0, 0, 0, 0, %WS_CHILD OR %WS_VISIBLE OR %LVS_NOCOLUMNHEADER OR _
                    %WS_TABSTOP OR %LVS_REPORT OR %LVS_SHOWSELALWAYS OR %LVS_OWNERDATA, %WS_EX_LEFT OR _
                    %WS_EX_CLIENTEDGE OR %WS_EX_RIGHTSCROLLBAR
                '
                CONTROL HANDLE CBHNDL, %IDC_SYSLISTVIEW32_1 TO h1
                CONTROL HANDLE CBHNDL, %IDC_SYSLISTVIEW32_2 TO h2
                CONTROL HANDLE CBHNDL, %IDC_SYSLISTVIEW32_3 TO h3
                CONTROL HANDLE CBHNDL, %IDC_SYSLISTVIEW32_4 TO h4
                '
                GetClientRect CBHNDL, rc
                x = rc.nRight   : y = rc.nBottom
                xMid = x \ 2    : yMid = y \ 2
                '
                SizeWindows(h1, h2, h3, h4, x, y, xMid, yMid)
                '
                SampleListView CBHNDL, %IDC_SYSLISTVIEW32_1, 11, 60
                SampleListView CBHNDL, %IDC_SYSLISTVIEW32_2, 11, 60
                SampleListView CBHNDL, %IDC_SYSLISTVIEW32_3, 11, 60
                SampleListView CBHNDL, %IDC_SYSLISTVIEW32_4, 11, 60
                '
                FOR i = 0 TO 10 : ColWidth(i) = SendMessage(h1, %LVM_GETCOLUMNWIDTH, i, 0) : NEXT
                '
                ' Make data
                FOR i = 0 TO 10 ' Columns
                    FOR j = 0 TO 59 ' Rows
                         IF i = 0 THEN
                             DataArray(i,j) = FORMAT$(j + 1)
                         ELSE
                             DataArray(i,j) = FORMAT$(RND(100, 999))
                         END IF
                    NEXT
                NEXT
                '
                hDC = GetDC(%HWND_DESKTOP) : LogPixelsY  = GetDeviceCaps(hDC, %LOGPIXELSY)
                FontTypeSize = 8 : FH = -MulDiv(FontTypeSize, LogPixelsY, 72)
                hFatFont = CreateFont(FH,0,0,0,700,0,0,0,0,3,2,1,82,"MS Sans Serif")
                '
                ' Set column header font
                SendMessage ListView_GetHeader(h1), %WM_SETFONT, hFatFont, MAKLNG(%TRUE,0)
                SendMessage ListView_GetHeader(h2), %WM_SETFONT, hFatFont, MAKLNG(%TRUE,0)
                '
                ' Make pitmap pattern for splitter.
                hDC = GetDC(%HWND_DESKTOP)
                memDC   = CreateCompatibleDC(hDC)
                hBitmap = CreateCompatibleBitmap(hDC, 8, 8)
                oldBmp  = SelectObject(memDC, hBitmap)
                rc.nTop = 0 : rc.nLeft = 0 : rc.nRight = 8 : rc.nBottom = 8
                hBrush = GetStockObject(%BLACK_BRUSH)
                FillRect memDC, rc, hBrush
                ' make the pattern
                FOR j = 0 TO 7 STEP 1
                    IF j=0 OR j=2 OR j=4 OR j=6 THEN
                        FOR i = 0 TO 7 STEP 2
                            SetPixel memDC,i, j, RGB(255,255,255)
                        NEXT
                    ELSE
                        FOR i = 1 TO 7 STEP 2
                            SetPixel memDC, i, j,RGB(255,255,255)
                        NEXT
                    END IF
                NEXT
                'Create the pattern brush
                hBrush2   = CreatePatternBrush(hBitmap)
                DeleteDC memDC
                DeleteObject hBitmap
                hBrush = CreateSolidBrush(RGB(160,200,200))
                ReleaseDC CBHNDL, hDC ' release desktop DC
                hDC = GetDC(CBHNDL)   ' device context of dialog
                Ci = 0 ' flag used in SUB DrawSplitter
                '
            CASE %WM_NOTIFY
                pnmh = CBLPARAM
                SELECT CASE @pnmh.code
                    CASE %NM_CUSTOMDRAW  ' Here you can specify font and color.
                        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. This method may be useful
                                ' in many other situations where the DDT engine may
                                ' swallow the information.
                                ' The following statement makes Windows happy:
                                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 @pnm.iSubItem = 0 THEN             ' "Row header"
                                    ' Specify background color
                                    @pnm.clrTextBk = RGB(227,227,227) ' light gray
                                    ' Specify text color
                                    @pnm.clrText = %BLACK
                                    ' Specify font
                                    hOldFont = SelectObject(@pnm.nmcd.hdc, hFatFont)
                                ELSE
                                    SelectObject @pnm.nmcd.hdc, hOldFont
                                    IF (@pnm.nmcd.dwItemSpec MOD 2) THEN
                                        @pnm.clrTextBk = RGB(200,255,255)
                                        @pnm.clrText = %BLACK
                                    ELSE
                                        @pnm.clrTextBk = %WHITE
                                        @pnm.clrText = %BLACK
                                    END IF
                                END IF
                                SetWindowLong CBHNDL,%DWL_MSGRESULT,(%CDRF_NEWFONT OR %CDRF_NOTIFYSUBITEMDRAW)
                                FUNCTION = 1: EXIT FUNCTION
                        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
                            szString =  DataArray(@lpLVDispInfo.item.iSubItem, @lpLVDispInfo.item.iItem)
                            @lpLVDispInfo.item.pszText = VARPTR(szString)
                        END IF
                        SELECT CASE @pnmh.idFrom
                            CASE %IDC_SYSLISTVIEW32_1 : PostMessage CBHNDL, %WM_USER + 401, 0, 0
                            CASE %IDC_SYSLISTVIEW32_2 : PostMessage CBHNDL, %WM_USER + 402, 0, 0
                            CASE %IDC_SYSLISTVIEW32_3 : PostMessage CBHNDL, %WM_USER + 403, 0, 0
                            CASE %IDC_SYSLISTVIEW32_4 : PostMessage CBHNDL, %WM_USER + 404, 0, 0
                        END SELECT
                END SELECT
                '
            CASE %WM_USER + 401
                IF TIMER - PrevTime > 0.15 AND GetFocus <> h1 THEN SetFocus h1
                PrevTime = TIMER
                IF GetFocus = h1 THEN SynchronizeWindows h1, h2, h3, h4, ColWidth(), 10
                '
            CASE %WM_USER + 402
                IF TIMER - PrevTime > 0.15 AND GetFocus <> h2 THEN SetFocus h2
                PrevTime = TIMER
                IF GetFocus = h2 THEN SynchronizeWindows h2, h1, h4, h3, ColWidth(), 10
                '
            CASE %WM_USER + 403
                IF TIMER - PrevTime > 0.15 AND GetFocus <> h3 THEN SetFocus h3
                PrevTime = TIMER
                IF GetFocus = h3 THEN SynchronizeWindows h3, h4, h1, h2, ColWidth(), 10
                '
            CASE %WM_USER + 404
                IF TIMER - PrevTime > 0.15 AND GetFocus <> h4 THEN SetFocus h4
                PrevTime = TIMER
                IF GetFocus = h4 THEN SynchronizeWindows h4, h3, h2, h1, ColWidth(), 10
                '
            CASE %WM_SIZE
                x = LOWRD(CBLPARAM) : y = HIWRD(CBLPARAM)
                SizeWindows h1, h2, h3, h4, x, y, xMid, yMid
                '
            CASE %WM_MOUSEMOVE
                xPos = LOWRD(CBLPARAM) : yPos = HIWRD(CBLPARAM)
                IF xPos > 8 AND xPos < x-8 AND yPos > 8 AND yPos < y-8 THEN
                    IF ISFALSE (CBWPARAM AND %MK_LBUTTON) THEN ' left button not down
                        IF ABS(xPos - xMid) < 7 AND yPos > 5 AND yPos < y-5 AND ABS(yPos - yMid) > 5 THEN MOUSEPTR 9 : VertFlag = 0 : HorzFlag = 1
                        IF ABS(yPos - yMid) < 7 AND xPos > 4 AND xPos < x-5 AND ABS(xPos - xMid) > 5 THEN MOUSEPTR 7 : HorzFlag = 0 : VertFlag = 1
                    ELSE ' left button down - dragging is going on
                        IF HorzFlag = 1 THEN MOUSEPTR 9 : xMid = xPos : DrawSplitter hBrush2, VertFlag, HorzFlag, Ci, x, y, xMid, yMid, CBHNDL
                        IF VertFlag = 1 THEN MOUSEPTR 7 : yMid = yPos : DrawSplitter hBrush2, VertFlag, HorzFlag, Ci, x, y, xMid, yMid, CBHNDL
                    END IF
                END IF
                '
            CASE %WM_LBUTTONDOWN
                IF HorzFlag = 1 OR VertFlag = 1 THEN SetCapture CBHNDL ELSE ReleaseCapture
                xPos = LOWRD(CBLPARAM) : yPos = HIWRD(CBLPARAM)
                IF xPos > 8 AND xPos < x-8 AND yPos > 8 AND yPos < y-8 THEN
                    IF HorzFlag = 1 THEN MOUSEPTR 9 : xMid = xPos : DrawSplitter hBrush2, VertFlag, HorzFlag, Ci, x, y, xMid, yMid, CBHNDL
                    IF VertFlag = 1 THEN MOUSEPTR 7 : yMid = yPos : DrawSplitter hBrush2, VertFlag, HorzFlag, Ci, x, y, xMid, yMid, CBHNDL
                END IF
                '
            CASE %WM_LBUTTONUP
                SizeWindows h1, h2, h3, h4, x, y, xMid, yMid
                ReleaseCapture : Ci = 0
                ' Ensure overpainting of splitter bar
                IF HorzFlag = 1 THEN rc.nTop = 3 : rc.nBottom = y-3 : rc.nLeft = xMid-3 : rc.nRight = xMid+3
                IF VertFlag = 1 THEN rc.nTop = yMid-3 : rc.nBottom = yMid+3 : rc.nLeft = 3 : rc.nRight = x-3
                FillRect hDC, rc, hBrush
                HorzFlag = 0 : VertFlag = 0
                InvalidateRect CBHNDL, BYVAL %NULL, %FALSE
                '
            CASE %WM_DESTROY
                DeleteObject hBrush
                DeleteObject hBrush2
                DeleteObject hFatFont
                ReleaseDC CBHNDL, hDC
                '
        END SELECT
    END FUNCTION
    '------------------------------------------------------------------------------
    FUNCTION PBMAIN()
        LOCAL hDlg AS DWORD
        LOCAL CC1 AS INIT_COMMON_CONTROLSEX
        CC1.dwSize=SIZEOF(CC1)
        CC1.dwICC=%ICC_WIN95_CLASSES
        InitCommonControlsEX CC1
        DIALOG NEW %HWND_DESKTOP, "Listview with movable vertical and horizontal splitter windows", _
            0, 0, 0, 0, %WS_OVERLAPPED OR %WS_BORDER OR _
            %WS_DLGFRAME OR %WS_THICKFRAME OR %WS_CAPTION OR %WS_SYSMENU OR _
            %WS_MINIMIZEBOX OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME _
            OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_CLIENTEDGE _
            OR %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
            %WS_EX_RIGHTSCROLLBAR, TO hDlg
        DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc
    END FUNCTION
    ------------------


    [This message has been edited by Erik Christensen (edited September 16, 2005).]

    Leave a comment:


  • Erik Christensen
    replied
    ' listview with movable vertical and horizontal splitter windows
    '
    ' version 3 (custom drawing)
    '
    ' this version with drawn splitter bars provides custom drawing.
    ' with this feature you can provide the font, background color
    ' and foreground color for the listviews. in this example a very
    ' simple pattern is provided using these features. you may well
    ' make other color and font schemes. this example uses some code
    ' previously used in this link:
    http://www.powerbasic.com/support/pb...ad.php?t=23230
    '
    ' the column headers in the lower panels have been omitted in this
    ' version.
    '
    ' best regards,
    '
    ' erik christensen ---------- august 20, 2005
    Code:
    #compile exe
    #dim all
    #register none
    '
    #include "win32api.inc"
    #include "commctrl.inc"
    '------------------------------------------------------------------------------
    %idd_dialog1         =  101
    %idc_syslistview32_1 = 1001
    %idc_syslistview32_2 = 1002
    %idc_syslistview32_3 = 1003
    %idc_syslistview32_4 = 1004
    '------------------------------------------------------------------------------
    function samplelistview(byval hdlg as dword, byval lid as long, byval lcolcnt _
        as long, byval lrowcnt as long) 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)
        szbuf        = "individual no."
        tlvc.iorder  = 0
        listview_insertcolumn(hctl, 0, tlvc)
    
        for lcol = 1 to lcolcnt-1
            szbuf       = using$("variable #", lcol)
            tlvc.iorder = lcol
            listview_insertcolumn(hctl, lcol, tlvc)
        next lcol
        szbuf       = "
        tlvc.iorder = lcolcnt
        listview_insertcolumn(hctl, lcol, tlvc)
    
        ' load sample data.
        randomize 2.4  ' get the same numbers for each listview
        for lrow = 0 to lrowcnt - 1
            tlvi.statemask = %lvis_focused
            tlvi.psztext   = varptr(szbuf)
            tlvi.iitem     = lrow
            for lcol = 0 to lcolcnt - 1
                tlvi.isubitem = lcol
                tlvi.lparam   = lrow
                if lcol = 0 then
                    szbuf = format$(lrow+1)
                    tlvi.mask = %lvif_text or %lvif_param or %lvif_state
                    listview_insertitem(hctl, tlvi)
                else
                    szbuf = format$(rnd(100, 999))
                    tlvi.mask = %lvif_text
                    listview_setitem(hctl, tlvi)
                end if
            next lcol
        next lrow
    
        ' size columns.
        for lcol = 0 to lcolcnt - 1
            sendmessage(hctl, %lvm_setcolumnwidth, lcol, maklng(110, 0))
        next lcol
        sendmessage(hctl, %lvm_setcolumnwidth, lcolcnt, maklng(500, 0))
    
    end function
    '------------------------------------------------------------------------------
    sub synchronizewindows(byval h1 as dword, byval h2 as dword, byval h3 as dword, _
                           byval h4 as dword, byref colwidth() as long, byval cols as long)
        local rc1 as rect, rc2 as rect, i as long, j as integer
        for i = 0 to cols
            j = sendmessage(h1, %lvm_getcolumnwidth, i, 0)
            if j <> colwidth(i) then
                colwidth(i) = j
                sendmessage h2, %lvm_setcolumnwidth, i, maklng(j, 0)
                sendmessage h3, %lvm_setcolumnwidth, i, maklng(j, 0)
                sendmessage h4, %lvm_setcolumnwidth, i, maklng(j, 0)
            end if
        next
        rc1.nleft = %lvir_bounds : sendmessage h1, %lvm_getitemrect, 0, varptr(rc1)
        rc2.nleft = %lvir_bounds : sendmessage h2, %lvm_getitemrect, 0, varptr(rc2)
        sendmessage h2, %lvm_scroll, 0, rc2.ntop - rc1.ntop
        rc2.nleft = %lvir_bounds : sendmessage h3, %lvm_getitemrect, 0, varptr(rc2)
        sendmessage h3, %lvm_scroll, rc2.nleft - rc1.nleft, 0
    end sub
    '------------------------------------------------------------------------------
    sub sizewindows(byval h1 as dword, byval h2 as dword, byval h3 as dword, byval h4 as dword, _
                    byval x as long, byval y as long, byval xmid as long, byval ymid as long)
        movewindow h1,  3,        3,      xmid-6,     ymid-6,     %true
        movewindow h2,  xmid+3,   3,      x-xmid-6,   ymid-6,     %true
        movewindow h3,  3,        ymid+3, xmid-6,     y-ymid-6,   %true
        movewindow h4,  xmid+3,   ymid+3, x-xmid-6,   y-ymid-6,   %true
    end sub
    '------------------------------------------------------------------------------
    sub drawsplitter(byval hbr as long, byval fv as long, byval fh as long, byref ci as long, byval x as long,  _
                     byval y as long, byval xmid as long, byval ymid as long, byval hwnd as long)
        local rc as rect, hdc as long, pt as pointapi
        dim co(1 to 4) as static long
        hdc = getdc(%hwnd_desktop)
        selectobject hdc, hbr
        if ci = 1 then patblt hdc, co(1), co(2), co(3), co(4), %patinvert
        clienttoscreen hwnd, pt
        if fh = 1 then         ' horizontal movement of vertical splitter
            rc.ntop = 3 :       rc.nbottom = y-3 :      rc.nleft = xmid-3 : rc.nright = xmid+3
        elseif fv = 1 then     ' vertical movement of horizontal splitter
            rc.ntop = ymid-3 :  rc.nbottom = ymid+3 :   rc.nleft = 3 :      rc.nright = x-3
        end if
        co(1) = rc.nleft + pt.x : co(2) = rc.ntop + pt.y : co(3) = rc.nright - rc.nleft : co(4) = rc.nbottom - rc.ntop
        patblt hdc, co(1), co(2), co(3), co(4), %patinvert
        releasedc hwnd, hdc
        ci = 1
    end sub
    '------------------------------------------------------------------------------
    callback function showdialog1proc()
        static x as long, y as long, xmid as long, ymid as long
        static xpos as long, ypos as long
        static h1 as dword, h2 as dword, h3 as dword, h4 as dword
        static rc as rect
        static prevtime as double
        dim colwidth(0 to 10) as static long
        static i as long, j as long
        static horzflag as long, vertflag as long
        local pnmh as nmhdr ptr
        local nmlv as nmlistview ptr
        local pnm as nmlvcustomdraw ptr
        static hdc      as long
        local memdc     as long
        local hbitmap   as long
        static hbrush   as long
        static hbrush2  as long
        local oldbmp    as long
        static ci       as long
        static hfatfont as long, holdfont as long
        local logpixelsy as long, fonttypesize as long, fh as long
        '
        select case as long cbmsg
            case %wm_initdialog
                '
                systemparametersinfo %spi_getworkarea, 0, byval varptr(rc), 0
                movewindow cbhndl,rc.nleft, rc.ntop,rc.nright - rc.nleft,rc.nbottom - rc.ntop,%true
                dialog set color cbhndl, 0, rgb(160,200,200)
                '
                control add "syslistview32", cbhndl, %idc_syslistview32_1, _
                    "syslistview32_1", 0, 0, 0, 0, %ws_child or %ws_visible or _
                    %ws_tabstop or %lvs_report or %lvs_showselalways, %ws_ex_clientedge _
                    or %ws_ex_left or %ws_ex_rightscrollbar
                control add "syslistview32", cbhndl, %idc_syslistview32_2, _
                    "syslistview32_2", 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
                control add "syslistview32", cbhndl, %idc_syslistview32_3, _
                    "syslistview32_3", 0, 0, 0, 0, %ws_child or %ws_visible or %lvs_nocolumnheader or _
                    %ws_tabstop or %lvs_report or %lvs_showselalways, %ws_ex_left or _
                    %ws_ex_clientedge or %ws_ex_rightscrollbar
                control add "syslistview32", cbhndl, %idc_syslistview32_4, _
                    "syslistview32_4", 0, 0, 0, 0, %ws_child or %ws_visible or %lvs_nocolumnheader or _
                    %ws_tabstop or %lvs_report or %lvs_showselalways, %ws_ex_left or _
                    %ws_ex_clientedge or %ws_ex_rightscrollbar
                '
                control handle cbhndl, %idc_syslistview32_1 to h1
                control handle cbhndl, %idc_syslistview32_2 to h2
                control handle cbhndl, %idc_syslistview32_3 to h3
                control handle cbhndl, %idc_syslistview32_4 to h4
                '
                getclientrect cbhndl, rc
                x = rc.nright   : y = rc.nbottom
                xmid = x \ 2    : ymid = y \ 2
                '
                sizewindows(h1, h2, h3, h4, x, y, xmid, ymid)
                '
                samplelistview cbhndl, %idc_syslistview32_1, 11, 60
                samplelistview cbhndl, %idc_syslistview32_2, 11, 60
                samplelistview cbhndl, %idc_syslistview32_3, 11, 60
                samplelistview cbhndl, %idc_syslistview32_4, 11, 60
                '
                for i = 0 to 10 : colwidth(i) = sendmessage(h1, %lvm_getcolumnwidth, i, 0) : next
                '
                hdc = getdc(%hwnd_desktop) : logpixelsy  = getdevicecaps(hdc, %logpixelsy)
                fonttypesize = 8 : fh = -muldiv(fonttypesize, logpixelsy, 72)
                hfatfont = createfont(fh,0,0,0,700,0,0,0,0,3,2,1,82,"ms sans serif")
                '
                ' set column header font
                sendmessage listview_getheader(h1), %wm_setfont, hfatfont, maklng(%true,0)
                sendmessage listview_getheader(h2), %wm_setfont, hfatfont, maklng(%true,0)
                '
                ' make pitmap pattern for splitter.
                hdc = getdc(%hwnd_desktop)
                memdc   = createcompatibledc(hdc)
                hbitmap = createcompatiblebitmap(hdc, 8, 8)
                oldbmp  = selectobject(memdc, hbitmap)
                rc.ntop = 0 : rc.nleft = 0 : rc.nright = 8 : rc.nbottom = 8
                hbrush = getstockobject(%black_brush)
                fillrect memdc, rc, hbrush
                ' make the pattern
                for j = 0 to 7 step 1
                    if j=0 or j=2 or j=4 or j=6 then
                        for i = 0 to 7 step 2
                            setpixel memdc,i, j, rgb(255,255,255)
                        next
                    else
                        for i = 1 to 7 step 2
                            setpixel memdc, i, j,rgb(255,255,255)
                        next
                    end if
                next
                'create the pattern brush
                hbrush2   = createpatternbrush(hbitmap)
                deletedc memdc
                deleteobject hbitmap
                hbrush = createsolidbrush(rgb(160,200,200))
                releasedc cbhndl, hdc ' release desktop dc
                hdc = getdc(cbhndl)   ' device context of dialog
                ci = 0 ' flag used in sub drawsplitter
                '
            case %wm_notify
                nmlv = cblparam
                if @nmlv.hdr.code = %nm_customdraw then
                    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. this method may be useful
                            ' in many other situations where the ddt engine may
                            ' swallow the information.
                            ' the following statement makes windows happy:
                            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 @pnm.isubitem = 0 then             ' "row header"
                                ' specify background color
                                @pnm.clrtextbk = rgb(227,227,227) ' light gray
                                ' specify text color
                                @pnm.clrtext = %black
                                ' specify font
                                holdfont = selectobject(@pnm.nmcd.hdc, hfatfont)
                            else
                                selectobject @pnm.nmcd.hdc, holdfont
                                if (@pnm.nmcd.dwitemspec mod 2) then
                                    @pnm.clrtextbk = rgb(200,255,255)
                                    @pnm.clrtext = %black
                                else
                                    @pnm.clrtextbk = %white
                                    @pnm.clrtext = %black
                                end if
                            end if
                            setwindowlong cbhndl,%dwl_msgresult,(%cdrf_newfont or %cdrf_notifysubitemdraw)
                            function = 1: exit function
                    end select
                end if
                '
                pnmh = cblparam
                if @pnmh.code = %lvn_getdispinfo then
                    select case @pnmh.idfrom
                        case %idc_syslistview32_1 : postmessage cbhndl, %wm_user + 401, 0, 0
                        case %idc_syslistview32_2 : postmessage cbhndl, %wm_user + 402, 0, 0
                        case %idc_syslistview32_3 : postmessage cbhndl, %wm_user + 403, 0, 0
                        case %idc_syslistview32_4 : postmessage cbhndl, %wm_user + 404, 0, 0
                    end select
                end if
                '
            case %wm_user + 401
                if timer - prevtime > 0.15 and getfocus <> h1 then setfocus h1
                prevtime = timer
                if getfocus = h1 then synchronizewindows h1, h2, h3, h4, colwidth(), 10
                '
            case %wm_user + 402
                if timer - prevtime > 0.15 and getfocus <> h2 then setfocus h2
                prevtime = timer
                if getfocus = h2 then synchronizewindows h2, h1, h4, h3, colwidth(), 10
                '
            case %wm_user + 403
                if timer - prevtime > 0.15 and getfocus <> h3 then setfocus h3
                prevtime = timer
                if getfocus = h3 then synchronizewindows h3, h4, h1, h2, colwidth(), 10
                '
            case %wm_user + 404
                if timer - prevtime > 0.15 and getfocus <> h4 then setfocus h4
                prevtime = timer
                if getfocus = h4 then synchronizewindows h4, h3, h2, h1, colwidth(), 10
                '
            case %wm_size
                x = lowrd(cblparam) : y = hiwrd(cblparam)
                sizewindows h1, h2, h3, h4, x, y, xmid, ymid
                '
            case %wm_mousemove
                xpos = lowrd(cblparam) : ypos = hiwrd(cblparam)
                if xpos > 8 and xpos < x-8 and ypos > 8 and ypos < y-8 then
                    if isfalse (cbwparam and %mk_lbutton) then ' left button not down
                        if abs(xpos - xmid) < 7 and ypos > 5 and ypos < y-5 and abs(ypos - ymid) > 5 then mouseptr 9 : vertflag = 0 : horzflag = 1
                        if abs(ypos - ymid) < 7 and xpos > 4 and xpos < x-5 and abs(xpos - xmid) > 5 then mouseptr 7 : horzflag = 0 : vertflag = 1
                    else ' left button down - dragging is going on
                        if horzflag = 1 then mouseptr 9 : xmid = xpos : drawsplitter hbrush2, vertflag, horzflag, ci, x, y, xmid, ymid, cbhndl
                        if vertflag = 1 then mouseptr 7 : ymid = ypos : drawsplitter hbrush2, vertflag, horzflag, ci, x, y, xmid, ymid, cbhndl
                    end if
                end if
                '
            case %wm_lbuttondown
                if horzflag = 1 or vertflag = 1 then setcapture cbhndl else releasecapture
                xpos = lowrd(cblparam) : ypos = hiwrd(cblparam)
                if xpos > 8 and xpos < x-8 and ypos > 8 and ypos < y-8 then
                    if horzflag = 1 then mouseptr 9 : xmid = xpos : drawsplitter hbrush2, vertflag, horzflag, ci, x, y, xmid, ymid, cbhndl
                    if vertflag = 1 then mouseptr 7 : ymid = ypos : drawsplitter hbrush2, vertflag, horzflag, ci, x, y, xmid, ymid, cbhndl
                end if
                '
            case %wm_lbuttonup
                sizewindows h1, h2, h3, h4, x, y, xmid, ymid
                releasecapture : ci = 0
                ' ensure overpainting of splitter bar
                if horzflag = 1 then rc.ntop = 3 : rc.nbottom = y-3 : rc.nleft = xmid-3 : rc.nright = xmid+3
                if vertflag = 1 then rc.ntop = ymid-3 : rc.nbottom = ymid+3 : rc.nleft = 3 : rc.nright = x-3
                fillrect hdc, rc, hbrush
                horzflag = 0 : vertflag = 0
                invalidaterect cbhndl, byval %null, %false
                '
            case %wm_destroy
                deleteobject hbrush
                deleteobject hbrush2
                deleteobject hfatfont
                releasedc cbhndl, hdc
                '
        end select
    end function
    '------------------------------------------------------------------------------
    function pbmain()
        local hdlg as dword
        local cc1 as init_common_controlsex
        cc1.dwsize=sizeof(cc1)
        cc1.dwicc=%icc_win95_classes
        initcommoncontrolsex cc1
        dialog new %hwnd_desktop, "listview with movable vertical and horizontal splitter windows", _
            0, 0, 0, 0, %ws_overlapped or %ws_border or _
            %ws_dlgframe or %ws_thickframe or %ws_caption or %ws_sysmenu or _
            %ws_minimizebox or %ws_clipsiblings or %ws_visible or %ds_modalframe _
            or %ds_3dlook or %ds_nofailcreate or %ds_setfont, %ws_ex_clientedge _
            or %ws_ex_controlparent or %ws_ex_left or %ws_ex_ltrreading or _
            %ws_ex_rightscrollbar, to hdlg
        dialog show modal hdlg, call showdialog1proc
    end function
    ------------------




    [this message has been edited by erik christensen (edited august 21, 2005).]

    Leave a comment:


  • Erik Christensen
    replied
    ' Listview with movable vertical and horizontal splitter windows
    '
    ' Version 2 (reduced flicker)
    '
    ' This version uses drawn splitters, and redrawing of the windows
    ' is only done when mouse dragging of the splitter in question has
    ' ended. In this way the flicker is reduced markedly. In this
    ' version I have used some code for creating a splitter pattern
    ' presented in the PB Forum by Jules Marchildon, whom I thank very much.
    '
    ' Best regards,
    '
    ' Erik Christensen ---------- August 16, 2005
    '
    ' August 18, 2005. This version has been revised following valuable help
    ' from Michael Mattias and Borje Hagsten, who has kindly tested the code
    ' using Spy++.
    Code:
    #COMPILE EXE
    #DIM ALL
    #REGISTER NONE
    '
    #INCLUDE "WIN32API.INC"
    #INCLUDE "COMMCTRL.INC"
    '------------------------------------------------------------------------------
    %IDD_DIALOG1         =  101
    %IDC_SYSLISTVIEW32_1 = 1001
    %IDC_SYSLISTVIEW32_2 = 1002
    %IDC_SYSLISTVIEW32_3 = 1003
    %IDC_SYSLISTVIEW32_4 = 1004
    '------------------------------------------------------------------------------
    FUNCTION SampleListView(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lColCnt _
        AS LONG, BYVAL lRowCnt AS LONG) 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)
        szBuf        = "Individual No."
        tLVC.iOrder  = 0
        ListView_InsertColumn(hCtl, 0, tLVC)
    
        FOR lCol = 1 TO lColCnt-1
            szBuf       = USING$("Variable #", lCol)
            tLVC.iOrder = lCol
            ListView_InsertColumn(hCtl, lCol, tLVC)
        NEXT lCol
        szBuf       = ""
        tLVC.iOrder = lColCnt
        ListView_InsertColumn(hCtl, lCol, tLVC)
    
        ' Load sample data.
        RANDOMIZE 2.4  ' get the same numbers for each listview
        FOR lRow = 0 TO lRowCnt - 1
            tLVI.stateMask = %LVIS_FOCUSED
            tLVI.pszText   = VARPTR(szBuf)
            tLVI.iItem     = lRow
            FOR lCol = 0 TO lColCnt - 1
                tLVI.iSubItem = lCol
                tLVI.lParam   = lRow
                IF lCol = 0 THEN
                    szBuf = FORMAT$(lRow+1)
                    tLVI.mask = %LVIF_TEXT OR %LVIF_PARAM OR %LVIF_STATE
                    ListView_InsertItem(hCtl, tLVI)
                ELSE
                    szBuf = FORMAT$(RND(100, 999))
                    tLVI.mask = %LVIF_TEXT
                    ListView_SetItem(hCtl, tLVI)
                END IF
            NEXT lCol
        NEXT lRow
    
        ' size columns.
        FOR lCol = 0 TO lColCnt - 1
            SendMessage(hCtl, %LVM_SETCOLUMNWIDTH, lCol, MAKLNG(110, 0))
        NEXT lCol
        SendMessage(hCtl, %LVM_SETCOLUMNWIDTH, lColCnt, MAKLNG(500, 0))
    
    END FUNCTION
    '------------------------------------------------------------------------------
    SUB SynchronizeWindows(BYVAL h1 AS DWORD, BYVAL h2 AS DWORD, BYVAL h3 AS DWORD, _
                           BYVAL h4 AS DWORD, BYREF ColWidth() AS LONG, BYVAL Cols AS LONG)
        LOCAL rc1 AS RECT, rc2 AS RECT, i AS LONG, j AS INTEGER
        FOR i = 0 TO Cols
            j = SendMessage(h1, %LVM_GETCOLUMNWIDTH, i, 0)
            IF j <> ColWidth(i) THEN
                ColWidth(i) = j
                SendMessage h2, %LVM_SETCOLUMNWIDTH, i, MAKLNG(j, 0)
                SendMessage h3, %LVM_SETCOLUMNWIDTH, i, MAKLNG(j, 0)
                SendMessage h4, %LVM_SETCOLUMNWIDTH, i, MAKLNG(j, 0)
            END IF
        NEXT
        rc1.nLeft = %LVIR_BOUNDS : SendMessage h1, %LVM_GETITEMRECT, 0, VARPTR(rc1)
        rc2.nLeft = %LVIR_BOUNDS : SendMessage h2, %LVM_GETITEMRECT, 0, VARPTR(rc2)
        SendMessage h2, %LVM_SCROLL, 0, rc2.nTop - rc1.nTop
        rc2.nLeft = %LVIR_BOUNDS : SendMessage h3, %LVM_GETITEMRECT, 0, VARPTR(rc2)
        SendMessage h3, %LVM_SCROLL, rc2.Nleft - rc1.nLeft, 0
    END SUB
    '------------------------------------------------------------------------------
    SUB SizeWindows(BYVAL h1 AS DWORD, BYVAL h2 AS DWORD, BYVAL h3 AS DWORD, BYVAL h4 AS DWORD, _
                    BYVAL x AS LONG, BYVAL y AS LONG, BYVAL xMid AS LONG, BYVAL yMid AS LONG)
        MoveWindow h1,  3,        3,      xMid-6,     yMid-6,     %TRUE
        MoveWindow h2,  xMid+3,   3,      x-xMid-6,   yMid-6,     %TRUE
        MoveWindow h3,  3,        yMid+3, xMid-6,     y-yMid-6,   %TRUE
        MoveWindow h4,  xMid+3,   yMid+3, x-xMid-6,   y-yMid-6,   %TRUE
    END SUB
    '------------------------------------------------------------------------------
    SUB DrawSplitter(BYVAL hBr AS LONG, BYVAL FV AS LONG, BYVAL FH AS LONG, BYREF Ci AS LONG, BYVAL x AS LONG,  _
                     BYVAL y AS LONG, BYVAL xMid AS LONG, BYVAL yMid AS LONG, BYVAL hWnd AS LONG)
        LOCAL rc AS RECT, hDC AS LONG, pt AS POINTAPI
        DIM co(1 TO 4) AS STATIC LONG
        hDC = GetDC(%HWND_DESKTOP)
        SelectObject hDC, hBr
        IF Ci = 1 THEN PatBlt hDC, co(1), co(2), co(3), co(4), %PATINVERT
        ClientToScreen hWnd, pt
        IF FH = 1 THEN         ' horizontal movement of vertical splitter
            rc.nTop = 3 :       rc.nBottom = y-3 :      rc.nLeft = xMid-3 : rc.nRight = xMid+3
        ELSEIF FV = 1 THEN     ' vertical movement of horizontal splitter
            rc.nTop = yMid-3 :  rc.nBottom = yMid+3 :   rc.nLeft = 3 :      rc.nRight = x-3
        END IF
        co(1) = rc.nLeft + pt.x : co(2) = rc.nTop + pt.y : co(3) = rc.nRight - rc.nLeft : co(4) = rc.nBottom - rc.nTop
        PatBlt hDC, co(1), co(2), co(3), co(4), %PATINVERT
        ReleaseDC hWnd, hDC
        Ci = 1
    END SUB
    '------------------------------------------------------------------------------
    CALLBACK FUNCTION ShowDIALOG1Proc()
        STATIC x AS LONG, y AS LONG, xMid AS LONG, yMid AS LONG
        STATIC xPos AS LONG, yPos AS LONG
        STATIC h1 AS DWORD, h2 AS DWORD, h3 AS DWORD, h4 AS DWORD
        STATIC rc AS RECT
        STATIC PrevTime AS DOUBLE
        DIM ColWidth(0 TO 10) AS STATIC LONG
        STATIC i AS LONG, j AS LONG
        STATIC HorzFlag AS LONG, VertFlag AS LONG
        LOCAL pnmh AS NMHDR PTR
        STATIC hDC      AS LONG
        LOCAL memDC     AS LONG
        LOCAL hbitmap   AS LONG
        STATIC hBrush   AS LONG
        STATIC hBrush2  AS LONG
        LOCAL oldBmp    AS LONG
        STATIC Ci       AS LONG
        '
        SELECT CASE AS LONG CBMSG
            CASE %WM_INITDIALOG
                '
                SystemParametersInfo %SPI_GETWORKAREA, 0, BYVAL VARPTR(rc), 0
                MoveWindow CBHNDL,rc.nLeft, rc.nTop,rc.nRight - rc.nLeft,rc.nBottom - rc.nTop,%TRUE
                DIALOG SET COLOR CBHNDL, 0, RGB(160,200,200)
                '
                CONTROL ADD "SysListView32", CBHNDL, %IDC_SYSLISTVIEW32_1, _
                    "SysListView32_1", 0, 0, 0, 0, %WS_CHILD OR %WS_VISIBLE OR _
                    %WS_TABSTOP OR %LVS_REPORT OR %LVS_SHOWSELALWAYS, %WS_EX_CLIENTEDGE _
                    OR %WS_EX_LEFT OR %WS_EX_RIGHTSCROLLBAR
                CONTROL ADD "SysListView32", CBHNDL, %IDC_SYSLISTVIEW32_2, _
                    "SysListView32_2", 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
                CONTROL ADD "SysListView32", CBHNDL, %IDC_SYSLISTVIEW32_3, _
                    "SysListView32_3", 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
                CONTROL ADD "SysListView32", CBHNDL, %IDC_SYSLISTVIEW32_4, _
                    "SysListView32_4", 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
                '
                CONTROL HANDLE CBHNDL, %IDC_SYSLISTVIEW32_1 TO h1
                CONTROL HANDLE CBHNDL, %IDC_SYSLISTVIEW32_2 TO h2
                CONTROL HANDLE CBHNDL, %IDC_SYSLISTVIEW32_3 TO h3
                CONTROL HANDLE CBHNDL, %IDC_SYSLISTVIEW32_4 TO h4
                '
                GetClientRect CBHNDL, rc
                x = rc.nRight   : y = rc.nBottom
                xMid = x \ 2    : yMid = y \ 2
                '
                SizeWindows(h1, h2, h3, h4, x, y, xMid, yMid)
                '
                SampleListView CBHNDL, %IDC_SYSLISTVIEW32_1, 11, 60
                SampleListView CBHNDL, %IDC_SYSLISTVIEW32_2, 11, 60
                SampleListView CBHNDL, %IDC_SYSLISTVIEW32_3, 11, 60
                SampleListView CBHNDL, %IDC_SYSLISTVIEW32_4, 11, 60
                '
                FOR i = 0 TO 10 : ColWidth(i) = SendMessage(h1, %LVM_GETCOLUMNWIDTH, i, 0) : NEXT
                '
                ' Make pitmap pattern for splitter.
                hDC = GetDC(%HWND_DESKTOP)
                memDC   = CreateCompatibleDC(hDC)
                hBitmap = CreateCompatibleBitmap(hDC, 8, 8)
                oldBmp  = SelectObject(memDC, hBitmap)
                rc.nTop = 0 : rc.nLeft = 0 : rc.nRight = 8 : rc.nBottom = 8
                hBrush = GetStockObject(%BLACK_BRUSH)
                FillRect memDC, rc, hBrush
                ' make the pattern
                FOR j = 0 TO 7 STEP 1
                    IF j=0 OR j=2 OR j=4 OR j=6 THEN
                        FOR i = 0 TO 7 STEP 2
                            SetPixel memDC,i, j, RGB(255,255,255)
                        NEXT
                    ELSE
                        FOR i = 1 TO 7 STEP 2
                            SetPixel memDC, i, j,RGB(255,255,255)
                        NEXT
                    END IF
                NEXT
                'Create the pattern brush
                hBrush2   = CreatePatternBrush(hBitmap)
                DeleteDC memDC
                DeleteObject hBitmap
                hBrush = CreateSolidBrush(RGB(160,200,200))
                ReleaseDC CBHNDL, hDC ' release desktop DC
                hDC = GetDC(CBHNDL)   ' device context of dialog
                Ci = 0 ' flag used in SUB DrawSplitter
                '
            CASE %WM_NOTIFY
                pnmh = CBLPARAM
                IF @pnmh.code = %LVN_GETDISPINFO THEN
                    SELECT CASE @pnmh.idFrom
                        CASE %IDC_SYSLISTVIEW32_1 : PostMessage CBHNDL, %WM_USER + 401, 0, 0
                        CASE %IDC_SYSLISTVIEW32_2 : PostMessage CBHNDL, %WM_USER + 402, 0, 0
                        CASE %IDC_SYSLISTVIEW32_3 : PostMessage CBHNDL, %WM_USER + 403, 0, 0
                        CASE %IDC_SYSLISTVIEW32_4 : PostMessage CBHNDL, %WM_USER + 404, 0, 0
                    END SELECT
                END IF
                '
            CASE %WM_USER + 401
                IF TIMER - PrevTime > 0.15 AND GetFocus <> h1 THEN SetFocus h1
                PrevTime = TIMER
                IF GetFocus = h1 THEN SynchronizeWindows h1, h2, h3, h4, ColWidth(), 10
                '
            CASE %WM_USER + 402
                IF TIMER - PrevTime > 0.15 AND GetFocus <> h2 THEN SetFocus h2
                PrevTime = TIMER
                IF GetFocus = h2 THEN SynchronizeWindows h2, h1, h4, h3, ColWidth(), 10
                '
            CASE %WM_USER + 403
                IF TIMER - PrevTime > 0.15 AND GetFocus <> h3 THEN SetFocus h3
                PrevTime = TIMER
                IF GetFocus = h3 THEN SynchronizeWindows h3, h4, h1, h2, ColWidth(), 10
                '
            CASE %WM_USER + 404
                IF TIMER - PrevTime > 0.15 AND GetFocus <> h4 THEN SetFocus h4
                PrevTime = TIMER
                IF GetFocus = h4 THEN SynchronizeWindows h4, h3, h2, h1, ColWidth(), 10
                '
            CASE %WM_SIZE
                x = LOWRD(CBLPARAM) : y = HIWRD(CBLPARAM)
                SizeWindows h1, h2, h3, h4, x, y, xMid, yMid
                '
            CASE %WM_MOUSEMOVE
                xPos = LOWRD(CBLPARAM) : yPos = HIWRD(CBLPARAM)
                IF xPos > 8 AND xPos < x-8 AND yPos > 8 AND yPos < y-8 THEN
                    IF ISFALSE (CBWPARAM AND %MK_LBUTTON) THEN ' left button not down
                        IF ABS(xPos - xMid) < 7 AND yPos > 5 AND yPos < y-5 AND ABS(yPos - yMid) > 5 THEN MOUSEPTR 9 : VertFlag = 0 : HorzFlag = 1
                        IF ABS(yPos - yMid) < 7 AND xPos > 4 AND xPos < x-5 AND ABS(xPos - xMid) > 5 THEN MOUSEPTR 7 : HorzFlag = 0 : VertFlag = 1
                    ELSE ' left button down - dragging is going on
                        IF HorzFlag = 1 THEN MOUSEPTR 9 : xMid = xPos : DrawSplitter hBrush2, VertFlag, HorzFlag, Ci, x, y, xMid, yMid, CBHNDL
                        IF VertFlag = 1 THEN MOUSEPTR 7 : yMid = yPos : DrawSplitter hBrush2, VertFlag, HorzFlag, Ci, x, y, xMid, yMid, CBHNDL
                    END IF
                END IF
                '
            CASE %WM_LBUTTONDOWN
                IF HorzFlag = 1 OR VertFlag = 1 THEN SetCapture CBHNDL ELSE ReleaseCapture
                xPos = LOWRD(CBLPARAM) : yPos = HIWRD(CBLPARAM)
                IF xPos > 8 AND xPos < x-8 AND yPos > 8 AND yPos < y-8 THEN
                    IF HorzFlag = 1 THEN MOUSEPTR 9 : xMid = xPos : DrawSplitter hBrush2, VertFlag, HorzFlag, Ci, x, y, xMid, yMid, CBHNDL
                    IF VertFlag = 1 THEN MOUSEPTR 7 : yMid = yPos : DrawSplitter hBrush2, VertFlag, HorzFlag, Ci, x, y, xMid, yMid, CBHNDL
                END IF
                '
            CASE %WM_LBUTTONUP
                SizeWindows h1, h2, h3, h4, x, y, xMid, yMid
                ReleaseCapture : Ci = 0
                ' Ensure overpainting of splitter bar
                IF HorzFlag = 1 THEN rc.nTop = 3 : rc.nBottom = y-3 : rc.nLeft = xMid-3 : rc.nRight = xMid+3
                IF VertFlag = 1 THEN rc.nTop = yMid-3 : rc.nBottom = yMid+3 : rc.nLeft = 3 : rc.nRight = x-3
                FillRect hDC, rc, hBrush
                HorzFlag = 0 : VertFlag = 0
                InvalidateRect CBHNDL, BYVAL %NULL, %FALSE
                '
            CASE %WM_DESTROY
                DeleteObject hBrush
                DeleteObject hBrush2
                ReleaseDC CBHNDL, hDC
                '
        END SELECT
    END FUNCTION
    '------------------------------------------------------------------------------
    FUNCTION PBMAIN()
        LOCAL hDlg AS DWORD
        LOCAL CC1 AS INIT_COMMON_CONTROLSEX
        CC1.dwSize=SIZEOF(CC1)
        CC1.dwICC=%ICC_WIN95_CLASSES
        InitCommonControlsEX CC1
        DIALOG NEW %HWND_DESKTOP, "Listview with movable vertical and horizontal splitter windows", _
            0, 0, 0, 0, %WS_OVERLAPPED OR %WS_BORDER OR _
            %WS_DLGFRAME OR %WS_THICKFRAME OR %WS_CAPTION OR %WS_SYSMENU OR _
            %WS_MINIMIZEBOX OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME _
            OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_CLIENTEDGE _
            OR %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
            %WS_EX_RIGHTSCROLLBAR, TO hDlg
        DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc
    END FUNCTION


    [This message has been edited by Erik Christensen (edited August 21, 2005).]

    Leave a comment:


  • Listview with movable vertical and horizontal splitter windows

    ' listview with movable vertical and horizontal splitter windows
    '
    ' frequently large amounts of data are organized in spreadsheet
    ' format, each line representing the data of one individual and
    ' each column representing a specific variable or characteristic.
    ' visual orientation and comparison is facilitated by looking at
    ' the data in two windows which can be scrolled in parallel in a
    ' synchronized way (with the same steps) in the two windows.
    ' e.g. if you have a left and right window, vertical scrolling
    ' should be synchronized to maintain the same relative line
    ' position in the two windows at any time. similarly, if you have
    ' an upper and lower window, horizontal scrolling should be
    ' synchronized so that the column positions in the upper window
    ' always are the same as in the lower window.

    ' this short code illustrates a four panel splitter window with
    ' parallel scrolling as described above. you can size and scroll
    ' any of the 4 list view controls applied so you can obtain the
    ' view of the data which suits you best. changing the column width
    ' in one panel will automatically be transferred to the other
    ' panels. you can move the splitters so much that in fact only one
    ' panel is visible. you can change this view back to a four panel
    ' view very easily.
    '
    ' best regards,
    '
    ' erik christensen ---------- august 14, 2005
    '
    ' august 18, 2005
    ' this version has been revised following valuable help
    ' from michael mattias and borje hagsten.
    ' for details on this see this thread where you should also post
    ' any comments you may have:
    http://www.powerbasic.com/support/pb...ad.php?t=12258
    '
    Code:
    #compile exe
    #dim all
    #register none
    '
    #include "win32api.inc"
    #include "commctrl.inc"
    '------------------------------------------------------------------------------
    %idd_dialog1         =  101
    %idc_syslistview32_1 = 1001
    %idc_syslistview32_2 = 1002
    %idc_syslistview32_3 = 1003
    %idc_syslistview32_4 = 1004
    '------------------------------------------------------------------------------
    function samplelistview(byval hdlg as dword, byval lid as long, byval lcolcnt _
        as long, byval lrowcnt as long) 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)
        szbuf        = "individual no."
        tlvc.iorder  = 0
        listview_insertcolumn(hctl, 0, tlvc)
    
        for lcol = 1 to lcolcnt-1
            szbuf       = using$("variable #", lcol)
            tlvc.iorder = lcol
            listview_insertcolumn(hctl, lcol, tlvc)
        next lcol
        szbuf       = "
        tlvc.iorder = lcolcnt
        listview_insertcolumn(hctl, lcol, tlvc)
    
        ' load sample data.
        randomize 2.4  ' get the same numbers for each listview
        for lrow = 0 to lrowcnt - 1
            tlvi.statemask = %lvis_focused
            tlvi.psztext   = varptr(szbuf)
            tlvi.iitem     = lrow
            for lcol = 0 to lcolcnt - 1
                tlvi.isubitem = lcol
                tlvi.lparam   = lrow
                if lcol = 0 then
                    szbuf = format$(lrow+1)
                    tlvi.mask = %lvif_text or %lvif_param or %lvif_state
                    listview_insertitem(hctl, tlvi)
                else
                    szbuf = format$(rnd(100, 999))
                    tlvi.mask = %lvif_text
                    listview_setitem(hctl, tlvi)
                end if
            next lcol
        next lrow
    
        ' size columns.
        for lcol = 0 to lcolcnt - 1
            sendmessage(hctl, %lvm_setcolumnwidth, lcol, maklng(110, 0))
        next lcol
        sendmessage(hctl, %lvm_setcolumnwidth, lcolcnt, maklng(500, 0))
    
    end function
    '------------------------------------------------------------------------------
    sub synchronizewindows(byval h1 as dword, byval h2 as dword, byval h3 as dword, _
                           byval h4 as dword, byref colwidth() as long, byval cols as long)
        local rc1 as rect, rc2 as rect, i as long, j as integer
        for i = 0 to cols
            j = sendmessage(h1, %lvm_getcolumnwidth, i, 0)
            if j <> colwidth(i) then
                colwidth(i) = j
                sendmessage h2, %lvm_setcolumnwidth, i, maklng(j, 0)
                sendmessage h3, %lvm_setcolumnwidth, i, maklng(j, 0)
                sendmessage h4, %lvm_setcolumnwidth, i, maklng(j, 0)
            end if
        next
        rc1.nleft = %lvir_bounds : sendmessage h1, %lvm_getitemrect, 0, varptr(rc1)
        rc2.nleft = %lvir_bounds : sendmessage h2, %lvm_getitemrect, 0, varptr(rc2)
        sendmessage h2, %lvm_scroll, 0, rc2.ntop - rc1.ntop
        rc2.nleft = %lvir_bounds : sendmessage h3, %lvm_getitemrect, 0, varptr(rc2)
        sendmessage h3, %lvm_scroll, rc2.nleft - rc1.nleft, 0
    end sub
    '------------------------------------------------------------------------------
    sub sizewindows(byval h1 as dword, byval h2 as dword, byval h3 as dword, byval h4 as dword, _
                    byval x as long, byval y as long, byval xmid as long, byval ymid as long)
        movewindow h1,  3,        3,      xmid-6,     ymid-6,     %true
        movewindow h2,  xmid+3,   3,      x-xmid-6,   ymid-6,     %true
        movewindow h3,  3,        ymid+3, xmid-6,     y-ymid-6,   %true
        movewindow h4,  xmid+3,   ymid+3, x-xmid-6,   y-ymid-6,   %true
    end sub
    '------------------------------------------------------------------------------
    callback function showdialog1proc()
        static x as long, y as long, xmid as long, ymid as long
        static xpos as long, ypos as long
        static h1 as dword, h2 as dword, h3 as dword, h4 as dword
        static rc as rect
        static prevtime as double
        dim colwidth(0 to 10) as static long
        static i as long
        static horzflag as long, vertflag as long
        local pnmh as nmhdr ptr
        '
        select case as long cbmsg
            case %wm_initdialog
                '
                systemparametersinfo %spi_getworkarea, 0, byval varptr(rc), 0
                movewindow cbhndl,rc.nleft, rc.ntop,rc.nright - rc.nleft,rc.nbottom - rc.ntop,%true
                dialog set color cbhndl, 0, rgb(160,200,200)
                '
                control add "syslistview32", cbhndl, %idc_syslistview32_1, _
                    "syslistview32_1", 0, 0, 0, 0, %ws_child or %ws_visible or _
                    %ws_tabstop or %lvs_report or %lvs_showselalways, %ws_ex_clientedge _
                    or %ws_ex_left or %ws_ex_rightscrollbar
                control add "syslistview32", cbhndl, %idc_syslistview32_2, _
                    "syslistview32_2", 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
                control add "syslistview32", cbhndl, %idc_syslistview32_3, _
                    "syslistview32_3", 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
                control add "syslistview32", cbhndl, %idc_syslistview32_4, _
                    "syslistview32_4", 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
                '
                control handle cbhndl, %idc_syslistview32_1 to h1
                control handle cbhndl, %idc_syslistview32_2 to h2
                control handle cbhndl, %idc_syslistview32_3 to h3
                control handle cbhndl, %idc_syslistview32_4 to h4
                '
                getclientrect cbhndl, rc
                x = rc.nright   : y = rc.nbottom
                xmid = x \ 2    : ymid = y \ 2
                '
                call sizewindows(h1, h2, h3, h4, x, y, xmid, ymid)
                '
                samplelistview cbhndl, %idc_syslistview32_1, 11, 60
                samplelistview cbhndl, %idc_syslistview32_2, 11, 60
                samplelistview cbhndl, %idc_syslistview32_3, 11, 60
                samplelistview cbhndl, %idc_syslistview32_4, 11, 60
                '
                for i = 0 to 10 : colwidth(i) = sendmessage(h1, %lvm_getcolumnwidth, i, 0) : next
                '
            case %wm_notify
                pnmh = cblparam
                if @pnmh.code = %lvn_getdispinfo then
                    select case @pnmh.idfrom
                        case %idc_syslistview32_1 : postmessage cbhndl, %wm_user + 401, 0, 0
                        case %idc_syslistview32_2 : postmessage cbhndl, %wm_user + 402, 0, 0
                        case %idc_syslistview32_3 : postmessage cbhndl, %wm_user + 403, 0, 0
                        case %idc_syslistview32_4 : postmessage cbhndl, %wm_user + 404, 0, 0
                    end select
                end if
                '
            case %wm_user + 401
                if timer - prevtime > 0.15 and getfocus <> h1 then setfocus h1
                prevtime = timer
                if getfocus = h1 then synchronizewindows h1, h2, h3, h4, colwidth(), 10
                '
            case %wm_user + 402
                if timer - prevtime > 0.15 and getfocus <> h2 then setfocus h2
                prevtime = timer
                if getfocus = h2 then synchronizewindows h2, h1, h4, h3, colwidth(), 10
                '
            case %wm_user + 403
                if timer - prevtime > 0.15 and getfocus <> h3 then setfocus h3
                prevtime = timer
                if getfocus = h3 then synchronizewindows h3, h4, h1, h2, colwidth(), 10
                '
            case %wm_user + 404
                if timer - prevtime > 0.15 and getfocus <> h4 then setfocus h4
                prevtime = timer
                if getfocus = h4 then synchronizewindows h4, h3, h2, h1, colwidth(), 10
                '
            case %wm_size
                x = lowrd(cblparam) : y = hiwrd(cblparam)
                call sizewindows(h1, h2, h3, h4, x, y, xmid, ymid)
                '
            case %wm_mousemove
                xpos = lowrd(cblparam) : ypos = hiwrd(cblparam)
                if xpos > 8 and xpos < x-8 and ypos > 8 and ypos < y-8 then
                    if isfalse (cbwparam and %mk_lbutton) then ' left button not down
                        if abs(xpos - xmid) < 7 and ypos > 5 and ypos < y-5 and abs(ypos - ymid) > 5 then mouseptr 9 : vertflag = 0 : horzflag = 1
                        if abs(ypos - ymid) < 7 and xpos > 4 and xpos < x-5 and abs(xpos - xmid) > 5 then mouseptr 7 : horzflag = 0 : vertflag = 1
                    else ' left button down - dragging is going on
                        if horzflag = 1 then mouseptr 9 : xmid = xpos : call sizewindows(h1, h2, h3, h4, x, y, xmid, ymid)
                        if vertflag = 1 then mouseptr 7 : ymid = ypos : call sizewindows(h1, h2, h3, h4, x, y, xmid, ymid)
                    end if
                end if
                '
            case %wm_lbuttondown
                if horzflag = 1 or vertflag = 1 then setcapture cbhndl else releasecapture
                xpos = lowrd(cblparam) : ypos = hiwrd(cblparam)
                if xpos > 8 and xpos < x-8 and ypos > 8 and ypos < y-8 then
                    if horzflag = 1 then mouseptr 9 : xmid = xpos : call sizewindows(h1, h2, h3, h4, x, y, xmid, ymid)
                    if vertflag = 1 then mouseptr 7 : ymid = ypos : call sizewindows(h1, h2, h3, h4, x, y, xmid, ymid)
                end if
                '
            case %wm_lbuttonup
                releasecapture : horzflag = 0 : vertflag = 0
        end select
    end function
    '------------------------------------------------------------------------------
    function pbmain()
        local hdlg as dword
        local cc1 as init_common_controlsex
        cc1.dwsize=sizeof(cc1)
        cc1.dwicc=%icc_win95_classes
        initcommoncontrolsex cc1
        dialog new %hwnd_desktop, "listview with movable vertical and horizontal splitter windows", _
            0, 0, 0, 0, %ws_overlapped or %ws_border or _
            %ws_dlgframe or %ws_thickframe or %ws_caption or %ws_sysmenu or _
            %ws_minimizebox or %ws_clipsiblings or %ws_visible or %ds_modalframe _
            or %ds_3dlook or %ds_nofailcreate or %ds_setfont, %ws_ex_clientedge _
            or %ws_ex_controlparent or %ws_ex_left or %ws_ex_ltrreading or _
            %ws_ex_rightscrollbar, to hdlg
        dialog show modal hdlg, call showdialog1proc
    end function
    [this message has been edited by erik christensen (edited august 18, 2005).]
Working...
X