View Full Version : TextWidth Inaccurate?


Malashaan
08-11-2010, 07:56 PM
I'm using TextWidth to format a report but it doesn't seem to be returning accurate results. To test what was going on I added the following code which should place the object TestLine lined up the text and set its length to the width of the text, essentially an underline.

Me.TestLine.Left = txtData.Left + intMargin
Me.TestLine.Width = TextWidth(txtData.Value)

In the preview of the report the "underline" is sometimes bang on the correct length but more often than not it is as much as 50% longer than the actual text. I've checked the font and size parameters and they all match up. I've also checked the values of each term in the above equations - the line drawn is correct based on these numbers. I'm fairly certain TextWidth is indeed returning over sized values, I just can't see a reason for it or a way round it.

My full code is loosely based on Lebans' leaderdots function (found here (http://www.lebans.com/leaderdots.htm)) which someone here kindly pointed me at last week. I notice is that sample project the same thing appears to be occurring (at least on my computer) - in that case it manifests as the dotted lines sometimes running right up to the data values they're associated with and sometimes stopping significantly short.

Any suggestions/ideas?

EDIT: I've attached a screen cap of how far short the dots sometimes fall including the "underline" I added indicating how long TextWidth is calculating my text to be.

SOS
08-12-2010, 07:56 AM
Can you post a screenshot of what it looks like in design view?

Malashaan
08-12-2010, 08:43 AM
Sure, no problem. I've attached the relevant code I'm using too. I would have done this last night but I'd been up all night and apparently wasn't thinking straight by that point :eek:

Option Compare Database

Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
Dim blErr As Boolean
blErr = fncSizeDots(Me.txtCut, Me.lblCutDots)
End Sub


Private Function fncSizeDots(ctlValue As Control, ctlDots As Control) As Boolean

'Variable to store distance (in TWIPS) that the dots object needs to
'overlap the value object to meet the beginning of the text in it.
Dim intOverlap As Integer

'Value for distance (in TWIPS) to allow for box margins.
Dim intDotsMargin As Integer

'Storage for original report font and scale information information
Dim oldFontName As String
Dim oldFontsize As Integer
Dim oldFontBold As Integer
Dim oldScaleMode As Integer

On Error GoTo Err_fncSizeDots

With Me
oldFontName = .FontName 'Store original font name
oldFontsize = .FontSize 'Store original font size
oldFontBold = .FontBold 'Store original font boldness
oldScaleMode = .ScaleMode 'Store original Scale mode
.ScaleMode = 1 'Set ScaleMode to Twips
End With

intDotsMargin = 20 'set margin correction to estimated value

ctlDots.Width = 100 ' Set ctlDots width to a safe value, well within available space

'Calculate width of ctlDots required to entirely
'fill the space between title and value objects,
'including overlaps to meet text end points.

With ctlValue

'Use ctlValue's font settings for TextWidth calculations in ctlValue
Me.FontName = .FontName
Me.FontSize = .FontSize
If .FontBold = 1 Then
Me.FontBold = True
Else
Me.FontBold = False
End If

Me.Line17.Width = Me.TextWidth(.Value) - intDotsMargin
Me.Line17.Left = .Left + .Width - Me.TextWidth(.Value)

intOverlap = .Width - Me.TextWidth(.Value) 'Calculate overlap required
End With

' Set the width for the control containing dots
ctlDots.Width = (ctlValue.Left - ctlDots.Left) + intOverlap - intDotsMargin

' Restore Report's original Font and scale settings
With Me
.ScaleMode = oldScaleMode
.FontBold = oldFontBold
.FontName = oldFontName
.FontSize = oldFontsize
End With

fncSizeDots = True

Exit_fncSizeDots:
Exit Function

Err_fncSizeDots:
fncSizeDots = False
Resume Exit_fncSizeDots

End Function

SOS
08-12-2010, 08:51 AM
Does your text box (for CUT) have the BACKSTYLE property set to TRANSPARENT or NORMAL?

Malashaan
08-12-2010, 09:23 AM
Transparent, the dots appear through the right hand edge of it - they just stop REALLY early. If you move the dots field out of vertical alignment I can see that they are indeed stopping. The length of the line (me.line17...etc.) confirms the place the dots are stopping is consistent with the value returned by TextWidth.

If I change the value the right hand control is reading from in the table it gives varying results. eg "Brilliant Round" produces a perfect result but "Rectangular Princess" is as bad/worse than "Oval."

scalextric59
08-12-2010, 02:15 PM
I don't know what are you trying to accomplish, but why don't you change the underline property of your control?

Malashaan
08-12-2010, 02:29 PM
I'm trying to get report data in the format

Cut........................ Oval
Cut........... Brilliant Round
Cut......................Square

ie, whatever the value for the record which is printed the title will be left aligned and the value right aligned with period characters filling the gap between them. The underline thing is just a debugging method I introduced to try and figure out what was going on. I'm setting it equal to the size returned by TextWidth to visually confirm that it is inaccurate.

The example I linked to in the first post is a solution to something very similar I was pointed at by someone here. The logic with it is sound and I totally understand what it's doing and it gave me the direction to follow to write my own function. Both the example and my function have the same problem, at least on my computer. I'm thinking it could be graphic driver/printer specific but haven't got to another computer to experiment yet.

Malashaan
08-13-2010, 05:54 PM
I had a moment of inspiration and figured out a way to achieve what I wanted without using the TextWidth function at all. Rather than have a separate text box for the dots I make the object with actual data from the query not visible and have a text box running from the right edge of the data label to the edge of the report. I fill this programatically with myTextBox = ". . . . . ." & myDataBox.Value (but with a lot more dots). Make the text right aligned and any excess dots disappear out of the start of the text box never to be seen by pesky user's eyes ;)

So, my problem is resolved but I'm still very curious. I've set up incredibly basic tests with nothing but a single string and a line set equal to the size returned by TextWidth and the function is just horrendously inaccurate as far as I can tell. I've tried this on both my computers and it behaves exactly the same, but if it's universal I don't understand why it isn't a common problem.

I've attached a VERY simple project which illustrates the problem - unless it's local and works on your computers.