charvi Posted December 9, 2008 Posted December 9, 2008 How can I retrieve the pixel size of a font at a particular size and attribute? This is mainly useful for monospaced fonts. And for proportional fonts, how can I retrieve the pixel size of a specified character at a specified size and attribute? I need this to calculate automatically the size of the label (GUICtrlCreateLabel).
martin Posted December 9, 2008 Posted December 9, 2008 How can I retrieve the pixel size of a font at a particular size and attribute? This is mainly useful for monospaced fonts.And for proportional fonts, how can I retrieve the pixel size of a specified character at a specified size and attribute? I need this to calculate automatically the size of the label (GUICtrlCreateLabel).It's easier to set the font of the gui to whatever you want then create the label and it will automatiucally be the correct size. You can set the gui font back afterwards if needed.Here is an example, but there are other ideas in the same thread. Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
charvi Posted December 10, 2008 Author Posted December 10, 2008 Yes martin, I agree, it's easier to let the label be created automatically. But knowing the size of a character in a certain font with some attributes set, it can help construct the screen page in advance, and not only for labels. Because nobody else replied to my original question, I must think that there is no way at this time. So, because of this, I was thinking of a way to get a value anyway. The code below is my solution as I have no (or too few) knowledge about Win API stuff, so I wrote a pure AutoIt method. If you have comments or ideas to make it better, your welcome. I even don't know if the values returned are correct. expandcollapse popup#include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <GuiStatusBar.au3> #include <GuiEdit.au3> #include <GuiMenu.au3> #include <GuiToolBar.au3> #include <GuiComboBoxEx.au3> #include <Array.au3> #include <Constants.au3> #include <WinAPI.au3> #include <File.au3> #include <Misc.au3> #include <GDIPlus.au3> #include <Color.au3> Global $h_Wx, $h_Label, $i_LabelWidth, $i_LabelHeight, $i_Color, $s_FontName, $n_FontSize, $i_FontAttr, $i_FontWeight, $n_FontWidth, $n_FontHeight Global $s_Char, $i_1, $i_2, $i_we, $i_ws, $i_he, $i_hs, $i_P, $s_Result ; ============================================================== ; Select the Font here $s_FontName = "Courier" $n_FontSize = 30 $i_FontWeight = 400 ; 400 (=normal) or 800 (=bold) $i_FontAttr = 1 $s_Char = "W" ; ============================================================== ; For larger font sizes like 200, set the label width and height ; both to 300 for example ; don't forget: the bigger the label, the longer it will take $i_LabelWidth = 30 $i_LabelHeight = 30 ; ============================================================== $h_Wx = GUICreate("",$i_LabelWidth,$i_LabelHeight,0,0,$WS_POPUP) GUISetBkColor(0xc1c1c1, $h_Wx) $h_Label = GUICtrlCreateLabel($s_Char,0,0,$i_LabelWidth,$i_LabelHeight) GUIctrlSetFont($h_Label, $n_FontSize, $i_FontWeight, $i_FontAttr, $s_FontName) GUICtrlSetBkColor($h_Label, 0xc0c0c0) GUICtrlSetColor($h_Label, 0xc2c2c2) GUISetState(@SW_SHOW) ; ============================================================== ; Begin measurements $i_we = 0 For $i_1 = 0 To $i_LabelHeight-1 For $i_2 = $i_LabelWidth-1 To 0 Step -1 $i_P = PixelGetColor($i_2, $i_1) If $i_P <> 0xc0c0c0 Then If $i_we < $i_2 Then $i_we = $i_2 EndIf EndIf Next Next $i_ws = $i_LabelWidth For $i_1 = 0 To $i_LabelHeight-1 For $i_2 = 0 To $i_LabelWidth-1 $i_P = PixelGetColor($i_2, $i_1) If $i_P <> 0xc0c0c0 Then If $i_ws > $i_2 Then $i_ws = $i_2 EndIf EndIf Next Next $i_he = 0 For $i_1 = 0 To $i_LabelHeight-1 For $i_2 = $i_LabelWidth-1 To 0 Step -1 $i_P = PixelGetColor($i_2, $i_1) If $i_P <> 0xc0c0c0 Then If $i_he < $i_1 Then $i_he = $i_1 EndIf EndIf Next Next $i_hs = $i_LabelHeight For $i_1 = 0 To $i_LabelHeight-1 For $i_2 = 0 To $i_LabelWidth-1 $i_P = PixelGetColor($i_2, $i_1) If $i_P <> 0xc0c0c0 Then If $i_hs > $i_1 Then $i_hs = $i_1 EndIf EndIf Next Next GUIDelete($h_Wx) ; ============================================================== ; Display results $s_Result = "Font Name : " & $s_FontName & @CR & "Font Size : " & $n_FontSize & @CR & "Font Weight : " & $i_FontWeight & @CR & "Font Attribute : " & $i_FontAttr & @CR & @CR & @CR $s_Result &="Tested character : " & $s_Char & @CR & @CR $s_Result &= "Width = " & $i_we-$i_ws+1 & @CR & "Height = " & $i_he-$i_hs+1 MsgBox(0, "Result", $s_Result) ; ============================================================== Exit
ResNullius Posted December 11, 2008 Posted December 11, 2008 How can I retrieve the pixel size of a font at a particular size and attribute? This is mainly useful for monospaced fonts.And for proportional fonts, how can I retrieve the pixel size of a specified character at a specified size and attribute? I need this to calculate automatically the size of the label (GUICtrlCreateLabel).You might want to look at thishttp://www.autoitscript.com/forum/index.ph...st&p=550588and/or this http://www.autoitscript.com/forum/index.ph...st&p=608669earlier in the same thread martin linked to:
martin Posted December 11, 2008 Posted December 11, 2008 Yes martin, I agree, it's easier to let the label be created automatically. But knowing the size of a character in a certain font with some attributes set, it can help construct the screen page in advance, and not only for labels. Because nobody else replied to my original question, I must think that there is no way at this time. So, because of this, I was thinking of a way to get a value anyway. The code below is my solution as I have no (or too few) knowledge about Win API stuff, so I wrote a pure AutoIt method. If you have comments or ideas to make it better, your welcome. I even don't know if the values returned are correct. expandcollapse popup#include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <GuiStatusBar.au3> #include <GuiEdit.au3> #include <GuiMenu.au3> #include <GuiToolBar.au3> #include <GuiComboBoxEx.au3> #include <Array.au3> #include <Constants.au3> #include <WinAPI.au3> #include <File.au3> #include <Misc.au3> #include <GDIPlus.au3> #include <Color.au3> Global $h_Wx, $h_Label, $i_LabelWidth, $i_LabelHeight, $i_Color, $s_FontName, $n_FontSize, $i_FontAttr, $i_FontWeight, $n_FontWidth, $n_FontHeight Global $s_Char, $i_1, $i_2, $i_we, $i_ws, $i_he, $i_hs, $i_P, $s_Result ; ============================================================== ; Select the Font here $s_FontName = "Courier" $n_FontSize = 30 $i_FontWeight = 400 ; 400 (=normal) or 800 (=bold) $i_FontAttr = 1 $s_Char = "W" ; ============================================================== ; For larger font sizes like 200, set the label width and height ; both to 300 for example ; don't forget: the bigger the label, the longer it will take $i_LabelWidth = 30 $i_LabelHeight = 30 ; ============================================================== $h_Wx = GUICreate("",$i_LabelWidth,$i_LabelHeight,0,0,$WS_POPUP) GUISetBkColor(0xc1c1c1, $h_Wx) $h_Label = GUICtrlCreateLabel($s_Char,0,0,$i_LabelWidth,$i_LabelHeight) GUIctrlSetFont($h_Label, $n_FontSize, $i_FontWeight, $i_FontAttr, $s_FontName) GUICtrlSetBkColor($h_Label, 0xc0c0c0) GUICtrlSetColor($h_Label, 0xc2c2c2) GUISetState(@SW_SHOW) ; ============================================================== ; Begin measurements $i_we = 0 For $i_1 = 0 To $i_LabelHeight-1 For $i_2 = $i_LabelWidth-1 To 0 Step -1 $i_P = PixelGetColor($i_2, $i_1) If $i_P <> 0xc0c0c0 Then If $i_we < $i_2 Then $i_we = $i_2 EndIf EndIf Next Next $i_ws = $i_LabelWidth For $i_1 = 0 To $i_LabelHeight-1 For $i_2 = 0 To $i_LabelWidth-1 $i_P = PixelGetColor($i_2, $i_1) If $i_P <> 0xc0c0c0 Then If $i_ws > $i_2 Then $i_ws = $i_2 EndIf EndIf Next Next $i_he = 0 For $i_1 = 0 To $i_LabelHeight-1 For $i_2 = $i_LabelWidth-1 To 0 Step -1 $i_P = PixelGetColor($i_2, $i_1) If $i_P <> 0xc0c0c0 Then If $i_he < $i_1 Then $i_he = $i_1 EndIf EndIf Next Next $i_hs = $i_LabelHeight For $i_1 = 0 To $i_LabelHeight-1 For $i_2 = 0 To $i_LabelWidth-1 $i_P = PixelGetColor($i_2, $i_1) If $i_P <> 0xc0c0c0 Then If $i_hs > $i_1 Then $i_hs = $i_1 EndIf EndIf Next Next GUIDelete($h_Wx) ; ============================================================== ; Display results $s_Result = "Font Name : " & $s_FontName & @CR & "Font Size : " & $n_FontSize & @CR & "Font Weight : " & $i_FontWeight & @CR & "Font Attribute : " & $i_FontAttr & @CR & @CR & @CR $s_Result &="Tested character : " & $s_Char & @CR & @CR $s_Result &= "Width = " & $i_we-$i_ws+1 & @CR & "Height = " & $i_he-$i_hs+1 MsgBox(0, "Result", $s_Result) ; ============================================================== ExitThat's an interesting ideas but a bit long winded. You could use the same idea but differently. For example, make a label which is a reference like this GuiCtrlCreateLabel("{",$x,$y);a character which uses all availble height afaik. $RefSize = controlgetpos(.... RefWid = $RefSize[0] Then use your idea to measure the real height. The width of any text can easily be worked out by creating a label with the text you want with '{' added to the text. Get the width of the label using ControlGetPos, take away the $RefWid and that's the width of your text. Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Moderators Melba23 Posted December 11, 2008 Moderators Posted December 11, 2008 Hi,I too have been trying to determine the correct size of a label to hold a given text for some time. Although the trick of omitting the width and height parameters works if there is no text wrapping, I wanted something that would allow wrapping within a set width and still give a good height measurement - by which I mean not trimming the text and not adding too much wasted space at the bottom.So far the best I have come with so far is to use _GDIPlus_GraphicsMeasureString, but even this is not perfect, particularly if a line ends very close to the end of the defined width. Furthermore, I discovered that GDI is not very happy with texts containing multiple @CRLF (try seaching in Google and see how many frustrated coders there are out there!), so I went the line-by-line route.The code draws each line of the text unwrapped to get its length. Dividing by the width requires then gives the number of lines it takes, although this takes no account of the wasted white-space at the end of lines cause by word breaks.Another method I tried was to find the height of a GDI character for a given font and size and then GDI draw each line of the text within the required width to see how many lines it takes, but my experiments showed this method is only really useful for monospace (fixed width) fonts where it sometimes gives the correct answer when the dividing method does not.Once the total number of lines has been determined, simply multiply this by the height of a GUICtrlCreateLabel character for the same font and size (and they are not quite the same!) and then you have the label height required. The following code is not infallible, but it is best I have produced to date:CODE#include-once#Include <GDIPlus.au3>#EndRegion; #FUNCTION# =======================================================================================; Name............: _Label_Size; Description ....: Returns the size of label required for a given text, even if wrapped to a width; Syntax..........: _Label_Size($sText, $iFont_Size, $sFont_Name[, $iWidth]); Parameters .....: $sText -> The text to display with @CRLF line endings; $iFont_Size -> The font size in points; $sFont_Name -> The font name; $iWidth -> The max width of the label - default is width of desktop; Requirement(s)..: v3.2.12.1 or higher; Return values ..: Success: Returns an array giving details of the label needed to hold the text; $array[0] = Number of unwrapped lines in $sText ; $array[1] = Height of 1 line of text ; $array[2] = Width of label required to hold text ; $array[3] = Height of label required to hold text; Failure: Returns 0 ; - Error 1 - Failure to create GUI to test label size; - Error 2 - GDI measure string failure; Author .........: Melba23, based on some original GDI code by Malkey; Example.........; Yes;===================================================================================================Func _Label_Size_Test($sText, $iFont_Size, $sFont_Name, $iWidth = @DesktopWidth) Local $hGUI, $hLabel, $hWin, $hGraphic, $hFamily, $hGDIFont, $hFormat, $tLayout, $iMessage_Depth Local $nGDI_Line, $iDiv_Count, $iGDI_Count, $iDiv_Depth, $iGDI_Depth Local $aLines[1], $aPos[4], $aInfo[3] ; Create GUI $hGUI = GUICreate("", 800, 1000, 800, 10) If $hGUI = 0 Then Return SetError(1, 0, 0) GUISetFont($iFont_Size, 400, 0, $sFont_Name) ; Break text into lines $aLines = StringSplit($sText, @CRLF, 1) ;Now fill with unwrapped lines to check on max width $hLabel = GUICtrlCreateLabel($sText, 10, 10) $aPos = ControlGetPos($hGUI, "", $hLabel) ; Store number of lines and line height for this font size $aPos[0] = $aLines[0] ; Remove label padding (8) $aPos[1] = ($aPos[3] - 8)/ $aLines[0] ; Now see if wrapping is required If $aPos[2] > $iWidth Then ; Set width element to max allowed $aPos[2] = $iWidth $hWin = WinGetHandle("[ACTIVE]") _GDIPlus_Startup() $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hWin) $hFamily = _GDIPlus_FontFamilyCreate($sFont_Name) $hGDIFont = _GDIPlus_FontCreate($hFamily, $iFont_Size) $hFormat = _GDIPlus_StringFormatCreate() ; Get GDI line height $tLayout = _GDIPlus_RectFCreate(0, 0, @DesktopWidth, @DesktopHeight) $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, "X", $hGDIFont, $tLayout, $hFormat) ; Remove GDI padding (2) $nGDI_Line = DllStructGetData($aInfo[0], 4) - 2 ; Set line counts to zero $iDiv_Count = 0 $iGDI_Count = 0 ; Take each line in turn For $j = 1 To $aLines[0] ; Replace blank lines to get valid GDI drawing If StringLen($aLines[$j]) = 0 Then $aLines[$j] = "X" ; GDI width method ; Reset the GDI width to desktop $tLayout = _GDIPlus_RectFCreate(0, 0, @DesktopWidth, @DesktopHeight) ; Draw the line unwrapped $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $aLines[$j], $hGDIFont, $tLayout, $hFormat) If Not IsArray($aInfo) Then GUIDelete($hGUI) Return SetError(2, 0, 0) EndIf ; Divide GDI width by max width $nDiv_Lines = DllStructGetData($aInfo[0], 3) / $iWidth ; Make adjustment to allow for lines which end right on the edge If Mod(DllStructGetData($aInfo[0], 3), $iWidth + 8) > .1 Then $nDiv_Lines += 1 $iDiv_Count += Int($nDiv_Lines) ; GDI Depth method - only used to check mono fonts If $sFont_Name = "Courier New" Or $sFont_Name = "Lucida Console" Then ; Limit the GDI width to max allowed $tLayout = _GDIPlus_RectFCreate(0, 0, $iWidth, @DesktopHeight) ; Draw the line which wraps if required $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $aLines[$j], $hGDIFont, $tLayout, $hFormat) If Not IsArray($aInfo) Then GUIDelete($hGUI) Return SetError(2, 0, 0) EndIf ; Divide GDI depth by line depth $iGDI_Count += Int(DllStructGetData($aInfo[0], 4) / $nGDI_Line) EndIf Next _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_FontDispose($hGDIFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() ; Convert lines to pixels $iDiv_Depth = 8 + Int($iDiv_Count) * $aPos[1] $aPos[3] = $iDiv_Depth $iGDI_Depth = 8 + Round($iGDI_Count) * $nGDI_Line ; Adjust if significant difference between methods for mono fonts If $iGDI_Depth - $iDiv_Depth > $aPos[1] / 2 Then $aPos[3] += $aPos[1] / 2 ; Note: $iGDI_Depth is only 8 if not mono font, so no need to check font type EndIf ; Clean up GUIDelete($hGUI) ; Return array Return $aPosEndFunc ; => _Label_SizeSo that is where I am for the moment. The code works pretty well for font sizes up to about 13 and label width of 350 or more. Bigger fonts or smaller widths mean there is too much wasted white-space at the ends of lines when the line breaks at word endings, leading to trimming.If anyone has any comments or suggestions for what to try next, I would love to hear them. If you have solution that works all the time, even better! :-DM23P.S. Why does the code come out without any formatting when you preview the post? It is fine in the editing box! Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
charvi Posted December 11, 2008 Author Posted December 11, 2008 Okay, my first idea was very primitive and unusable because the height and width were calculated at character level at their limits, so the "a" will be lower than a "d" and a "i" narrower than a "w". Martin's idea is better, and ResNullius has a very quick way to determine the width of a character or even a string. I have not yet tested Melba23 idea, but it is worth a deep study I'm writing to you now because I have taken a look at MSDN for the first time. And I was wondering if GetCharWidth32() at http://msdn.microsoft.com/en-us/library/aa911452.aspx is not the solution we all want? The problem is that I don't know if it is possible to use these functions in AutoIt, and if affirmative, how? Now I'm going to study Melba23 code lol P.S. Why does the code come out without any formatting when you preview the post? It is fine in the editing box!Instead of using [ code ] and [ /code ], use [ autoit ] and [ /autoit ] (without the spaces) to format your code in the forum.
martin Posted December 11, 2008 Posted December 11, 2008 Instead of using [ code ] and [ /code ], use [ autoit ] and [ /autoit ] (without the spaces) to format your code in the forum. Autoit tags are totally unreliable and cause a lot of hassle beause when you try to reply to a post which has used them there is a good, but unpredictable, chance that the text will will converted into gibberish. They have irritated me so many times that they feature in my signature. Everyone who uses AutoIt tags should have had every hair below their neck pulled out one at a time, slowly. Better make that only on one side so they can still be punished if they do it again. Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
charvi Posted December 11, 2008 Author Posted December 11, 2008 (edited) I studied Melba23 script... Looks good, I added a working example. expandcollapse popup#include <GDIPlus.au3> #include <Array.au3> $hGUI = GUICreate("", 800, 800, 800, 10) GUISetState() Global $aArray[4], $sX ; single line example =========================== $sX = "Thank you Melba23 for the your script!" $aArray = _Label_Size_Test($sX,12,"Times New Roman") _ArrayDisplay($aArray) GUISetFont(12,400,1,"Times New Roman") GUICtrlCreateLabel($sX,10,10,$aArray[2],$aArray[1]) GUICtrlSetBkColor(-1, 0xff0080) Sleep(2000) ; multi line example ============================ $sX = "Martin says: Do not use [AutoIt] tag in the forum as it seems to be sometimes problematic, use [code] tag instead." & @CRLF & "A pity, really, because the [code] tag does not display the colours..." $aArray = _Label_Size_Test($sX,10,"Tahoma",200) _ArrayDisplay($aArray) GUISetFont(10,400,1,"Tahoma") GUICtrlCreateLabel($sX,10,110,$aArray[2],$aArray[3]) GUICtrlSetBkColor(-1, 0xff0080) Sleep(3000) Exit ; #FUNCTION# ======================================================================================= ; Name............: _Label_Size ; Description ....: Returns the size of label required for a given text, even if wrapped to a width ; Syntax..........: _Label_Size($sText, $iFont_Size, $sFont_Name[, $iWidth]) ; Parameters .....: $sText -> The text to display with @CRLF line endings ; $iFont_Size -> The font size in points ; $sFont_Name -> The font name ; $iWidth -> The max width of the label - default is width of desktop ; Requirement(s)..: v3.2.12.1 or higher ; Return values ..: Success: Returns an array giving details of the label needed to hold the text ; $array[0] = Number of unwrapped lines in $sText ; $array[1] = Height of 1 line of text ; $array[2] = Width of label required to hold text ; $array[3] = Height of label required to hold text ; Failure: Returns 0 ; - Error 1 - Failure to create GUI to test label size ; - Error 2 - GDI measure string failure ; Author .........: Melba23, based on some original GDI code by Malkey ; Example.........; Yes ;=================================================================================================== Func _Label_Size_Test($sText, $iFont_Size, $sFont_Name, $iWidth = @DesktopWidth) Local $hGUI, $hLabel, $hWin, $hGraphic, $hFamily, $hGDIFont, $hFormat, $tLayout, $iMessage_Depth Local $nGDI_Line, $iDiv_Count, $iGDI_Count, $iDiv_Depth, $iGDI_Depth Local $aLines[1], $aPos[4], $aInfo[3] ; Create GUI $hGUI = GUICreate("", 800, 1000, 800, 10) If $hGUI = 0 Then Return SetError(1, 0, 0) GUISetFont($iFont_Size, 400, 0, $sFont_Name) ; Break text into lines $aLines = StringSplit($sText, @CRLF, 1) ;Now fill with unwrapped lines to check on max width $hLabel = GUICtrlCreateLabel($sText, 10, 10) $aPos = ControlGetPos($hGUI, "", $hLabel) ; Store number of lines and line height for this font size $aPos[0] = $aLines[0] ; Remove label padding (8) $aPos[1] = ($aPos[3] - 8)/ $aLines[0] ; Now see if wrapping is required If $aPos[2] > $iWidth Then ; Set width element to max allowed $aPos[2] = $iWidth $hWin = WinGetHandle("[ACTIVE]") _GDIPlus_Startup() $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hWin) $hFamily = _GDIPlus_FontFamilyCreate($sFont_Name) $hGDIFont = _GDIPlus_FontCreate($hFamily, $iFont_Size) $hFormat = _GDIPlus_StringFormatCreate() ; Get GDI line height $tLayout = _GDIPlus_RectFCreate(0, 0, @DesktopWidth, @DesktopHeight) $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, "X", $hGDIFont, $tLayout, $hFormat) ; Remove GDI padding (2) $nGDI_Line = DllStructGetData($aInfo[0], 4) - 2 ; Set line counts to zero $iDiv_Count = 0 $iGDI_Count = 0 ; Take each line in turn For $j = 1 To $aLines[0] ; Replace blank lines to get valid GDI drawing If StringLen($aLines[$j]) = 0 Then $aLines[$j] = "X" ; GDI width method ; Reset the GDI width to desktop $tLayout = _GDIPlus_RectFCreate(0, 0, @DesktopWidth, @DesktopHeight) ; Draw the line unwrapped $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $aLines[$j], $hGDIFont, $tLayout, $hFormat) If Not IsArray($aInfo) Then GUIDelete($hGUI) Return SetError(2, 0, 0) EndIf ; Divide GDI width by max width $nDiv_Lines = DllStructGetData($aInfo[0], 3) / $iWidth ; Make adjustment to allow for lines which end right on the edge If Mod(DllStructGetData($aInfo[0], 3), $iWidth + 8) > .1 Then $nDiv_Lines += 1 $iDiv_Count += Int($nDiv_Lines) ; GDI Depth method - only used to check mono fonts If $sFont_Name = "Courier New" Or $sFont_Name = "Lucida Console" Then ; Limit the GDI width to max allowed $tLayout = _GDIPlus_RectFCreate(0, 0, $iWidth, @DesktopHeight) ; Draw the line which wraps if required $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $aLines[$j], $hGDIFont, $tLayout, $hFormat) If Not IsArray($aInfo) Then GUIDelete($hGUI) Return SetError(2, 0, 0) EndIf ; Divide GDI depth by line depth $iGDI_Count += Int(DllStructGetData($aInfo[0], 4) / $nGDI_Line) EndIf Next _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_FontDispose($hGDIFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() ; Convert lines to pixels $iDiv_Depth = 8 + Int($iDiv_Count) * $aPos[1] $aPos[3] = $iDiv_Depth $iGDI_Depth = 8 + Round($iGDI_Count) * $nGDI_Line ; Adjust if significant difference between methods for mono fonts If $iGDI_Depth - $iDiv_Depth > $aPos[1] / 2 Then $aPos[3] += $aPos[1] / 2 ; Note: $iGDI_Depth is only 8 if not mono font, so no need to check font type EndIf ; Clean up GUIDelete($hGUI) ; Return array Return $aPos EndFunc; => _Label_Size Edited December 11, 2008 by charvi
Moderators Melba23 Posted December 15, 2008 Moderators Posted December 15, 2008 Charvi, I have a fully working script for label sizing in the Example Scripts area here. Hope it does what you want. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now