' 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
'
[this message has been edited by erik christensen (edited august 18, 2005).]
'
' 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
Comment