Click to See Complete Forum and Search --> : last column width in listview (report view)


Tom
January 20th, 1999, 10:46 AM
Hi,


Does anyone know an easy way I can make the width of the LAST column header in a 'report view' listview automatically be equal to the space available.


ie,

if the other columns take up half the width of the listview, the last column takes up the other half.


Similary, if the width of one of the other columns changes, the width of the last column is automatically changed appropiately (so there is never a horizontal scroll bar).


Thanks in advance for any help you can give me.


Tom.

tom
January 20th, 1999, 10:46 AM
Hi,


Does anyone know an easy way I can make the width of the LAST column header in a 'report view' listview automatically be equal to the space available.


ie,

if the other columns take up half the width of the listview, the last column takes up the other half.


Similary, if the width of one of the other columns changes, the width of the last column is automatically changed appropiately (so there is never a horizontal scroll bar).


Thanks in advance for any help you can give me.


Tom.

Chris Eastwood
January 21st, 1999, 04:52 AM
Hi


This problem is probably better split into 2 parts.


1. The resizing of the last column

2. The capturing of the column resize and resizing the columns appropriately


For this post I'll just stick to number 1. Number 2 involves subclassing the ListView to capture the Column Resize event. I've written an article about this on the CodeGuru site (see http://www.codeguru.com/vb/articles/htm/LVTricks.shtml). The article shows how to disable resizing but you could quite easily replace it with your own code.


To resize the last column in the listview, you'll need to determine whether your listview already has a horizontal scrollbar. If it has, then we're not interested in resizing the last column. Otherwise, we want to resize the last column to fill up the remainder of the listview (but not cause a Horizontal Scrollbar to appear).


Here's the code from the sample form I wrote. Place a listview onto the form with two buttons (command1 and command2), then paste in the following code :


Option Explicit


Private Const LVSCW_AUTOSIZE As Long = -1

Private Const LVM_FIRST = &H1000

Private Const LVM_GETCOLUMNWIDTH As Long = LVM_FIRST + 29

Private Const WM_SETREDRAW = &HB

Private Const LVM_SETCOLUMNWIDTH As Long = LVM_FIRST + 30

'

Private Const SM_CXVSCROLL = 2 ' Get Width Of Vertical ScrollBar

Private Const WS_HSCROLL = &H100000

Private Const GWL_STYLE = (-16)

'

Private Declare Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Long) As Long

Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long

Private Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long


Private Function HasHorizontalScrollBar(ByVal lHwnd As Long) As Boolean

'

' General purpose routine to see if ANY control has a Horizontal ScrollBar

'

Dim lStyle As Long


lStyle = GetWindowLong(hwnd, GWL_STYLE)


HasHorizontalScrollBar = lStyle And WS_HSCROLL

End Function


Private Sub Command1_Click()

Dim lCount As Long

'

' This button does an auto resize of all the columns :

'


'

' Turn off Redrawing at this point to speed up / hide the visible changes

'


LockWindowUpdate ListView1.hwnd


For lCount = 0 To ListView1.ColumnHeaders.Count - 1

SendMessageLong ListView1.hwnd, LVM_SETCOLUMNWIDTH, lCount, LVSCW_AUTOSIZE

Next



LockWindowUpdate ByVal 0&


End Sub


Private Sub Command2_Click()

Dim lCount As Long

Dim lNoColumns As Long

Dim lTotSize As Long

Dim lRet As Long

Dim lSize As Long

Dim lHScrollBarWidth As Long

'

' This button will size the listview if no Horizontal scrollbar is displayed

'


'

' Get System defined width of the Horizontal ScrollBars

'

lHScrollBarWidth = GetSystemMetrics(SM_CXVSCROLL)

'

' Get Number of columns in this listview

'

lNoColumns = ListView1.ColumnHeaders.Count

'

' Check if it has a Horizontal Scrollbar

'

If HasHorizontalScrollBar(ListView1.hwnd) Then

'

' Don't do anything if it has ... otherwise ...

'

Else

For lCount = 0 To lNoColumns - 2

'

' Get the total size of all the columns except the last one we want to resize

'

lSize = SendMessageLong(ListView1.hwnd, LVM_GETCOLUMNWIDTH, lCount, 0)

lTotSize = lTotSize + lSize

Next

'

' Now determine how big to make the last columm in pixels

'



lSize = (ListView1.Width / Screen.TwipsPerPixelX) - (lTotSize + lHScrollBarWidth + 10)

'

' Now set the column width

'

SendMessageLong ListView1.hwnd, LVM_SETCOLUMNWIDTH, lNoColumns - 1, lSize

End If



End Sub


Private Sub Form_Load()

Dim lCount As Long

Dim li As ListItem

'

' Populate the listview with some random junk strings

'

With ListView1

.View = lvwReport



For lCount = 1 To 4

.ColumnHeaders.Add , , "Column " & lCount

Next



For lCount = 1 To 3000

Set li = .ListItems.Add(, , String$((Rnd(1) * 20), "X"))

li.SubItems(1) = String$(Rnd(1) * 15, "1")

li.SubItems(2) = String$(Rnd(1) * 15, "2")

li.SubItems(3) = String$(Rnd(1) * 15, "3")

Next

End With



End Sub


Hope it helps


Chris Eastwood

Software Engineer

ACNielsen Ltd


http://www.codeguru.com