Mbee Posted June 20, 2016 Share Posted June 20, 2016 (edited) Honored Melba23, I once again beseech you for your assistance, please! I'm trying to use your wondrous StringSize() sorta in reverse: Given a font, size, weight, etc, what's the max # of characters that will fit in a given pixel width? Of course I realize that except for mono-spaced fonts, the result will depend on a specific string itself. but I've tried to compromize by submitting a string consisting of a number of the widest character I can think of, the capital "M" (at least for ANSI Latin alphabets). Here's a simple app I wrote to try it.. expandcollapse popup#include <GUIConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <Array.au3> #include <Constants.au3> #include <StaticConstants.au3> #include <Misc.au3> #include <String.au3> #include <StringConstants.au3> #include <GDIPlus.au3> #include <GDIPlusConstants.au3> #include <StructureConstants.au3> #include <FontConstants.au3> #include <WinAPI.au3> #include "StringSize.au3" Opt("MustDeclareVars", 0) Const $Cmy_DefaultPathFontName="Franklin Gothic Medium Cond", $Cmy_DefaultPathFontSize="9", $Cmy_DefaultPathFontWeight="400" Const $Cmy_DefaultPathFontAttrib="0" Const $Cmy_NicknameFontName="Lucida Console", $Cmy_NicknameFontSize="11", $Cmy_NicknameFontWeight="400" Const $Cmy_NicknameFontAttrib="2" Const $Cmy_SlotPathFontCode = 1, $Cmy_SlotNicknameFontCode = 2, $Cmy_MaxBtnPathTxtLen = 90, $Cmy_MaxBtnNickTxtLen = 38 Local $ResultAra[4], $MaxLenResults[4], $ErrFound Local $FontInfo[4][6] = [ [ "Pathnames in Nickname Slots", 9, 400, 0, "Franklin Gothic Medium Cond", 305], _ [ "Nicknames in Nickname Slots", 11, 400, 2, "Lucida Console", 305], _ [ "Pathname under Picture", 11, 400, 0, "Gentium Book Basic", 730], _ [ "Notify String", 11, 700, 0, "High Tower Text", 500] ] $ErrFound = False ; For $i = 0 To 3 $MaxPixelLenSoFar = 0 $MaxCharLenSoFar = 1 $TestStrSoFar = "M" $GotMaxChars = False While (Not $GotMaxChars) And (Not $ErrFound) $ResultAra = _StringSize($TestStrSoFar, $FontInfo[$i][1], $FontInfo[$i][2], $FontInfo[$i][3], $FontInfo[$i][4], $FontInfo[$i][5]) If @error = 0 Then $RequiredPixelWidth = $ResultAra[2] If $RequiredPixelWidth < $FontInfo[$i][5] Then ; If we've still got room... $TestStrSoFar &= "M" $MaxCharLenSoFar += 1 Else $ResultAra[$i] = $MaxCharLenSoFar $GotMaxChars = True EndIf Else MsgBox($MB_OK, "StringSizeMaxTest Error", "Error: _StringSize() @error Returned: " & @error) $ErrFound = True Exit EndIf WEnd Next ; For $i = 0 To 3 MsgBox($MB_OK, "StringSizeMaxTest Results", "Max # chars for " & $FontInfo[$i][0] & " == " & $ResultAra[$i] ) Next ; MsgBox($MB_OK, "StringSizeMaxTest Results", "Press OK when ready") Exit What happens is the app always reports error 3: "GetDeviceCaps failure", from StringSize(). What's that all about? Thanks! Edited June 23, 2016 by Mbee Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted June 20, 2016 Moderators Share Posted June 20, 2016 (edited) Mbee, Error 3 is not "GetDeviceCaps failure" but something quite different: Quote Failure - Returns 0 and sets @error: 3 - Font too large for chosen max width - a word will not fit which is exactly the error I would expect to see once the string become too long to fit in the defined width. Let me take a look at the code - although I doubt I have some of those fonts. M23 Edited June 20, 2016 by Melba23 Expanded comments Mbee 1 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 Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted June 20, 2016 Moderators Share Posted June 20, 2016 Mbee, If you get the checking logic correct in the loop the UDF seems to provide sensible results: #include <Array.au3> #include "StringSize.au3" Opt("MustDeclareVars", 0) Local $ResultAra[4] Local $FontInfo[4][6] = [["Pathnames in Nickname Slots", 9, 400, 0, "Arial", 305], _ ["Nicknames in Nickname Slots", 11, 400, 2, "Lucida Console", 305], _ ["Pathname under Picture", 11, 400, 0, "Consolas", 730], _ ["Notify String", 11, 700, 0, "Times New Roman", 500]] For $i = 0 To 3 $TestStrSoFar = "" Do $TestStrSoFar &= "M" _StringSize($TestStrSoFar, $FontInfo[$i][1], $FontInfo[$i][2], $FontInfo[$i][3], $FontInfo[$i][4], $FontInfo[$i][5]) Until @error $ResultAra[$i] = StringLen($TestStrSoFar) - 1 Next _ArrayDisplay($ResultAra, "", Default, 8) The suggested values for max character counts seem perfectly reasonable to me. M23 Mbee 1 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 Link to comment Share on other sites More sharing options...
Mbee Posted June 20, 2016 Author Share Posted June 20, 2016 Thanks again, Melba23! I apologize for mis-reading the error return description in StringSize! Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted June 20, 2016 Moderators Share Posted June 20, 2016 Mbee, Glad I could help. 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 Link to comment Share on other sites More sharing options...
Mbee Posted June 20, 2016 Author Share Posted June 20, 2016 Revised, working code if someone else wants this info... expandcollapse popup#include <FontConstants.au3> #include <WinAPI.au3> #include "StringSize.au3" Opt("MustDeclareVars", 0) Const $Cmy_DefaultPathFontName="Franklin Gothic Medium Cond", $Cmy_DefaultPathFontSize="9", $Cmy_DefaultPathFontWeight="400" Const $Cmy_DefaultPathFontAttrib="0" Const $Cmy_NicknameFontName="Lucida Console", $Cmy_NicknameFontSize="11", $Cmy_NicknameFontWeight="400" Const $Cmy_NicknameFontAttrib="2" Const $Cmy_SlotPathFontCode = 1, $Cmy_SlotNicknameFontCode = 2, $Cmy_MaxBtnPathTxtLen = 90, $Cmy_MaxBtnNickTxtLen = 38 Local $ResultAra[4], $MaxLenResults[4], $ErrFound Local $FontInfo[4][6] = [ [ "Pathnames in Nickname Slots", 9, 400, 0, "Franklin Gothic Medium Cond", 305], _ [ "Nicknames in Nickname Slots", 11, 400, 2, "Lucida Console", 305], _ [ "Pathname under Picture", 11, 400, 0, "Gentium Book Basic", 730], _ [ "Notify String", 11, 700, 0, "High Tower Text", 500] ] $ErrFound = False ; For $i = 0 To 3 $MaxPixelLenSoFar = 0 $MaxCharLenSoFar = 1 $TestStrSoFar = "M" $GotMaxChars = False While (Not $GotMaxChars) And (Not $ErrFound) $ResultAra = _StringSize($TestStrSoFar, $FontInfo[$i][1], $FontInfo[$i][2], $FontInfo[$i][3], $FontInfo[$i][4], $FontInfo[$i][5]) If @error = 0 Then $RequiredPixelWidth = $ResultAra[2] If $RequiredPixelWidth < $FontInfo[$i][5] Then ; If we've still got room... $TestStrSoFar &= "M" $MaxCharLenSoFar += 1 Else $MaxLenResults[$i] = $MaxCharLenSoFar $GotMaxChars = True EndIf Else If @error = 3 Then $MaxLenResults[$i] = $MaxCharLenSoFar $GotMaxChars = True Else MsgBox($MB_OK, "StringSizeMaxTest Error", "Error: _StringSize() @error Returned: " & @error) $ErrFound = True Exit EndIf EndIf WEnd Next ; For $i = 0 To 3 MsgBox($MB_OK, "StringSizeMaxTest Results", "Max # chars for " & $FontInfo[$i][0] & " = " & $MaxLenResults[$i] ) Next ; MsgBox($MB_OK, "StringSizeMaxTest Results", "Press OK when ready") Exit Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted June 20, 2016 Moderators Share Posted June 20, 2016 Mbee, Why are you using an even more convoluted mess when I posted a much simpler script which produced exactly the same results? 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 Link to comment Share on other sites More sharing options...
Mbee Posted June 23, 2016 Author Share Posted June 23, 2016 (edited) Sorry! The thing is, I personally hate _ArrayDisplay() (just a personal thing, if you will). How's this? #include <Array.au3> #include "StringSize.au3" Opt("MustDeclareVars", 0) Const $CMy_NumFontsToTest = 5 Local $ResultAra[$CMy_NumFontsToTest], $DispStr Local $FontInfo[$CMy_NumFontsToTest][6] = [ _ ["Pathnames in Nickname Slots", 9, 400, 0, "Franklin Gothic Medium Cond", 305], _ ["Nicknames in Nickname Slots", 11, 400, 2, "Lucida Console", 305], _ ["Pathname under Picture", 11, 400, 0, "Gentium Book Basic", 780], _ ["Notify String", 11, 700, 0, "High Tower Text", 780], _ ["Profile ID String", 12, 700, 0, "Calibri", 601] ] For $i = 0 To $CMy_NumFontsToTest -1 $TestStrSoFar = "" Do $TestStrSoFar &= "M" _StringSize($TestStrSoFar, $FontInfo[$i][1], $FontInfo[$i][2], $FontInfo[$i][3], $FontInfo[$i][4], $FontInfo[$i][5]) Until @error $ResultAra[$i] = StringLen($TestStrSoFar) - 1 Next ; $DispStr = "" For $i = 0 To $CMy_NumFontsToTest -1 $DispStr &= "Max Chars for: " & $FontInfo[$i][0] & " = " & $ResultAra[$i] & @CRLF Next ; ClipPut( $DispStr ) MsgBox($MB_SYSTEMMODAL, "StringSizeMaxTest Results", $DispStr ) Exit The last value in each row of the $FontInfo array is set to the width in pixels of the label or other text control I'll be setting whatever text into. I set those values up and then run this trivial little tool (which saves the results in the clipboard for saving in a text file if wanted) so that I can know the values to pre-set for use in a function that uses your StringSize() func to adjust whatever string I want to put into a given text control to fit into the allotted pixel width. I use those calculated values to pass as the fourth parameter in that function, which I call _AdjStringToFit(), which follows (the version below is stripped of some basic optimizing code which avoided the loop if AdjStringToFit is called consecutively with the same first arguement): expandcollapse popup#include-once #include "StringSize.au3" ; #INDEX# ============================================================================================================ ; Title .........: _AdjStringToFit ; AutoIt Version : v3.2.12.1 or higher ; Language ......: English ; Description ...: Returns a string representing the input string that's adjusted in order to fit into a specified ; text field, given the specific width (in pixels) of the desired text field. ; Remarks .......: If the input string is too long for that given width, it can be prefixed with a string which would indicate ; that it has been truncated. Common options for this prefix are either a drive letter (with initial ; backslash) followed by an elipsis (or three period characters) for truncated path strings, or just an elipsis ; (or three period characters) for a general purpose truncated string. ; Note ..........: ; Author(s) .....: MBee - Huge thanks to Melba23 for the StringSize function ; ==================================================================================================================== ; #FUNCTION# ========================================================================================================= ; Name...........: _AdjStringToFit ; ; Description ...: Returns a string representing the input string that's adjusted in order to fit into a specified ; text field, given the specific width (in pixels) of the desired text field. ; ; Syntax ........: _AdjStringToFit($sText, $sPrefix, $iWidth, $iAlwaysFitCCount, $iSize, $iWeight, $iAttrib, $sName ) ; ; Parameters ....: $sText - Desired string to be optionally adjusted ; $sPrefix - Prefix string to insert to indicate the string has been adjusted ; $iWidth - The width in pixels of the intended text field ; $iAlwaysFitCCount - The max number of characters that will always fit in the specified field ; i.e., any string with this # chars or fewer will never have to be adjusted ; $iSize - [optional] Font size in points - (default = 8.5) ; $iWeight - [optional] Font weight - (default = 400 = normal) ; $iAttrib - [optional] Font attribute (0-Normal (default), 2-Italic, 4-Underline, 8 Strike) ; $sName - [optional] Font name - (default = Tahoma) ; ; Requirement(s) : v3.2.12.1 or higher ; ; Return values .: Success - The possibly adjusted input string with optional prefix inserted that will fit in the field ; @error will be set to 0 ; ; Failure - Returns null string ("") & @error and @extended from error return from StringSize ; ; Author ........: MBee - Thanks to Melba23 for the StringSize function ; Modified ......: ; Remarks .......: ; Related .......: StringSize() ; Link ..........: ; Example .......: No Func _AdjStringToFit($arg_TestStr, $arg_Prefix, $arg_FieldSize, $arg_NoAdjCharCount, $arg_FSize=8.5, $arg_FWeight=400, _ $arg_FAttrib=0, $arg_FName="Tahoma") Local $Lf_ResAra[4], $Lf_WorkStr, $Lf_AdjustedStr, $Lf_WillFit, $Lf_FirstPass, $Lf_TestStrLen=StringLen($arg_TestStr) ; $Lf_WorkStr = $arg_TestStr $Lf_AdjustedStr = $arg_TestStr $Lf_FirstPass = True $Lf_WillFit = False ; Assume string is too long to display Do $Lf_ResAra = _StringSize( $Lf_WorkStr, $arg_FSize, $arg_FWeight, $arg_FAttrib, $arg_FName, $arg_FieldSize ) If @error = 0 Then If StringInStr( $Lf_ResAra[0], @CR ) = 0 Then ; It'll fit $Lf_WillFit = True ExitLoop EndIf Else If @error <> 3 Then ; If an error other than "string won't fit in field" then Return "" ; Pass back Melba23's @error EndIf EndIf ; If $Lf_FirstPass Then $Lf_AdjustedStr = StringRight( $Lf_AdjustedStr, StringLen($Lf_AdjustedStr) - (StringLen($arg_Prefix) -1) ) $Lf_FirstPass = False Else $Lf_AdjustedStr = StringRight( $Lf_AdjustedStr, StringLen($Lf_AdjustedStr) -1 ) EndIf ; $Lf_WorkStr = $arg_Prefix & $Lf_AdjustedStr If $Lf_WorkStr = $arg_Prefix Then ; Once we've stripped down to nothing but the prefix, give up SetError(2, 0) Return "" EndIf Until $Lf_WillFit ; SetError(0, 0) Return $Lf_WorkStr EndFunc I followed the traditional naming conventions in the function headers, but followed my own preferred naming conventions in the actual code (Inot to criticize the traditional AutoIt standards, but I've been using my naming conventions for a very long time, and since AutoIt is wonderfully not a strongly-typed programming language, prefixing variable names with the variable type seems a bit needless when this can be as well accomplished in the later parts of the variable names... Just one man's personal opinion...) As always, I am willing to accept criticism and/or suggestions for improvements. Edited June 24, 2016 by Mbee Re-inserted critical missing code line Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted June 23, 2016 Moderators Share Posted June 23, 2016 Mbee, That looks a lot cleaner. 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 Link to comment Share on other sites More sharing options...
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