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

  • 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).]

  • #2
    ' 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).]

    Comment


    • #3
      ' 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).]

      Comment


      • #4
        ' 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).]

        Comment

        Working...
        X