Measure Character Width (regardless of controls and forms) [Resolved]
is it possible to do that only with api calls without doing printer or something ? because I want to use this function vba and getting form handle.
I need to specify text font,italic,bold,size and measure the word or character exact width in pixel format to do my customized wrapping text.
I know it has asked alot in forum and I did a search through all but none could help me.
thanks in advance.
Last edited by vbcodec; Apr 2nd, 2005 at 05:02 PM.
Re: Measure Character Width (regardless of controls and forms)
hi dude, thanks for the reply
but I don't know anything about api advanced api programming like making object handle to it and stuff like that, do u mind making some sample function code?
They would both return different values (unless you're using a fixed-length font). It returns the number of twips, but that can easily be converted to pixels like this:
Re: Measure Character Width (regardless of controls and forms)
thanks dude but like I said its gonna ba vba function which can't have access to form and even if does vba form does not have same method like textwidth
Re: Measure Character Width (regardless of controls and forms)
I've written a class for you that you (and others) might find useful. It only contains a Font property and a TextWidth and a TextHeight method. TextWidth|Height will always return the width/height of the supplied text in pixels. If a multilined text is supplied to the TextWidth method, the return value will be the length of the longest line. TextHeight will return the height needed for all lines to be printed.
It's very easy to use:
VB Code:
Dim o As CTextSize
Set o = New CTextSize
With o.Font
.Name = "Times New Roman"
.Size = 12
.Bold = True
End With
MsgBox o.TextWidth("Hello World!")
If no Font has been supplied the class will use MS Sans Serif, 8pt, with normal font style (not bold or italic).
Enjoy!
Last edited by Joacim Andersson; Apr 2nd, 2005 at 06:55 PM.
Reason: Correcting the spelling of my own class name...
Re: Measure Character Width (regardless of controls and forms)
thanks alot dude, ur code worked fine
except that in example it should be "CTextSize" instead of "CfontSize".
however I found another function around the net in another forum made by somebody else which I thought its not bad to post it here for case somebody else needed it.
VB Code:
Option Explicit
' ===================================
' API Declares
'
Private Declare Function CreateDC Lib "gdi32.dll" Alias "CreateDCA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, lpInitData As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32.dll" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function CreateFontIndirect Lib "gdi32.dll" Alias "CreateFontIndirectA" (lpLogFont As LOGFONT) As Long
Private Declare Function SelectObject Lib "gdi32.dll" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long
Private Declare Function GetTextExtentPoint32 Lib "gdi32.dll" Alias "GetTextExtentPoint32A" (ByVal hdc As Long, ByVal lpsz As String, ByVal cbString As Long, lpSize As SIZE) As Long
Private Declare Function MulDiv Lib "kernel32.dll" (ByVal nNumber As Long, ByVal nNumerator As Long, ByVal nDenominator As Long) As Long
Private Declare Function GetDC Lib "user32.dll" (ByVal hwnd As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32.dll" (ByVal hdc As Long, ByVal nIndex As Long) As Long
Private Declare Function DeleteDC Lib "gdi32.dll" (ByVal hdc As Long) As Long
Private Const LOGPIXELSY As Long = 90
Public Type SIZE
cx As Long
cy As Long
End Type
Private Type LOGFONT
lfHeight As Long
lfWidth As Long
lfEscapement As Long
lfOrientation As Long
lfWeight As Long
lfItalic As Byte
lfUnderline As Byte
lfStrikeOut As Byte
lfCharSet As Byte
lfOutPrecision As Byte
lfClipPrecision As Byte
lfQuality As Byte
lfPitchAndFamily As Byte
lfFaceName As String * 32
End Type
' ===================================
'
' GetTextSize
' -> Measures the size in pixels of a string, given a particular font. This uses
' the GetTextExtentPoint32 API to measure the string. The API is defined as
' follows:
'
' GetTextExtendPoint(ByVal hdc As Long, ByVal lpsz As String, ByVal cbString As Long, lpSize As SIZE)
' hdc: The device context which is attached to the font to be used
' lpsz: The string to measure, based on the font contained in the hdc specified
' cbString: The length of the string which was passed in 'lpsz'
' lpSize: The SIZE structure which the measurements will be returned to
'
'
Public Function GetTextSize(text As String, font As StdFont) As SIZE
Dim tempDC As Long
Dim tempBMP As Long
Dim f As Long
Dim lf As LOGFONT
Dim textSize As SIZE
' Create a device context and a bitmap that can be used to store a
Re: Measure Character Width (regardless of controls and forms)
Originally Posted by vbcodec
thanks alot dude, ur code worked fine
except that in example it should be "CTextSize" instead of "CfontSize".
Whoops... Sorry, that's what happens when you type the code directly in the post... I don't even remember what name I gave my class However I've edited my origional post to correct it
Re: Measure Character Width (regardless of controls and forms) [Resolved]
Just a little side note on the code you provided. It's using GetTextExtentPoint32 which was also suggested by RobDog888 earlier. During my testing that function returned the font size in logical units rather then pixels, so you have to convert that. My class will return the width and height in pixels and also messure the width and height of a string containing multiple lines.
Re: Measure Character Width (regardless of controls and forms) [Resolved]
OK Rob, it looks fine but if you change the Font used in the TextBox it won't messure the correct length of that will it? You create a stock object using ANSI_VAR_FONT so that will use a standard Ansi font, not the font you're using. At least that is how I read the code. Besides according to MSDN the GetTextExtentPoint32 returns the size in logical units and not in pixels.
My code creates a LogFont structure out of a StdFont object. It then creates gets a hFont handle from that via a call to CreateFontInderect which is selected into a Device Context that I create directly from the screen. My class doesn't need any visual components or forms. You just select the font you want to use and call the TextWidth/Height methods to get the size in pixels.