Date: 02-16-2022
Return to Index
created by gbSnippets
All columns are always visible (cMin is observed)
Entire ListView width always used (no dead space to the right)
Manual Resize Column (non-RightMost)
1. All other columns expand proportionately.
2. Columns to the left are unchanged.
3. Columns to the right are resized proportionately to fill space to right
Manual Resize RightMost Column
1. Can only be resized smaller
2. Cannot move divider outside the ListView
3. All other columns expand proportionately to fill all available space
Manual Resizing Limitations
1. Cannot move divider farther to the left than LeftEdgeCurrentColumn + cMin
2. Cannot move divider farther to the right than ColsToLeft * cMin.
DoubleClick (non-RightMost)
1.
11. Double-clicked divider expands on to SpaceToRight - ColsToRight*cMin
Stop divider from moving wCol < m
Stop divider from moving wCol > w-n*m
'Compilable Example: (Jose Includes)
#Compiler PBWin 9, PBWin 10
#Compile EXE
#Dim All
%Unicode=1
#Include "Win32API.inc"
#Include "CommCtrl.inc"
%IDC_ListView = 400
Global hDlg, hListView,hListViewH,hConsole As Dword, OrigLVProc, OrigLVHProc As Long
Global CD() As Single, Tracking As Long
Function PBMain() As Long
Dialog New Pixels, 0, "Outlook Resizing",300,300,400,150, %WS_OverlappedWindow To hDlg
CreateListViewControl
Dialog Show Modal hDlg Call DlgProc
End Function
CallBack Function DlgProc() As Long
Local w,h,wCol As Long
Select Case Cb.Msg
Case %WM_InitDialog
OrigLVProc = SetWindowLong(hListView, %GWL_WndProc, CodePtr(NewLVProc)) 'subclass
Case %WM_User + 500
ResizeColumnsLV(Cb.WParam)
ResizeWindows
Case %WM_Size
ResizeWindows
Case %WM_Destroy
SetWindowLong hListView, %GWL_WNDPROC, OrigLVProc
End Select
End Function
Sub CreateListViewControl
Control Add ListView, hDlg, %IDC_ListView,"", 10,10,380,200
Control Handle hDlg, %IDC_ListView To hListView
ListView Insert Column hDlg, %IDC_ListView, 1, "Name", 100, 0
ListView Insert Column hDlg, %IDC_ListView, 2, "Path", 100, 0
ListView Insert Column hDlg, %IDC_ListView, 3, "Date", 100, 0
ListView Insert Column hDlg, %IDC_ListView, 4, "Size", 100, 0
ListView Insert Item hDlg, %IDC_ListView, 1,0, "First Row"
ListView Set Text hDlg, %IDC_ListView, 1, 2, "Column two data which can be very long if you let it which we will in this case"
ListView Set Text hDlg, %IDC_ListView, 1, 3, "Column three data which is long but not all that long."
ListView Set Text hDlg, %IDC_ListView, 1, 4, "This is somewhat short"
ReDim CD(4)
CD(1) = 15 : CD(2) = 60 : CD(3) = 15 : CD(4) = 10
End Sub
Function NewLVProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Local hdnptr As HD_NOTIFY Ptr, hdiptr As HD_ITEM Ptr, w,iCol,wCol,iResult As Long
Select Case Msg
Case %WM_Notify
hdnptr = lParam
hdiptr = @hdnptr.pitem
Select Case @hdnptr.hdr.code
Case %hdn_DividerDblClickW
Tracking = 2
Dialog Post hDlg, %WM_User+500, @hdnptr.iItem + 1, 0
Case %hdn_TrackW
Tracking = 1
Case %hdn_EndTrackW
iResult = @hdnptr.iItem
If Tracking Then Dialog Post hDlg, %WM_User+500, @hdnptr.iItem+1, 0
End Select
End Select
Function = CallWindowProc(OrigLVProc, hWnd, Msg, wParam, lParam)
End Function
Sub DisplayStuff
Local sResult As Single, i, wTotal, iResult As Long, temp$
sResult = 0 : wTotal = 0
For i = 1 To UBound(CD)
sResult = sResult + CD(i)
ListView Get Column hDlg, %IDC_ListView, i To iResult
temp$ = temp$ + Str$(iResult)
wTotal = wTotal + iResult
Next i
Dialog Set Text hDlg, Str$(sResult) + Str$(wTotal) + temp$
End Sub
Sub ResizeWindows
Local x,y,w,h As Long
Dialog Get Client hDlg To w,h
Control Set Size hDlg, %IDC_ListView, w-20, h-20
Control Get Client hDlg, %IDC_ListView To w,h
w = w + 20 * IsTrue(GetWindowLong(hListView, %GWL_STYLE) And %WS_VScroll) 'account for scrollbar
For x = 1 To UBound(CD) : ListView Set Column hDlg, %IDC_ListView, x, CD(x) * w / 100 : Next x
DisplayStuff
End Sub
Sub ResizeColumnsLV(ByVal iCol As Long)
Local i,j,w,h,iResult,wCol,ww, wToLeft,wToRight,wTotal, m As Long
Local pToLeft, pToRight, cMin As Single
'get/set values needed to adjust column percentages
Control Get Client hDlg, %IDC_ListView To w,h 'ListView client w,h
ListView Get Column hDlg, %IDC_Listview, iCol To wCol 'width of column iCol
m = 20 'min column width - pixels
cMin = 100 * m/w 'min column width - percentage of w
'minimum column width
If wCol < m Then wCol = m
'get total width of all columns, including newly resized iCol
For i = 1 To UBound(CD)
ListView Get Column hDlg, %IDC_ListView, i To iResult 'column width
If i < iCol Then pToLeft = pToLeft + CD(i) : wToLeft = wToLeft + iResult
wTotal = wTotal + iResult
Next i
'if wCol is too big (either by double-click or by user re-sizing with mouse) lower wCol
If (wToLeft + wCol) > (w - (UBound(CD)-iCol) * m) Then
wCol = w - wToLeft - (UBound(CD)-iCol)*m 'force column to n*cMin less right edge of LV
For i = iCol+1 To UBound(CD) : CD(i) = cMin : Next i
CD(iCol) = 100 * wCol / w 'set CD(iCol) - percentage of dragged or double-clicked column
Else
For i = iCol+1 To UBound(CD) : pToRight = pToRight + CD(i) : Next i
CD(iCol) = 100 * wCol / w 'set CD(iCol) - percentage of dragged or double-clicked column
'adjust all other appropriate columns
If iCol < UBound(CD) Then
For i = iCol+1 To UBound(CD) : CD(i) = CD(i) / pToRight * (100 - pToLeft - CD(iCol)) : Next i 'all except last column
Else
For i = 1 To iCol-1 : CD(i) = CD(i) /pToLeft * (100 - CD(iCol)) : Next i 'last column only
End If
End If
Tracking = 0
End Sub
'gbs_01020
'Date: 03-10-2012
http://www.garybeene.com/sw/gbsnippets.htm