Sunday, May 1, 2011

How to correctly calculate the height of a table

How do you calculate the height of a flexgrid table in VB6 so that it only contains the number of filled rows.

Currently

myFlexGrid.Height = (myFlexGrid.CellHeight * myFlexGrid.Rows) ' paraphrased from code

comes out at about 3 pixels short per line. Adding in the magic number is a bit hackish and would like to accomplish this without having to resort to that.

Update: To complicate matters it also needs to handle multiline cells.

From stackoverflow
  • You need to go

    Me.MSFlexGrid1.Height = (Me.MSFlexGrid1.CellHeight) * (Me.MSFlexGrid1.Rows + Me.MSFlexGrid1.FixedRows) + 30

    The 30 is to make it two pixels longer to show the black border running around the flexgrid.

    Also disabling the vertical scrollbar helps as well.

    graham.reeds : Actually the 30 is not correct from what I can find: If a user is running in 120dpi mode then 12 twips is equal to 1 pixel. But this adding of a semi-arbitary number is what I am trying to avoid.
    graham.reeds : I've also just found it needs to handle multiline cells.
    RS Conley : Unless the control explicitly supports an autoheight function or exposes the values of the height of every UI element you will not be able to avoid using magic numbers. This is because controls are designed as black boxes. It looks like your logic is going to get complex here I suggest wrapping the flexgrid inside of a control class and add the autoheight function in there so the code in your main routines remains clean.
  • RS Coneley is close, but here is the correct way that accounts for all DPI settings:

    Me.MSFlexGrid1.Height = Me.MSFlexGrid1.CellHeight _
                          * (Me.MSFlexGrid1.Rows + Me.MSFlexGrid1.FixedRows) _
                          + (Screen.TwipsPerPixelY * 2)
    
  • This is the final code I came up with

        For i = 0 To fgrComments.Rows - 1
            'Set MSFlexGrid to appropriate Cell
            myFlexGrid.Row = i
    
            'Set textbox to match the selected cell
            txtSizer.Width = myFlexGrid.ColWidth(2)
            txtSizer.Font = myFlexGrid.Font
            txtSizer.Text = myFlexGrid.Text
    
            'Call API to determine how many lines of text are in text box
            lLinesOfText = SendMessage(txtSizer.hwnd, EM_GETLINECOUNT, 0&, 0&)
    
            ' Update the running values
            lTotalNumberOfRows = lTotalNumberOfRows + lLinesOfText
            lCurrentHeight = lCurrentHeight + myFlexGrid.CellHeight
        Next i
    
        ' resize the grid
        Dim iSpacers As Integer
        iSpacers = Screen.TwipsPerPixelY * lTotalNumberOfRows
        myFlexGrid.Height = lCurrentHeight + iSpacers
    

    You will need to Declare the SendMessage (see here to see how) and the value of EM_GETLINECOUNT, but you should be able to do that yourself:-)

    It doesn't remove the magic numbers but it does rationalise them which is close enough for me.

0 comments:

Post a Comment

Note: Only a member of this blog may post a comment.