Results 1 to 10 of 10

Thread: Fit to Text

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Sep 2001
    Location
    Canada
    Posts
    202

    Fit to Text

    I need to have a richtextbox fit to text... in other words I need it's height to adjust according to how much text is in it. And it will have different font sizes in it so it isn't just a matter of getting the lines and and font size multipling the font sizes by screen.twipsperpixely and off you go. Any ideas on how to go about that?

    Thanks...

    BestCoder

  2. #2
    jim mcnamara
    Guest
    It's messy but you can use GetTextMetrics to get the height of a given font in your control. You have to know what fonts are on what line in the RTB.

    Sample code:

    http://www.allapi.net/apilist/exampl...0Small%20Fonts

  3. #3
    Your Ad Here! Edneeis's Avatar
    Join Date
    Feb 2000
    Location
    Moreno Valley, CA (SoCal)
    Posts
    7,339
    You could try this:
    VB Code:
    1. Private Sub RichTextBox1_Change()
    2.     RichTextBox1.Width = RichTextBox1.Container.TextWidth(RichTextBox1.Text) * 1.1
    3. End Sub

    Its not perfect but it works.

  4. #4
    gaffa
    Guest
    Here's some code I've used to set the RIchText box height to match the contents. I haven't included all the API declarations or constnats - they are easy enought ot find in the API viewer. Returns the height in twips.

    VB Code:
    1. Private Function CalculateTextHeight(pobjRTF As RichTextBox, pobjPic As PictureBox) As Long
    2.  
    3.     'Calcualtes the height of the text in a rich text box
    4.     Dim lLines As Long
    5.     Dim lIndex As Long
    6.     Dim lMax As Long
    7.     Dim lCurrentLine As Long
    8.     Dim lMaxLineHeight As Long
    9.     Dim lTotalLineHeight As Long
    10.     Dim lCharLine As Long
    11.     Dim lCharHeight As Long
    12.     Dim lFont As StdFont
    13.     Dim lSize As SIZEL
    14.     Dim lLastFont As Font
    15.    
    16.     LockWindowUpdate pobjRTF.hwnd
    17.    
    18.     lLines = SendMessage(pobjRTF.hwnd, EM_GETLINECOUNT, 0, 0)
    19.     lMax = Len(pobjRTF.Text)
    20.    
    21.     For lIndex = 0 To lMax
    22.         'See if the current char
    23.         'is on a new line
    24.         lCharLine = SendMessage(pobjRTF.hwnd, EM_LINEFROMCHAR, lIndex, 0)
    25.         If lCharLine > lCurrentLine Then
    26.             If lMaxLineHeight = 0 Then
    27.                 'Must have been a blank space,
    28.                 GetTextSize pobjPic.hdc, lLastFont, "A", lSize
    29.                 lMaxLineHeight = lSize.cy
    30.             End If
    31.             lCurrentLine = lCurrentLine + 1
    32.             lTotalLineHeight = lTotalLineHeight + lMaxLineHeight
    33.             lMaxLineHeight = 0
    34.         End If
    35.         'Get the characters font
    36.         pobjRTF.SelStart = lIndex
    37.         pobjRTF.SelLength = 1
    38.         Set lFont = New StdFont
    39.         lFont.Name = pobjRTF.SelFontName
    40.         lFont.Size = pobjRTF.SelFontSize
    41.         lFont.Bold = pobjRTF.SelBold
    42.         lFont.Underline = pobjRTF.SelUnderline
    43.         lFont.Italic = pobjRTF.SelItalic
    44.         Set pobjPic.Font = lFont
    45.         GetTextSize pobjPic.hdc, lFont, pobjRTF.SelText, lSize
    46.        
    47.         If lSize.cy > lMaxLineHeight Then
    48.             lMaxLineHeight = lSize.cy
    49.         End If
    50.         'Store the old font
    51.         Set lLastFont = lFont
    52.     Next lIndex
    53.    
    54.     'Get the final line info
    55.     If lMaxLineHeight = 0 Then
    56.         'Must have been a blank space,
    57.         GetTextSize pobjPic.hdc, lLastFont, "A", lSize
    58.         lMaxLineHeight = lSize.cy
    59.     End If
    60.     lTotalLineHeight = lTotalLineHeight + lMaxLineHeight
    61.    
    62.     LockWindowUpdate 0
    63.     'Return the value
    64.     CalculateTextHeight = lTotalLineHeight
    65.    
    66.    
    67. End Function
    68.  
    69. Public Sub GetTextSize(phBufferDC As Long, pobjFont As StdFont, pstrText As String, ByRef pusrSize As SIZEL)
    70.     Dim hFont As Long
    71.     Dim hOldFont As Long
    72.     Dim lSize As SIZEL
    73.     Dim strText As String
    74.     'Retrieve the handle of the new font
    75.     hFont = CreateFont(phBufferDC, pobjFont, 0)
    76.     'Select the font into the device context
    77.     hOldFont = SelectObject(phBufferDC, hFont)
    78.  
    79.     strText = pstrText
    80.     'Calculate the text size
    81.     GetTextExtentPoint32 phBufferDC, strText, Len(strText), lSize
    82.  
    83.     pusrSize = lSize
    84.     'Release the old font
    85.     hFont = SelectObject(phBufferDC, hOldFont)
    86.     'Delete the font handle
    87.     DeleteObject hFont
    88.  
    89. End Sub
    90.  
    91. Public Function CreateFont(phDestDC As Long, ByVal pFont As Font, pRotation As Long) As Long
    92.     'Entry point for the font creation
    93.     'procedure
    94.     Dim lf As LogFont
    95.     Dim hwnd As Long
    96.     Dim hdc As Long
    97.     Dim lFont As StdFont
    98.    
    99.     hwnd = GetDesktopWindow
    100.     hdc = GetDC(hwnd)
    101.    
    102.     'Copy the passed in font into the local font
    103.     Set lFont = New StdFont
    104.     With lFont
    105.         .Bold = pFont.Bold
    106.         .Charset = pFont.Charset
    107.         .Italic = pFont.Italic
    108.         .Name = pFont.Name
    109.         .Size = pFont.Size
    110.         .Strikethrough = pFont.Strikethrough
    111.         .Underline = pFont.Underline
    112.         .Weight = pFont.Weight
    113.     End With
    114.    
    115.    
    116.     With lf
    117.         '
    118.         ' All but two properties are very straight-forward,
    119.         ' even with rotation, and map directly.
    120.         '
    121.         .lfHeight = -(lFont.Size * GetDeviceCaps(hdc, LOGPIXELSY)) / 72
    122.         .lfWidth = 0
    123.         .lfEscapement = pRotation * 10
    124.         .lfOrientation = .lfEscapement
    125.         .lfWeight = lFont.Weight
    126.         .lfItalic = lFont.Italic
    127.         .lfUnderline = lFont.Underline
    128.         .lfStrikeOut = lFont.Strikethrough
    129.         .lfClipPrecision = CLIP_DEFAULT_PRECIS
    130.         .lfQuality = PROOF_QUALITY
    131.         .lfPitchAndFamily = DEFAULT_PITCH Or FF_DONTCARE
    132.         .lfFaceName = lFont.Name & vbNullChar
    133.         '
    134.         ' OEM fonts can't rotate, and we must force
    135.         ' substitution with something ANSI.
    136.         '
    137.         .lfCharSet = lFont.Charset
    138.         If .lfCharSet = OEM_CHARSET Then
    139.             If (pRotation Mod 360) <> 0 Then
    140.                 .lfCharSet = ANSI_CHARSET
    141.             End If
    142.         End If
    143.         '
    144.         ' Only TrueType fonts can rotate, so we must
    145.         ' specify TT-only if angle is not zero.
    146.         '
    147.         If (pRotation Mod 360) <> 0 Then
    148.             .lfOutPrecision = OUT_TT_ONLY_PRECIS
    149.         Else
    150.             .lfOutPrecision = OUT_DEFAULT_PRECIS
    151.         End If
    152.     End With
    153.    
    154.     CreateFont = CreateFontIndirect(lf)
    155.    
    156.     Call ReleaseDC(hwnd, hdc)
    157.    
    158.    
    159. End Function

    As you can see, it basically loops through the text and determines the maximum height of each line. You should be able to use some of the text box API calls to do this instead, but I cpould never get the damn things to work properly, so I did it this way. Obviously, it's not blindingly fast, and is probably only suited to small amounts of text (I use it to calculate classifed newspaper ad heights which generally don't have more than a couple of hundred characters).

    - gaffa

  5. #5

    Thread Starter
    Addicted Member
    Join Date
    Sep 2001
    Location
    Canada
    Posts
    202

    That's great

    Thanks gaffa... I'll give that a try in the morning...

    Cheers

  6. #6
    gaffa
    Guest
    If you play around with the code, be a bit careful with the GetTextSize and CreateFont functions - you need to make sure you are cleaning up all the handles properly, or you start leaking memory, and you app will go haywire...

    - gaffa

  7. #7

    Thread Starter
    Addicted Member
    Join Date
    Sep 2001
    Location
    Canada
    Posts
    202
    Hey gaffa... I don't know what made me think of it but as I was in bed last night I had a brilliant idea... I thought "Oh yeah, the scollbars!" The scrollbars maximum position value changes with the amount of text in the control. Therefore if we could get the value of that we could adjust our height accordingly. So here is a little function that I did up. I haven't tested it extensively yet but as far as I can tell it works just fine. It uses the API function GetScrollRange and constant SB_VERT; I think they are available in the API Viewer but if not they are in the winuser.h file. Also the scrollbars property may have to be set vertical... I am not sure.

    VB Code:
    1. Public Sub AdjustHeight(ByVal rtfRichEdit As RichTextLib.RichTextBox, ByVal lpMinHeight As Long)
    2.     Dim lpMax As Long    ' Max scroll position
    3.     Dim lpMin As Long    ' Min scroll position
    4.    
    5.     ' get the scroll range
    6.     GetScrollRange rtfRichEdit.hwnd, SB_VERT, lpMin, lpMax
    7.    
    8.     ' It may not be necessary to subtract the lpMin value from lpMax because I can't think of anytime that lpMin would be anything but 0... but just in case....
    9.     If ((lpMax - lpMin) * Screen.TwipsPerPixelY < lpMinHeight) Then
    10.        ' This allows you to set a minimum height for your control
    11.         rtfRichEdit.Height = lpMinHeight
    12.     Else
    13.        ' Else the control height should be equal to the text height - the max scroll value.
    14.         rtfRichEdit.Height = (lpMax - lpMin) * Screen.TwipsPerPixelY
    15.     End If
    16. End Sub

    Anyway... I don't know if this will work for your situation but it works for mine and it is pretty fast. But thanks for offering your code...

    Cheers

    BestCoder

  8. #8
    Conquistador
    Join Date
    Dec 1999
    Location
    Australia
    Posts
    4,527
    VB Code:
    1. RichTextBox1.Height = Me.TextHeight(RichTextBox1.Text) + 150

    That works for me

  9. #9

    Thread Starter
    Addicted Member
    Join Date
    Sep 2001
    Location
    Canada
    Posts
    202
    Well some variation of that would probably work for me if all of the text was the same font and size. But in my case it isn't.

  10. #10
    Conquistador
    Join Date
    Dec 1999
    Location
    Australia
    Posts
    4,527
    Woops, sorry man, I forgot to test it with different font sizes

Posting Permissions

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



Click Here to Expand Forum to Full Width