dcsimg
Results 1 to 16 of 16

Thread: Listview Height

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2010
    Posts
    1,192

    Listview Height

    Is it possible to calculate LV Height by the number of entries?
    I tried multiplying .Count by font size but it didn't work at all!

  2. #2
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,026

    Re: Listview Height

    You can use FindWindowEx to locate the child window contained within the listview and then use GetClientRect of that child to get the overall dimensions:
    Version 5 of the control has a child with classname of "SysHeader32"
    Version 6 of the control has a child with classname of "msvb_lib_header"

    Note that the listview's header is another child window inside the listview

    The listitem object has a Height property. That could be helpful. You can divide the client height by the listitem height to get a feel for how many listitems can fit without being clipped. Of course this assumes you have a listitem in the listview. This can't really be used to calculate the height of a listview because you can have 100s of list items; where only a few are displayed

    edited: oops, got my brain-wires crossed. The listview doesn't have a separate child window for the view itself, but it does have one for any displayed column headers. Fixed the header class names above.
    Last edited by LaVolpe; Mar 30th, 2019 at 08:57 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  3. #3

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2010
    Posts
    1,192

    Re: Listview Height

    Thank you for that info. Done some Googling for FindWindowEx and it looks pretty advanced stuff (for me).
    Maybe there's some example code? What I hope to do do add x items, then calculate the height of the listview control.
    (Using this height to set a vertical scrollbar on a Frame)

  4. #4
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,026

    Re: Listview Height

    Here are the APIs
    Code:
    Private Declare Function GetClientRect Lib "user32.dll" (ByVal hWnd As Long, ByRef lpRect As RECT) As Long
    Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
    Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
    and here is a sample call. Note: for version 5 of the control, use "SysHeader32" in the FindWindowEx call below
    Code:
        Dim wRect As RECT, hdrRect As RECT
        Dim cy As Long, cHwnd As Long
        
        GetClientRect ListView1.hWnd, wRect
        cHwnd = FindWindowEx(ListView1.hWnd, 0, "msvb_lib_header", vbNullString)
        If cHwnd <> 0 Then GetClientRect cHwnd, hdrRect
        cy = (wRect.Bottom - wRect.Top) - (hdrRect.Bottom - hdrRect.Top) + 1
    cy will be the internal height, excluding borders and the header bar
    If you don't want to exclude the header bar in the height calculation, simply don't call the 2nd GetClientRect statement
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  5. #5

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2010
    Posts
    1,192

    Re: Listview Height

    The code is running without any errors but isn't giving the expected result. cy is returning 163 with 9 entries.
    If I exclude the header this value changes to 180
    Both are too small. The height should be about 2500.

    Is value would you expect cy to be ?

  6. #6
    Hyperactive Member
    Join Date
    Jul 2007
    Location
    Essex, UK.
    Posts
    457

    Re: Listview Height

    The height has been returned to you in Pixels. Multiply by Screen.TwipsperPixelY to get twips.

  7. #7
    Frenzied Member
    Join Date
    Jun 2012
    Posts
    1,222

    Re: Listview Height

    You can use send LVM_GETHEADER to the ListView to get the hWnd of the header.

  8. #8

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2010
    Posts
    1,192

    Re: Listview Height

    Thanks Steve I see now the expected result, and find it's not what I want. Sorry La vople if I asked for the wrong thing.
    If I set Listview height to 500, add eight items, Listview height remains 500 (LaVolpe's code returns 420).
    What I actually want if the height the Listview would be to display the 8 items. Sort of an AutoSize value.
    Maybe it's not possible... so perhaps Choose and height preset per x items.

    "hWnd" is something I've never figured out. Seen it mentioned of course, but never much more. Same as APIs.

  9. #9
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,026

    Re: Listview Height

    You are asking for something like Integral Height. Want whole items displayed, not partial items?

    Here are the API declarations I used. Not the same as in post #4
    Code:
    Private Declare Function GetClientRect Lib "user32.dll" (ByVal hWnd As Long, ByRef lpRect As RECT) As Long
    Private Declare Function GetWindowRect Lib "user32.dll" (ByVal hWnd As Long, ByRef lpRect As RECT) As Long
    Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
    Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
    Here is the code you can place in a routine of yours. Heavily commented so you can follow along
    Code:
        Dim cyItem As Single, cyHdr As Long
        Dim cWnd As Long, wRect As RECT
        Dim cyOffset As Long, cyScale As Single
        
        If ListView1.ListItems.Count = 0 Then Exit Sub ' need at least 1 list item
        
        ' get height of 1 list item
        ' note: appears to return size in container's scalemode, both v5 & v6
        cyItem = ListView1.ListItems(1).Height
        
        ' APIs below will return sizes in pixels
        ' get height of the header bar
        cWnd = FindWindowEx(ListView1.hWnd, 0, "msvb_lib_header", vbNullString)
        If cWnd <> 0 Then
            GetWindowRect cWnd, wRect
            cyHdr = wRect.Bottom - wRect.Top
        End If
        
        ' get height of the listview's client area (inside the borders)
        GetClientRect ListView1.hWnd, wRect
        cyOffset = wRect.Bottom - wRect.Top
        
        ' get height of the entire listview, as it is now and its scale relative to its parent's scalemode
        GetWindowRect ListView1.hWnd, wRect
        cyScale = ListView1.Height / (wRect.Bottom - wRect.Top)
    
        ' calculate difference between inside/outside. This is the border size of top/bottom borders
        cyOffset = (wRect.Bottom - wRect.Top - cyOffset)
        
        ' now calculate the size needed to display 8 listitems in container's scalemode
        cyItem = 8 * Abs(cyItem) + (cyHdr + cyOffset) * cyScale
        ' note: Abs() used in case scalemode is custom, i.e., having a negative scaleheight
        
        ListView1.Height = cyItem
    Edited: 3 tweaks may be needed.
    1. Obviously substitute ListView1 with your listview's actual name
    2. If placing code in a function, replace Exit Sub with Exit Function
    3. If using v5 of common controls use "SysHeader32" vs "msvb_lib_header" in FindWindowEx

    FYI. I hard-coded the nr items to size to 8 per your previous posting. You may want to pass the number of rows as a parameter to your routine instead. That way you can set the integral height to whatever nr of rows you want at any time. If so, replace that hard-coded 8 (2nd to last line) with your parameter name

    Last but not least... The above code will work. But I personally wouldn't use it. Why? I dislike any control option that uses Integral Height (sizes itself based on content) during runtime. Reason is that, in this case, depending on the Font used in the control, then the routine would change the control's height -- potentially much larger. What if you had a checkbox or button or some other control just below the listview? Now they would overlap unless you also adjusted all the other controls around the listview so no overlapping occurred. To each their own. If it's a must-have, then be aware that you may need to move other controls after you calculated the height of your listview. If the new size extended below your form, you'll need to adjust the height of your form. Though this problem could be far more relative in an application that is DPI aware or allowing users to choose their own font
    Last edited by LaVolpe; Mar 31st, 2019 at 09:37 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  10. #10

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2010
    Posts
    1,192

    Re: Listview Height

    My goal is to have the listview (and other controls) on a Frame. Their integral height sets the Top position for each.
    And the Frame scrolls the lot. The LV font is MS Sans Serif , Regular 8.
    If I have 8 items cyitem = 1963.11 and the listview acquires a vertical scrollbar.
    I spent many hours playing around and then a penny dropped with cyItem = ListView1.ListItems(1).Height
    If this was multiplied by LV count, what would happen. I added a coloured label and added this after yours

    Code:
    cyItem = 8 * Abs(cyItem) + (cyHdr + cyOffset) * cyScale
        ' note: Abs() used in case scalemode is custom, i.e., having a negative scaleheight
        Debug.Print cyItem
        
        cyItem = ListView1.ListItems(1).Height * (ListView1.ListItems.Count + 2)
        Debug.Print cyItem
        Debug.Print ListView1.ListItems.Count
        ListView1.Height = cyItem
        Label1.Left = ListView1.Left
        Label1.Top = cyItem + ListView1.Top
    1963.11
    2097.638
    8
    I can't figure why the +2 is needed. Maybe the Header... puzzling. The original cyItem value is about 134 less than the other, regardless of Items count.
    I'm probably missing something.. anyway I find the LV control isn't behaving very well. Can you detect a click on other than column 1, do you know ?
    A problem arises when the row clicked sometimes isn't right, instead col 1 is selected on another (the previous?) row.

  11. #11
    Frenzied Member
    Join Date
    Jun 2012
    Posts
    1,222

    Re: Listview Height

    In my VBCCR ListView I have a public method for the users called 'ComputeControlSize'.

    Below is the code. You need to adapt some few things for your MS ListView. Should be worth a try.
    Code:
    Public Sub ComputeControlSize(ByVal VisibleCount As Long, ByRef Width As Single, ByRef Height As Single, Optional ByVal ProposedWidth As Single, Optional ByVal ProposedHeight As Single)
    Attribute ComputeControlSize.VB_Description = "A method that returns the width and height for a given number of visible list items."
    If VisibleCount < 0 Then Err.Raise 380
    If ListViewHandle <> 0 Then
        Dim RetVal As Long, RC(0 To 1) As RECT, ProposedX As Long, ProposedY As Long
        GetWindowRect ListViewHandle, RC(0)
        GetClientRect ListViewHandle, RC(1)
        With UserControl
        If ProposedWidth <> 0 Then
            ProposedX = CLng(.ScaleX(ProposedWidth, vbContainerSize, vbPixels))
        Else
            ProposedX = -1
        End If
        If ProposedHeight <> 0 Then
            ProposedY = CLng(.ScaleY(ProposedHeight, vbContainerSize, vbPixels))
        Else
            ProposedY = -1
        End If
        RetVal = SendMessage(ListViewHandle, LVM_APPROXIMATEVIEWRECT, IIf(PropView = LvwViewReport, VisibleCount - 1, VisibleCount), MakeDWord(ProposedX, ProposedY))
        If LoWord(RetVal) <> 0 Then Width = .ScaleX(LoWord(RetVal) + ((RC(0).Right - RC(0).Left) - (RC(1).Right - RC(1).Left)), vbPixels, vbContainerSize)
        If HiWord(RetVal) <> 0 Then Height = .ScaleY(HiWord(RetVal) + ((RC(0).Bottom - RC(0).Top) - (RC(1).Bottom - RC(1).Top)), vbPixels, vbContainerSize)
        End With
    End If
    End Sub
    In the first param VisibleCount you specify what count of visible items you desire.
    The second and third are returning the resulti g width and height.

  12. #12
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,026

    Re: Listview Height

    @Alexander. What did not work in post #9? The listview in my tests was sized perfectly. My tests included both versions of the control, different font sizes, different visible rows, and different scalemodes.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  13. #13

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2010
    Posts
    1,192

    Re: Listview Height

    I'm still trying to figure it all out. I think now you're right except I didn't expect a scroll bar.
    Adding 134 to cyitem and setting that height it goes away. But with and without the 134 cyitem is correct
    and the label displays where it should. It's only 8 items shouldn't have a scrollbar. I'm confused. I'll attach what I have, suspecting all is correct, except for me!

    Sorry Krool, I couldn't get your Sub to run.
    Attached Files Attached Files

  14. #14
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,026

    Re: Listview Height

    Quote Originally Posted by AlexanderBB View Post
    I'm still trying to figure it all out. I think now you're right except I didn't expect a scroll bar.
    So, to better describe the scenario. When the LV has exactly 8 items (or whatever number the LV is sized to), you don't want the scrollbar? Understandable.

    Since that wasn't explained, my routine in post #9 is not guaranteed to do that. Why? Well, the LV is probably using a pixel around the header (2 total), then another between each listitem (7 more). That equates to 9 pixels or 135 twips. The 135 twips can be hardcoded but only if it behaves that way every time, regardless of font, DPI, etc. Otherwise, more calculations are needed in order to discover those offsets.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  15. #15

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2010
    Posts
    1,192

    Re: Listview Height

    Looks like either use cyitem result or the .ListItems(1).Height * count are a solution. Cool, thank you.
    I don't suppose you know a way to detect a sub item click ? Or change the column which accept click event ? Seems to be only the first one.

  16. #16
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,026

    Re: Listview Height

    SubItem click examples can be found on the forum. Look for keywords: ListView HitTest
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width