Jump to content

tcurran

Active Members
  • Posts

    36
  • Joined

  • Last visited

Reputation Activity

  1. Like
    tcurran got a reaction from maniootek in Plain text (HTML) to Formatted (HTML) Text for clipboard   
    I realize this is an old, dead thread, but in case anyone comes searching here, I believe this is what MikeMan27294 was looking for:

    _ClipPutHTML https://sites.google.com/site/ascend4ntscode/clipputhtml
  2. Thanks
    tcurran got a reaction from zeenmakr in Pixel-accurate string width and height   
    Here are two functions to provide pixel-accurate height and width dimensions for a given string.
    The more commonly-used _GDIPlus_GraphicsMeasureString built-in UDF is problematic because it returns the width padded by roughly one en-space (for reasons related to the various ways Windows produces anti-aliased fonts).
    These are AutoIt translations of Pierre Arnaud's C# functions, described in his CodeProject article "Bypass Graphics.MeasureString limitations"
    The first is an all-purpose version that takes a window handle, string, font family, font size (in points), style, and (optionally) width of the layout column (in pixels) as parameters.
    The second, more efficient version is intended for applications where GDI+ fonts are already in use, and takes handles to the existing graphics context, string, font, layout and format as parameters.
    Both functions return a two-row array with the exact width [0] and height [1] of the string (in pixels).
    EDIT: (Note that some of the same anti-aliasing measurement issues still apply. I did my best to work around them, but the output of the function may still be off by a pixel or two. Buyer beware.)
    #include <GDIPlus.au3> #include <GUIConstantsEx.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StringInPixels ; Description ...: Returns a pixel-accurate height and width for a given string using a given font, style and size. ; Syntax ........: _StringInPixels($hGUI, $sString, $sFontFamily, $fSize, $iStyle[, $iColWidth = 0]) ; Parameters ....: $hGUI - Handle to the window. ; $sString - The string to be measured. ; $sFontFamily - Full name of the font to use. ; $fSize - Font size in points (half-point increments). ; $iStyle - Combination of 0-normal, 1-bold, 2-italic, 4-underline, 8-strikethrough ; $iColWidth - [optional] If word-wrap is desired, column width in pixels ; Return values .: 2-row array. [0] is width in pixels; [1] is height in pixels. ; Author ........: Tim Curran; adapted from Pierre Arnaud's C# function ; Modified ......: ; Remarks .......: This version is longer and less efficient but works for all purposes. ; Related .......: <https://www.codeproject.com/Articles/2118/Bypass-Graphics-MeasureString-limitations> ; Link ..........: ; Example .......: Example-StringInPixels.au3 ; =============================================================================================================================== #include <GDIPlus.au3> #include <GUIConstantsEx.au3> Func _StringInPixels($hGUI, $sString, $sFontFamily, $fSize, $iStyle, $iColWidth = 0) _GDIPlus_Startup() Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;Create a graphics object from a window handle Local $aRanges[2][2] = [[1]] $aRanges[1][0] = 0 ;Measure first char (0-based) $aRanges[1][1] = StringLen($sString) ;Region = String length Local $hFormat = _GDIPlus_StringFormatCreate() Local $hFamily = _GDIPlus_FontFamilyCreate($sFontFamily) Local $hFont = _GDIPlus_FontCreate($hFamily, $fSize, $iStyle) _GDIPlus_GraphicsSetTextRenderingHint($hGraphic, $GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT) _GDIPlus_StringFormatSetMeasurableCharacterRanges($hFormat, $aRanges) ;Set ranges Local $aWinClient = WinGetClientSize($hGUI) If $iColWidth = 0 Then $iColWidth = $aWinClient[0] Local $tLayout = _GDIPlus_RectFCreate(10, 10, $iColWidth, $aWinClient[1]) Local $aRegions = _GDIPlus_GraphicsMeasureCharacterRanges($hGraphic, $sString, $hFont, $tLayout, $hFormat) ;get array of regions Local $aBounds = _GDIPlus_RegionGetBounds($aRegions[1], $hGraphic) Local $aWidthHeight[2] = [$aBounds[2], $aBounds[3]] ; Clean up resources _GDIPlus_FontDispose($hFont) _GDIPlus_RegionDispose($aRegions[1]) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() Return $aWidthHeight EndFunc ;==>_StringInPixels ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StringInPixels_gdip ; Description ...: Returns a pixel-accurate height and width for a given string using a GDI+ font, layout and format ; Syntax ........: _StringInPixels_gdip($hGraphic, $sString, $hFont, $tLayout, $hFormat) ; Parameters ....: $hGraphic - Handle to a GDI+ graphics object. ; $sString - The string to be measured. ; $hFont - Handle to a GDI+ font. ; $tLayout - A $tagGDIPRECTF structure that bounds the string. ; $hFormat - Handle to a GDI+ string format. ; Return values .: 2-row array. [0] is width in pixels; [1] is height in pixels. ; Author ........: Tim Curran; adapted from Pierre Arnaud's C# function ; Modified ......: ; Remarks .......: This much more efficient version is for use with GDI+ fonts ; Related .......: ; Link ..........: <https://www.codeproject.com/Articles/2118/Bypass-Graphics-MeasureString-limitations> ; Example .......: Example-StringInPixels.au3 ; =============================================================================================================================== #include <GDIPlus.au3> #include <GUIConstantsEx.au3> Func _StringInPixels_gdip($hGraphic, $sString, $hFont, $tLayout, $hFormat) Local $aRanges[2][2] = [[1]] $aRanges[1][0] = 0 ;Measure first char (0-based) $aRanges[1][1] = StringLen($sString) ;Region = String length _GDIPlus_GraphicsSetTextRenderingHint($hGraphic, $GDIP_TEXTRENDERINGHINT_CLEARTYPEGRIDFIT) _GDIPlus_StringFormatSetMeasurableCharacterRanges($hFormat, $aRanges) ;Set ranges Local $aRegions = _GDIPlus_GraphicsMeasureCharacterRanges($hGraphic, $sString, $hFont, $tLayout, $hFormat) ;get array of regions Local $aBounds = _GDIPlus_RegionGetBounds($aRegions[1], $hGraphic) Local $aWidthHeight[2] = [$aBounds[2], $aBounds[3]] _GDIPlus_RegionDispose($aRegions[1]) Return $aWidthHeight EndFunc ;==>_StringInPixels_gdip  
    _StringInPixels.au3
    Example-StringInPixels.au3
  3. Like
    tcurran got a reaction from coffeeturtle in UDF for Title Case, Initial Caps, and Sentence Case   
    This UDF is intended to improve on the existing _StringProper UDF by using the magic of regular expressions (don't worry, it protects the user from having to know anything about RegEx). In addition to avoiding some of the anomalies associated with _StringProper (such as a cap following each apostrophe--Susan'S Farm), it provides additional functionality:
    Sentence Case: Only the first word of each sentence (following a period, question mark, exclamation point or colon) is capitalized. Title Case: Initial caps for all words except articles (a, the) and some common conjunctions (and, but) and prepositions (in, on). While the actual rules for capitalizing authored works would require hundreds of lines of code and still not be perfect, this will suffice for most uses. Capitalization Exceptions: Permits user selectable exceptions to the default scheme. Mac (as in MacDonald), Mc, and O' are the defaults, but users can pass their own exceptions in an easy-to-use function parameter. I've chosen not to use the term "Proper Case" in the function at all, because a) there are varying opinions about what it means, b ) my equivalent (termed "Initial Caps") works somewhat differently (i.e. better ), and c) "Proper Case" as used in other applications (e.g. Excel) works (or doesn't work) the same as _StringProper in AutoIt.
    I'm posting _StringChooseCase here in hopes of getting some feedback and squashing any bugs I've missed prior to submitting it as a candidate for inclusion as a standard AutoIt UDF.

    UPDATE (3 Jan 2013): I removed the hack noted below using a more bullet-proof method of marking capitalization exceptions, inspired by dany's _StringRegExpSplit function. Also added the colon character as sentence punctuation, and added II, III & IV as default cap exceptions.

    UPDATE (9 Jan 2013): The code is a hair more efficient. #include-once and #include <array.au3> now appear where they're supposed to. "I" is now always capitalized (both as the first person pronoun and the Roman numeral one). Title Case further improved: It now has a more comprehensive list of lower-case words--mainly more prepositions--and the last word of a title will always be capitalized.


    #include-once #include <Array.au3> ;_ArrayToString UDF used in Return ; #FUNCTION# ==================================================================================================================== ; Name...........: _StringChooseCase ; Description ...: Returns a string in the selected upper & lower case format: Initial Caps, Title Case, or Sentence Case ; Syntax.........: _StringChooseCase($sMixed, $iOption[, $sCapExcepts = "Mc^|Mac^|O'^|II|III|IV"]) ;PROSPECTIVE: add param for Ignore mixed case input ; Parameters ....: $sMixed - String to change capitalization of. ; $iOption - 1: Initial Caps: Capitalize Every Word; ; 2: Title Case: Use Standard Rules for the Capitalization of Work Titles; ; 3: Sentence Case: Capitalize as in a sentence. ; $sCapExcepts - [optional] Exceptions to capitalizing set by options, delimited by | character. Use the ^ ; character to cause the next input character (whatever it is) to be capitalized ; Return values .: Success - Returns the same string, capitalized as selected. ; Failure - "" ; Author ........: Tim Curran <tim at timcurran dot com> ; Remarks .......: Option 1 is similar to standard UDF _StringProper, but avoids anomalies like capital following an apostrophe ; Related .......: _StringProper, StringUpper, StringLower ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _StringChooseCase(ByRef $sMixed, $iOption, $sCapExcepts = "Mc^|Mac^|O'^|I|II|III|IV") Local $asSegments, $sTrimtoAlpha, $iCapPos = 1 $sMixed = StringLower($sMixed) Switch $iOption Case 1 ;Initial Caps $asSegments = StringRegExp($sMixed, ".*?(?:\s|\Z)", 3) ;break by word Case 2 ;Title Case $asSegments = StringRegExp($sMixed, ".*?(?:\s|\Z)", 3) ;break by word Case 3 ;Sentence Case $asSegments = StringRegExp($sMixed, ".*?(?:\.\W*|\?\W*|\!\W*|\:\W*|\Z)", 3) ;break by sentence EndSwitch Local $iLastWord = UBound($asSegments) - 2 For $iIndex = 0 to $iLastWord ;Capitalize the first letter of each element in array $sTrimtoAlpha = StringRegExp($asSegments[$iIndex], "\w.*", 1) If @error = 0 Then $iCapPos = StringInStr($asSegments[$iIndex], $sTrimtoAlpha[0]) If $iOption <> 2 Or $iIndex = 0 Then ;Follow non-cap rules for Title Case if option selected (including cap last word) $asSegments[$iIndex] = StringReplace($asSegments[$iIndex], $iCapPos, StringUpper(StringMid($asSegments[$iIndex], $iCapPos, 1))) ElseIf $iIndex = $iLastWord Or StringRegExp($asSegments[$iIndex], "\band\b|\bthe\b|\ba\b|\ban\b|\bbut\b|\bfor\b|\bor\b|\bin\b|\bon\b|\bfrom\b|\bto\b|\bby\b|\bover\b|\bof\b|\bto\b|\bwith\b|\bas\b|\bat\b", 0) = 0 Then $asSegments[$iIndex] = StringReplace($asSegments[$iIndex], $iCapPos, StringUpper(StringMid($asSegments[$iIndex], $iCapPos, 1))) EndIf ;Capitalization exceptions $asSegments[$iIndex] = _CapExcept($asSegments[$iIndex], $sCapExcepts) Next Return _ArrayToString($asSegments, "") EndFunc ;==> _StringChooseCase Func _CapExcept($sSource, $sExceptions) Local $sRegExaExcept, $iMakeUCPos Local $avExcept = StringSplit($sExceptions, "|") For $iIndex = 1 to $avExcept[0] $sRegExaExcept = "(?i)\b" & $avExcept[$iIndex] $iMakeUCPos = StringInStr($avExcept[$iIndex], "^") If $iMakeUCPos <> 0 Then $sRegExaExcept = StringReplace($sRegExaExcept, "^", "") Else $sRegExaExcept &= "\b" EndIf $avExcept[$iIndex] = StringReplace($avExcept[$iIndex], "^", "") ;remove ^ from replacement text $sSource = StringRegExpReplace($sSource, $sRegExaExcept, $avExcept[$iIndex]) If $iMakeUCPos <> 0 Then Local $iNextUC = _StringRegExpPos($sSource, $sRegExaExcept) Local $iMatches = @extended Local $iCapThis = $iNextUC + $iMakeUCPos For $x = 1 to $iMatches $sSource = StringLeft($sSource, $iCapThis - 2) & StringUpper(StringMid($sSource, $iCapThis - 1, 1)) & StringMid($sSource, $iCapThis) Next EndIf Next Return $sSource EndFunc ;==> _CapExcept Func _StringRegExpPos($sTest, $sPattern, $iOcc = 1, $iStart = 1) Local $sDelim, $iHits If $iStart > StringLen($sTest) Then Return SetError(1) ;Delimiter creation snippet by dany from his version of _StringRegExpSplit For $i = 1 To 31 $sDelim &= Chr($i) If Not StringInStr($sTest, $sDelim) Then ExitLoop If 32 = StringLen($sDelim) Then Return SetError(3, 0, 0) Next Local $aResults = StringRegExpReplace(StringMid($sTest, $iStart + (StringLen($sDelim) * ($iOcc - 1))), "(" & $sPattern & ")", $sDelim & "$1") If @error = 2 Then Return SetError(2, @extended, 0) $iHits = @extended If $iHits = 0 Then Return 0 If $iOcc > $iHits Then Return SetError(1) Local $iPos = StringInStr($aResults, $sDelim, 0, $iOcc) SetExtended($iHits) Return $iStart - 1 + $iPos EndFunc ;<== _StringRegExpPos
    Here's a bit of sample code:

    EDIT (16 Jan 2013): Corrected format of #include to use quotation marks instead of angle brackets.


    #Include "_StringChooseCase.au3" Global $test = "'abcdefghi now it's 'the time for all good men.' 'AND TWELVE MORE MACDONALD'S!'" & @CRLF & "The quick brown fox JUMPED over the lazy MacDonalds. The USA's Usain Bolt ran for the USA." ConsoleWrite(_StringChooseCase($test, 1, "Mc^|Mac^|O'^|USA|FBI|Barack|Obama") & @CRLF) ConsoleWrite(_StringChooseCase('"and the band played on"', 2) & @CRLF)
    Previous downloads: 18
    _StringChooseCase.au3
  4. Like
    tcurran got a reaction from Gianni in Pixel-accurate string width and height   
    Here are two functions to provide pixel-accurate height and width dimensions for a given string.
    The more commonly-used _GDIPlus_GraphicsMeasureString built-in UDF is problematic because it returns the width padded by roughly one en-space (for reasons related to the various ways Windows produces anti-aliased fonts).
    These are AutoIt translations of Pierre Arnaud's C# functions, described in his CodeProject article "Bypass Graphics.MeasureString limitations"
    The first is an all-purpose version that takes a window handle, string, font family, font size (in points), style, and (optionally) width of the layout column (in pixels) as parameters.
    The second, more efficient version is intended for applications where GDI+ fonts are already in use, and takes handles to the existing graphics context, string, font, layout and format as parameters.
    Both functions return a two-row array with the exact width [0] and height [1] of the string (in pixels).
    EDIT: (Note that some of the same anti-aliasing measurement issues still apply. I did my best to work around them, but the output of the function may still be off by a pixel or two. Buyer beware.)
    #include <GDIPlus.au3> #include <GUIConstantsEx.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StringInPixels ; Description ...: Returns a pixel-accurate height and width for a given string using a given font, style and size. ; Syntax ........: _StringInPixels($hGUI, $sString, $sFontFamily, $fSize, $iStyle[, $iColWidth = 0]) ; Parameters ....: $hGUI - Handle to the window. ; $sString - The string to be measured. ; $sFontFamily - Full name of the font to use. ; $fSize - Font size in points (half-point increments). ; $iStyle - Combination of 0-normal, 1-bold, 2-italic, 4-underline, 8-strikethrough ; $iColWidth - [optional] If word-wrap is desired, column width in pixels ; Return values .: 2-row array. [0] is width in pixels; [1] is height in pixels. ; Author ........: Tim Curran; adapted from Pierre Arnaud's C# function ; Modified ......: ; Remarks .......: This version is longer and less efficient but works for all purposes. ; Related .......: <https://www.codeproject.com/Articles/2118/Bypass-Graphics-MeasureString-limitations> ; Link ..........: ; Example .......: Example-StringInPixels.au3 ; =============================================================================================================================== #include <GDIPlus.au3> #include <GUIConstantsEx.au3> Func _StringInPixels($hGUI, $sString, $sFontFamily, $fSize, $iStyle, $iColWidth = 0) _GDIPlus_Startup() Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;Create a graphics object from a window handle Local $aRanges[2][2] = [[1]] $aRanges[1][0] = 0 ;Measure first char (0-based) $aRanges[1][1] = StringLen($sString) ;Region = String length Local $hFormat = _GDIPlus_StringFormatCreate() Local $hFamily = _GDIPlus_FontFamilyCreate($sFontFamily) Local $hFont = _GDIPlus_FontCreate($hFamily, $fSize, $iStyle) _GDIPlus_GraphicsSetTextRenderingHint($hGraphic, $GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT) _GDIPlus_StringFormatSetMeasurableCharacterRanges($hFormat, $aRanges) ;Set ranges Local $aWinClient = WinGetClientSize($hGUI) If $iColWidth = 0 Then $iColWidth = $aWinClient[0] Local $tLayout = _GDIPlus_RectFCreate(10, 10, $iColWidth, $aWinClient[1]) Local $aRegions = _GDIPlus_GraphicsMeasureCharacterRanges($hGraphic, $sString, $hFont, $tLayout, $hFormat) ;get array of regions Local $aBounds = _GDIPlus_RegionGetBounds($aRegions[1], $hGraphic) Local $aWidthHeight[2] = [$aBounds[2], $aBounds[3]] ; Clean up resources _GDIPlus_FontDispose($hFont) _GDIPlus_RegionDispose($aRegions[1]) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() Return $aWidthHeight EndFunc ;==>_StringInPixels ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StringInPixels_gdip ; Description ...: Returns a pixel-accurate height and width for a given string using a GDI+ font, layout and format ; Syntax ........: _StringInPixels_gdip($hGraphic, $sString, $hFont, $tLayout, $hFormat) ; Parameters ....: $hGraphic - Handle to a GDI+ graphics object. ; $sString - The string to be measured. ; $hFont - Handle to a GDI+ font. ; $tLayout - A $tagGDIPRECTF structure that bounds the string. ; $hFormat - Handle to a GDI+ string format. ; Return values .: 2-row array. [0] is width in pixels; [1] is height in pixels. ; Author ........: Tim Curran; adapted from Pierre Arnaud's C# function ; Modified ......: ; Remarks .......: This much more efficient version is for use with GDI+ fonts ; Related .......: ; Link ..........: <https://www.codeproject.com/Articles/2118/Bypass-Graphics-MeasureString-limitations> ; Example .......: Example-StringInPixels.au3 ; =============================================================================================================================== #include <GDIPlus.au3> #include <GUIConstantsEx.au3> Func _StringInPixels_gdip($hGraphic, $sString, $hFont, $tLayout, $hFormat) Local $aRanges[2][2] = [[1]] $aRanges[1][0] = 0 ;Measure first char (0-based) $aRanges[1][1] = StringLen($sString) ;Region = String length _GDIPlus_GraphicsSetTextRenderingHint($hGraphic, $GDIP_TEXTRENDERINGHINT_CLEARTYPEGRIDFIT) _GDIPlus_StringFormatSetMeasurableCharacterRanges($hFormat, $aRanges) ;Set ranges Local $aRegions = _GDIPlus_GraphicsMeasureCharacterRanges($hGraphic, $sString, $hFont, $tLayout, $hFormat) ;get array of regions Local $aBounds = _GDIPlus_RegionGetBounds($aRegions[1], $hGraphic) Local $aWidthHeight[2] = [$aBounds[2], $aBounds[3]] _GDIPlus_RegionDispose($aRegions[1]) Return $aWidthHeight EndFunc ;==>_StringInPixels_gdip  
    _StringInPixels.au3
    Example-StringInPixels.au3
  5. Like
    tcurran got a reaction from Earthshine in AutoIt Snippets   
    This function offers a simple way to roughly calibrate the speed of animations on various computers and OSes. It calculates the number of loops iterated within a given number of milliseconds.
    #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7 Global $iAnimSpeed _SetAnimSpeed() AdlibRegister("_SetAnimSpeed", 300000) ;wait 5 minutes for Windows startup to finish, then every 5 minutes, recalibrate animation speed Func _SetAnimSpeed() $iAnimSpeed = _CalibrateLoopTime(1000, 1) ;get the number of loops within a second with 1 Sleep() ;AdlibUnRegister("_SetAnimSpeed") ;uncomment this line if you only want to recalibrate once EndFunc ;==>_SetAnimSpeed ConsoleWrite("On this computer, 1 second of animation = " & $iAnimSpeed & " for-next loops, including 1 sleep." & @CRLF) ; #FUNCTION# ==================================================================================================================== ; Name ..........: _CalibrateLoopTime ; Description ...: Calculates the number of loops iterated within a given number of milliseconds. A simple way to *roughly* ; calibrate the speed of animations on various computers and OSes. ; Syntax ........: _CalibrateLoopTime($iMilliseconds[, $iSleep = 0]) ; Parameters ....: $iMilliseconds - number of milliseconds to calibrate. Longer is more accurate, shorter is less disruptive. ; Remember to divide or multiply to get the length of the animation. ; $iSleep - [optional] manually adjust this to correct for the how fast animation gets generated. ; Default is 0. ; Return value ..: integer number of loops within given milliseconds ; Author ........: Tim Curran (tim/at/timcurran/dot/com) ; Modified ......: ; Remarks .......: The longer the Sleep() adjustment, the less accurate this calibration, as computer speed performing the task ; (e.g. building the animation) becomes a greater factor. ; Example .......: See above. ; =============================================================================================================================== Func _CalibrateLoopTime($iMilliseconds, $iSleep = 0) Local $iLoopCounter, $hCaliTimer $hCaliTimer = TimerInit() Do $iLoopCounter += 1 Sleep($iSleep) Until TimerDiff($hCaliTimer) >= $iMilliseconds Return $iLoopCounter EndFunc ;==>_CalibrateLoopTime  
  6. Like
    tcurran got a reaction from Danyfirex in Pixel-accurate string width and height   
    Here are two functions to provide pixel-accurate height and width dimensions for a given string.
    The more commonly-used _GDIPlus_GraphicsMeasureString built-in UDF is problematic because it returns the width padded by roughly one en-space (for reasons related to the various ways Windows produces anti-aliased fonts).
    These are AutoIt translations of Pierre Arnaud's C# functions, described in his CodeProject article "Bypass Graphics.MeasureString limitations"
    The first is an all-purpose version that takes a window handle, string, font family, font size (in points), style, and (optionally) width of the layout column (in pixels) as parameters.
    The second, more efficient version is intended for applications where GDI+ fonts are already in use, and takes handles to the existing graphics context, string, font, layout and format as parameters.
    Both functions return a two-row array with the exact width [0] and height [1] of the string (in pixels).
    EDIT: (Note that some of the same anti-aliasing measurement issues still apply. I did my best to work around them, but the output of the function may still be off by a pixel or two. Buyer beware.)
    #include <GDIPlus.au3> #include <GUIConstantsEx.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StringInPixels ; Description ...: Returns a pixel-accurate height and width for a given string using a given font, style and size. ; Syntax ........: _StringInPixels($hGUI, $sString, $sFontFamily, $fSize, $iStyle[, $iColWidth = 0]) ; Parameters ....: $hGUI - Handle to the window. ; $sString - The string to be measured. ; $sFontFamily - Full name of the font to use. ; $fSize - Font size in points (half-point increments). ; $iStyle - Combination of 0-normal, 1-bold, 2-italic, 4-underline, 8-strikethrough ; $iColWidth - [optional] If word-wrap is desired, column width in pixels ; Return values .: 2-row array. [0] is width in pixels; [1] is height in pixels. ; Author ........: Tim Curran; adapted from Pierre Arnaud's C# function ; Modified ......: ; Remarks .......: This version is longer and less efficient but works for all purposes. ; Related .......: <https://www.codeproject.com/Articles/2118/Bypass-Graphics-MeasureString-limitations> ; Link ..........: ; Example .......: Example-StringInPixels.au3 ; =============================================================================================================================== #include <GDIPlus.au3> #include <GUIConstantsEx.au3> Func _StringInPixels($hGUI, $sString, $sFontFamily, $fSize, $iStyle, $iColWidth = 0) _GDIPlus_Startup() Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;Create a graphics object from a window handle Local $aRanges[2][2] = [[1]] $aRanges[1][0] = 0 ;Measure first char (0-based) $aRanges[1][1] = StringLen($sString) ;Region = String length Local $hFormat = _GDIPlus_StringFormatCreate() Local $hFamily = _GDIPlus_FontFamilyCreate($sFontFamily) Local $hFont = _GDIPlus_FontCreate($hFamily, $fSize, $iStyle) _GDIPlus_GraphicsSetTextRenderingHint($hGraphic, $GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT) _GDIPlus_StringFormatSetMeasurableCharacterRanges($hFormat, $aRanges) ;Set ranges Local $aWinClient = WinGetClientSize($hGUI) If $iColWidth = 0 Then $iColWidth = $aWinClient[0] Local $tLayout = _GDIPlus_RectFCreate(10, 10, $iColWidth, $aWinClient[1]) Local $aRegions = _GDIPlus_GraphicsMeasureCharacterRanges($hGraphic, $sString, $hFont, $tLayout, $hFormat) ;get array of regions Local $aBounds = _GDIPlus_RegionGetBounds($aRegions[1], $hGraphic) Local $aWidthHeight[2] = [$aBounds[2], $aBounds[3]] ; Clean up resources _GDIPlus_FontDispose($hFont) _GDIPlus_RegionDispose($aRegions[1]) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() Return $aWidthHeight EndFunc ;==>_StringInPixels ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StringInPixels_gdip ; Description ...: Returns a pixel-accurate height and width for a given string using a GDI+ font, layout and format ; Syntax ........: _StringInPixels_gdip($hGraphic, $sString, $hFont, $tLayout, $hFormat) ; Parameters ....: $hGraphic - Handle to a GDI+ graphics object. ; $sString - The string to be measured. ; $hFont - Handle to a GDI+ font. ; $tLayout - A $tagGDIPRECTF structure that bounds the string. ; $hFormat - Handle to a GDI+ string format. ; Return values .: 2-row array. [0] is width in pixels; [1] is height in pixels. ; Author ........: Tim Curran; adapted from Pierre Arnaud's C# function ; Modified ......: ; Remarks .......: This much more efficient version is for use with GDI+ fonts ; Related .......: ; Link ..........: <https://www.codeproject.com/Articles/2118/Bypass-Graphics-MeasureString-limitations> ; Example .......: Example-StringInPixels.au3 ; =============================================================================================================================== #include <GDIPlus.au3> #include <GUIConstantsEx.au3> Func _StringInPixels_gdip($hGraphic, $sString, $hFont, $tLayout, $hFormat) Local $aRanges[2][2] = [[1]] $aRanges[1][0] = 0 ;Measure first char (0-based) $aRanges[1][1] = StringLen($sString) ;Region = String length _GDIPlus_GraphicsSetTextRenderingHint($hGraphic, $GDIP_TEXTRENDERINGHINT_CLEARTYPEGRIDFIT) _GDIPlus_StringFormatSetMeasurableCharacterRanges($hFormat, $aRanges) ;Set ranges Local $aRegions = _GDIPlus_GraphicsMeasureCharacterRanges($hGraphic, $sString, $hFont, $tLayout, $hFormat) ;get array of regions Local $aBounds = _GDIPlus_RegionGetBounds($aRegions[1], $hGraphic) Local $aWidthHeight[2] = [$aBounds[2], $aBounds[3]] _GDIPlus_RegionDispose($aRegions[1]) Return $aWidthHeight EndFunc ;==>_StringInPixels_gdip  
    _StringInPixels.au3
    Example-StringInPixels.au3
  7. Like
    tcurran got a reaction from BrewManNH in Pixel-accurate string width and height   
    Here are two functions to provide pixel-accurate height and width dimensions for a given string.
    The more commonly-used _GDIPlus_GraphicsMeasureString built-in UDF is problematic because it returns the width padded by roughly one en-space (for reasons related to the various ways Windows produces anti-aliased fonts).
    These are AutoIt translations of Pierre Arnaud's C# functions, described in his CodeProject article "Bypass Graphics.MeasureString limitations"
    The first is an all-purpose version that takes a window handle, string, font family, font size (in points), style, and (optionally) width of the layout column (in pixels) as parameters.
    The second, more efficient version is intended for applications where GDI+ fonts are already in use, and takes handles to the existing graphics context, string, font, layout and format as parameters.
    Both functions return a two-row array with the exact width [0] and height [1] of the string (in pixels).
    EDIT: (Note that some of the same anti-aliasing measurement issues still apply. I did my best to work around them, but the output of the function may still be off by a pixel or two. Buyer beware.)
    #include <GDIPlus.au3> #include <GUIConstantsEx.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StringInPixels ; Description ...: Returns a pixel-accurate height and width for a given string using a given font, style and size. ; Syntax ........: _StringInPixels($hGUI, $sString, $sFontFamily, $fSize, $iStyle[, $iColWidth = 0]) ; Parameters ....: $hGUI - Handle to the window. ; $sString - The string to be measured. ; $sFontFamily - Full name of the font to use. ; $fSize - Font size in points (half-point increments). ; $iStyle - Combination of 0-normal, 1-bold, 2-italic, 4-underline, 8-strikethrough ; $iColWidth - [optional] If word-wrap is desired, column width in pixels ; Return values .: 2-row array. [0] is width in pixels; [1] is height in pixels. ; Author ........: Tim Curran; adapted from Pierre Arnaud's C# function ; Modified ......: ; Remarks .......: This version is longer and less efficient but works for all purposes. ; Related .......: <https://www.codeproject.com/Articles/2118/Bypass-Graphics-MeasureString-limitations> ; Link ..........: ; Example .......: Example-StringInPixels.au3 ; =============================================================================================================================== #include <GDIPlus.au3> #include <GUIConstantsEx.au3> Func _StringInPixels($hGUI, $sString, $sFontFamily, $fSize, $iStyle, $iColWidth = 0) _GDIPlus_Startup() Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;Create a graphics object from a window handle Local $aRanges[2][2] = [[1]] $aRanges[1][0] = 0 ;Measure first char (0-based) $aRanges[1][1] = StringLen($sString) ;Region = String length Local $hFormat = _GDIPlus_StringFormatCreate() Local $hFamily = _GDIPlus_FontFamilyCreate($sFontFamily) Local $hFont = _GDIPlus_FontCreate($hFamily, $fSize, $iStyle) _GDIPlus_GraphicsSetTextRenderingHint($hGraphic, $GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT) _GDIPlus_StringFormatSetMeasurableCharacterRanges($hFormat, $aRanges) ;Set ranges Local $aWinClient = WinGetClientSize($hGUI) If $iColWidth = 0 Then $iColWidth = $aWinClient[0] Local $tLayout = _GDIPlus_RectFCreate(10, 10, $iColWidth, $aWinClient[1]) Local $aRegions = _GDIPlus_GraphicsMeasureCharacterRanges($hGraphic, $sString, $hFont, $tLayout, $hFormat) ;get array of regions Local $aBounds = _GDIPlus_RegionGetBounds($aRegions[1], $hGraphic) Local $aWidthHeight[2] = [$aBounds[2], $aBounds[3]] ; Clean up resources _GDIPlus_FontDispose($hFont) _GDIPlus_RegionDispose($aRegions[1]) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() Return $aWidthHeight EndFunc ;==>_StringInPixels ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StringInPixels_gdip ; Description ...: Returns a pixel-accurate height and width for a given string using a GDI+ font, layout and format ; Syntax ........: _StringInPixels_gdip($hGraphic, $sString, $hFont, $tLayout, $hFormat) ; Parameters ....: $hGraphic - Handle to a GDI+ graphics object. ; $sString - The string to be measured. ; $hFont - Handle to a GDI+ font. ; $tLayout - A $tagGDIPRECTF structure that bounds the string. ; $hFormat - Handle to a GDI+ string format. ; Return values .: 2-row array. [0] is width in pixels; [1] is height in pixels. ; Author ........: Tim Curran; adapted from Pierre Arnaud's C# function ; Modified ......: ; Remarks .......: This much more efficient version is for use with GDI+ fonts ; Related .......: ; Link ..........: <https://www.codeproject.com/Articles/2118/Bypass-Graphics-MeasureString-limitations> ; Example .......: Example-StringInPixels.au3 ; =============================================================================================================================== #include <GDIPlus.au3> #include <GUIConstantsEx.au3> Func _StringInPixels_gdip($hGraphic, $sString, $hFont, $tLayout, $hFormat) Local $aRanges[2][2] = [[1]] $aRanges[1][0] = 0 ;Measure first char (0-based) $aRanges[1][1] = StringLen($sString) ;Region = String length _GDIPlus_GraphicsSetTextRenderingHint($hGraphic, $GDIP_TEXTRENDERINGHINT_CLEARTYPEGRIDFIT) _GDIPlus_StringFormatSetMeasurableCharacterRanges($hFormat, $aRanges) ;Set ranges Local $aRegions = _GDIPlus_GraphicsMeasureCharacterRanges($hGraphic, $sString, $hFont, $tLayout, $hFormat) ;get array of regions Local $aBounds = _GDIPlus_RegionGetBounds($aRegions[1], $hGraphic) Local $aWidthHeight[2] = [$aBounds[2], $aBounds[3]] _GDIPlus_RegionDispose($aRegions[1]) Return $aWidthHeight EndFunc ;==>_StringInPixels_gdip  
    _StringInPixels.au3
    Example-StringInPixels.au3
  8. Like
    tcurran got a reaction from argumentum in Pixel-accurate string width and height   
    Here are two functions to provide pixel-accurate height and width dimensions for a given string.
    The more commonly-used _GDIPlus_GraphicsMeasureString built-in UDF is problematic because it returns the width padded by roughly one en-space (for reasons related to the various ways Windows produces anti-aliased fonts).
    These are AutoIt translations of Pierre Arnaud's C# functions, described in his CodeProject article "Bypass Graphics.MeasureString limitations"
    The first is an all-purpose version that takes a window handle, string, font family, font size (in points), style, and (optionally) width of the layout column (in pixels) as parameters.
    The second, more efficient version is intended for applications where GDI+ fonts are already in use, and takes handles to the existing graphics context, string, font, layout and format as parameters.
    Both functions return a two-row array with the exact width [0] and height [1] of the string (in pixels).
    EDIT: (Note that some of the same anti-aliasing measurement issues still apply. I did my best to work around them, but the output of the function may still be off by a pixel or two. Buyer beware.)
    #include <GDIPlus.au3> #include <GUIConstantsEx.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StringInPixels ; Description ...: Returns a pixel-accurate height and width for a given string using a given font, style and size. ; Syntax ........: _StringInPixels($hGUI, $sString, $sFontFamily, $fSize, $iStyle[, $iColWidth = 0]) ; Parameters ....: $hGUI - Handle to the window. ; $sString - The string to be measured. ; $sFontFamily - Full name of the font to use. ; $fSize - Font size in points (half-point increments). ; $iStyle - Combination of 0-normal, 1-bold, 2-italic, 4-underline, 8-strikethrough ; $iColWidth - [optional] If word-wrap is desired, column width in pixels ; Return values .: 2-row array. [0] is width in pixels; [1] is height in pixels. ; Author ........: Tim Curran; adapted from Pierre Arnaud's C# function ; Modified ......: ; Remarks .......: This version is longer and less efficient but works for all purposes. ; Related .......: <https://www.codeproject.com/Articles/2118/Bypass-Graphics-MeasureString-limitations> ; Link ..........: ; Example .......: Example-StringInPixels.au3 ; =============================================================================================================================== #include <GDIPlus.au3> #include <GUIConstantsEx.au3> Func _StringInPixels($hGUI, $sString, $sFontFamily, $fSize, $iStyle, $iColWidth = 0) _GDIPlus_Startup() Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;Create a graphics object from a window handle Local $aRanges[2][2] = [[1]] $aRanges[1][0] = 0 ;Measure first char (0-based) $aRanges[1][1] = StringLen($sString) ;Region = String length Local $hFormat = _GDIPlus_StringFormatCreate() Local $hFamily = _GDIPlus_FontFamilyCreate($sFontFamily) Local $hFont = _GDIPlus_FontCreate($hFamily, $fSize, $iStyle) _GDIPlus_GraphicsSetTextRenderingHint($hGraphic, $GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT) _GDIPlus_StringFormatSetMeasurableCharacterRanges($hFormat, $aRanges) ;Set ranges Local $aWinClient = WinGetClientSize($hGUI) If $iColWidth = 0 Then $iColWidth = $aWinClient[0] Local $tLayout = _GDIPlus_RectFCreate(10, 10, $iColWidth, $aWinClient[1]) Local $aRegions = _GDIPlus_GraphicsMeasureCharacterRanges($hGraphic, $sString, $hFont, $tLayout, $hFormat) ;get array of regions Local $aBounds = _GDIPlus_RegionGetBounds($aRegions[1], $hGraphic) Local $aWidthHeight[2] = [$aBounds[2], $aBounds[3]] ; Clean up resources _GDIPlus_FontDispose($hFont) _GDIPlus_RegionDispose($aRegions[1]) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() Return $aWidthHeight EndFunc ;==>_StringInPixels ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StringInPixels_gdip ; Description ...: Returns a pixel-accurate height and width for a given string using a GDI+ font, layout and format ; Syntax ........: _StringInPixels_gdip($hGraphic, $sString, $hFont, $tLayout, $hFormat) ; Parameters ....: $hGraphic - Handle to a GDI+ graphics object. ; $sString - The string to be measured. ; $hFont - Handle to a GDI+ font. ; $tLayout - A $tagGDIPRECTF structure that bounds the string. ; $hFormat - Handle to a GDI+ string format. ; Return values .: 2-row array. [0] is width in pixels; [1] is height in pixels. ; Author ........: Tim Curran; adapted from Pierre Arnaud's C# function ; Modified ......: ; Remarks .......: This much more efficient version is for use with GDI+ fonts ; Related .......: ; Link ..........: <https://www.codeproject.com/Articles/2118/Bypass-Graphics-MeasureString-limitations> ; Example .......: Example-StringInPixels.au3 ; =============================================================================================================================== #include <GDIPlus.au3> #include <GUIConstantsEx.au3> Func _StringInPixels_gdip($hGraphic, $sString, $hFont, $tLayout, $hFormat) Local $aRanges[2][2] = [[1]] $aRanges[1][0] = 0 ;Measure first char (0-based) $aRanges[1][1] = StringLen($sString) ;Region = String length _GDIPlus_GraphicsSetTextRenderingHint($hGraphic, $GDIP_TEXTRENDERINGHINT_CLEARTYPEGRIDFIT) _GDIPlus_StringFormatSetMeasurableCharacterRanges($hFormat, $aRanges) ;Set ranges Local $aRegions = _GDIPlus_GraphicsMeasureCharacterRanges($hGraphic, $sString, $hFont, $tLayout, $hFormat) ;get array of regions Local $aBounds = _GDIPlus_RegionGetBounds($aRegions[1], $hGraphic) Local $aWidthHeight[2] = [$aBounds[2], $aBounds[3]] _GDIPlus_RegionDispose($aRegions[1]) Return $aWidthHeight EndFunc ;==>_StringInPixels_gdip  
    _StringInPixels.au3
    Example-StringInPixels.au3
  9. Like
    tcurran got a reaction from coffeeturtle in Which Monitor is a Window On?   
    Given a specific XY coordinate, this snippet returns the handle to the monitor the coordinate appears on... or 0 if it is off all screens. Particularly useful in multiple monitor setups where monitors have different resolutions or are offset vertically or horizontally (in which case, there are areas of the virtual desktop that are off all screens).
    You could also use it to return the handle of the monitor where a window is placed, or where the mouse was clicked, or other similar applications.
    #include <WinAPIGdi.au3> ;for _WinOnMonitor() Func _WinOnMonitor($iXPos, $iYPos) Local $aMonitors = _WinAPI_EnumDisplayMonitors() If IsArray($aMonitors) Then ReDim $aMonitors[$aMonitors[0][0] + 1][5] For $ix = 1 To $aMonitors[0][0] $aPos = _WinAPI_GetPosFromRect($aMonitors[$ix][1]) For $j = 0 To 3 $aMonitors[$ix][$j + 1] = $aPos[$j] Next Next EndIf For $ixMonitor = 1 to $aMonitors[0][0] ; Step through array of monitors If $iXPos > $aMonitors[$ixMonitor][1] And $iXPos < $aMonitors[$ixMonitor][1] + $aMonitors[$ixMonitor][3] Then If $iYPos > $aMonitors[$ixMonitor][2] And $iYPos < $aMonitors[$ixMonitor][2] + $aMonitors[$ixMonitor][4] Then Return $aMonitors[$ixMonitor][0] ; return handle to monitor coordinate is on EndIf EndIf Next Return 0 ;Return 0 if coordinate is on none of the monitors EndFunc ;==> _WinOnMonitor  
  10. Like
    tcurran reacted to Dav1d in Program specific volume control (UDF)   
    Tested to work under Win7. Should work with Vista as well.

    Usage:


    WinSetVolume("title", 50) - Set volume (0-100)
    WinSetVolume("title", "mute") - Mute
    WinSetVolume("title", "unmute") - Unmute
    WinSetVolume("title", "toggle") - Toggles mute state
    Returns 1 on success, 0 on failure.

    Please note:


    For non-English platforms you'll need to alter the $localized string (e.g. for Dutch: $localized = "Dempen voor "). Setting the volume to 0 is not the same as muting. This function doesn't respect the WinTitleMatchMode setting, it will always match titles as if in mode 1. On how it functions:


    The keypress after setting the slider's position is needed to trigger Windows to adjust the volume, otherwise it won't become effective. Just FYI, if you wondered. Since there's no easy way to determine whether or not a given window is muted, the volume level is being re-set which results in unmuting (though it possibly already was), so we're certain of it's state. Afterwards it 'presses' the mute button, if applicable. Any questions, bug reports or ideas are welcome. I appreciate if you let me know if this was of use to you.


    #include <GuiConstantsEx.au3> #include <GuiSlider.au3> Func WinSetVolume($targetTitle, $targetVolume = "toggle") Const $localized = "Mute for " $currentActive = WinGetHandle("[active]") $mixerPid = Run(@SystemDir & "\SndVol.exe -r", "", @SW_HIDE) $mixerHandle = WinWaitActive("[CLASS:#32770]") WinActivate($currentActive) $iSlider = 1 $iButton = 2 While 1 $currentButton = ControlGetText("[CLASS:#32770]", "", "[CLASS:ToolbarWindow32; INSTANCE:" & $iButton & "]") If @error Then ProcessClose($mixerPid) Return 0 ElseIf StringInStr($currentButton, $localized & $targetTitle, 1) = 1 Then If NOT ($targetVolume == "toggle") Then $sliderHandle = ControlGetHandle("[CLASS:#32770]", "", "[CLASS:msctls_trackbar32; INSTANCE:" & $iSlider & "]") If IsInt($targetVolume) Then $setVolume = -($targetVolume-100) Else $setVolume = _GUICtrlSlider_GetPos($sliderHandle) EndIf If $setVolume < 100 Then _GUICtrlSlider_SetPos($sliderHandle, $setVolume+1) ControlSend("[CLASS:#32770]", "", "[CLASS:msctls_trackbar32; INSTANCE:" & $iSlider & "]", "{UP}") Else _GUICtrlSlider_SetPos($sliderHandle, $setVolume-1) ControlSend("[CLASS:#32770]", "", "[CLASS:msctls_trackbar32; INSTANCE:" & $iSlider & "]", "{DOWN}") EndIf EndIf If $targetVolume == "toggle" OR $targetVolume == "mute" Then ControlCommand("[CLASS:#32770]", "", "[CLASS:ToolbarWindow32; INSTANCE:" & $iButton & "]", "SendCommandID", 305) WinClose($mixerHandle) Return 1 EndIf $iSlider += 1 $iButton += 2 WEnd EndFunc
  11. Like
    tcurran got a reaction from KaFu in SMF - The fastest duplicate files finder... [Updated 2025-May-18]   
    Glad to be of help. And very glad I didn't have to work out how to reproduce the buggy behavior!

    Updated exe downloaded.
  12. Like
    tcurran got a reaction from KaFu in SMF - The fastest duplicate files finder... [Updated 2025-May-18]   
    When I attempted to delete individual duplicate files, SMF deleted my entire Pictures folder. Luckily, it was simply moved to the Recycling folder, so I was able to restore it. But needless to say, I'm going to stop using SMF until you figure out what's wrong.
  13. Like
    tcurran reacted to czardas in Snippet Dump   
    Loch Ness Monster Case and Camel Case

    Some sightings of Loch Ness Monster Case have been reported in the wild, although none have been substantiated. Also note that Camel Case isn't normally found outside its native enviroment. ^^


    #include-once #include <Array.au3> MsgBox(0, LochNessMonsterCase("message from nessie"), LochNessMonsterCase("hello from the loch ness monster!")) Func LochNessMonsterCase($sText) If StringRegExp($sText, "(?i)[[:alpha:]]") = 0 Then Return SetError(1, 0, $sText) ; Contains no alpha characters. Local $aWords = StringRegExp($sText, "(?i)[[:alpha:]']+", 3) $aWords = _ArrayUnique($aWords) _ArraySortByLen($aWords, 0, 1) Local $iLen, $iMidPoint, $sCurrChar, $sTempStr, $iApostrophe For $i = 1 To $aWords[0] $iApostrophe = StringInStr($aWords[$i], "'") If $iApostrophe Then $aWords[$i] = StringReplace($aWords[$i], "'", "", 1) $iLen = StringLen($aWords[$i]) $iMidPoint = Ceiling($iLen/2) If Mod($iLen , 2) = 0 Then $iMidPoint += 1 $sTempStr = "" For $j = 1 To $iLen $sCurrChar = StringMid($aWords[$i], $j, 1) If $j = $iMidPoint Or $j = $iMidPoint -1 Then $sCurrChar = StringUpper($sCurrChar) Else $sCurrChar = StringLower($sCurrChar) EndIf $sTempStr &= $sCurrChar Next If $iApostrophe Then $sTempStr = StringLeft($sTempStr, $iApostrophe -1) & "'" & StringRight($sTempStr, $iLen -$iApostrophe +1) $sText = StringReplace($sText, $sTempStr, $sTempStr) Next Return $sText EndFunc ;==> LochNessMonsterCase Func _ArraySortByLen(ByRef $aArray, $iDescending =0, $iStart =0, $iEnd =0) If Not IsArray($aArray) Or UBound($aArray, 0) > 1 Then Return SetError(1, 0, 0) ; Not a 1D array If Not IsInt($iStart) Or Not IsInt($iEnd) Then Return SetError(5, 0, 0) ; Parameters need to be integers. Local $iBound = UBound($aArray) Local $aElementLen[$iBound][2] $iBound -=1 For $i = 0 To $iBound $aElementLen[$i][0] = StringLen($aArray[$i]) ; Get the length of the element $aElementLen[$i][1] = $aArray[$i] ; The element to sort Next _ArraySort($aElementLen, $iDescending, $iStart, $iEnd) If @error Then Return SetError(@error, 0, 0) ; See _ArraySort() for error codes 2 to 4. For $i = 0 To $iBound $aArray[$i] = $aElementLen[$i][1] Next Return 1 EndFunc ;==> _ArraySortByLen

    MsgBox(0, "Camel Case", CamelCase(" _ testing _ camel _ case" & @TAB & " ThIs caMeL hAs 3 hUMPS ")) Func CamelCase($sText, $CapsNext = 1, $bRecursion = False) If StringLen($sText) = 0 Then Return SetError(1) If Not $bRecursion Then $sText = StringLower($sText) Local $sNewStr = "", $sCurrChar For $i = 1 To StringLen($sText) $sCurrChar = StringMid($sText, $i, 1) If StringRegExp($sCurrChar, "\w") Then If Not $bRecursion Then If StringIsAlpha($sCurrChar) Then If $CapsNext Then $sCurrChar = StringUpper($sCurrChar) $CapsNext = 0 EndIf Else $CapsNext = 1 EndIf Else If StringIsAlpha($sCurrChar) And Not $CapsNext Then $sCurrChar = StringLower($sCurrChar) $CapsNext = 1 EndIf EndIf ElseIf $bRecursion Then $CapsNext = 0 Else $CapsNext = 1 EndIf $sNewStr &= $sCurrChar Next If Not $bRecursion Then While StringRegExp($sNewStr, "(\w)( +)(\w)") $sNewStr = StringRegExpReplace($sNewStr, "(\w)( +)(\w)", "\1\3") WEnd $sNewStr = CamelCase($sNewStr, 0, True) EndIf Return $sNewStr EndFunc ;==> CamelCase
  14. Like
    tcurran reacted to TheSaint in UDF for Title Case, Initial Caps, and Sentence Case   
    Here's an example from my Update Mp3 Artwork program, which I use at the click of a CASE button for the Track Title (ID3 Tag) field. In the Settings window, is another CASES button that allows editing the following text file in Notepad.

    Cases.txt

    Here's the simple code I use to process it, remembering that I code with speed not perfection ... for personal use only. I do my programs like I needed them yesterday, which in most cases I do.

    Func CaseFile($tagtxt) If FileExists($casefle) Then $lines = _FileCountLines($casefle) If $lines > 0 Then $file = FileOpen($casefle, 0) For $l = 1 To $lines $line = FileReadLine($file, $l) If StringLeft($line, 1) <> ";" Then $part = StringSplit($line, "|") If $part[0] > 1 Then If StringInStr($tagtxt, $part[1]) > 0 Then If $part[0] = 2 Then $tagtxt = StringReplace($tagtxt, $part[1], $part[2]) ElseIf $part[3] = "query" Then $ans = MsgBox(262177, "Confirm Case Change or Replacement", _ "Change --> " & $part[1] & @LF & _ "To --> " & $part[2] & @LF & @LF & _ "NOTE - This will apply to every instance." & @LF & @LF & _ "Do you want to proceed?", 0) If $ans = 1 Then $tagtxt = StringReplace($tagtxt, $part[1], $part[2]) EndIf EndIf EndIf EndIf EndIf Next FileClose($file) EndIf Return $tagtxt EndIf EndFunc ;=> CaseFile Very simplistic for sure, but does the job well, and fast enough processing for my needs.

    NOTE - Because I manually transferred the code from my other PC via a text file, all the tabbing got lost when I pasted here, so I've manually & painfully spaced everything. Which appears to gradually get lost after every edit I do.
  15. Like
    tcurran got a reaction from TheSaint in UDF for Title Case, Initial Caps, and Sentence Case   
    Why, you use MY function, of course.

    Edit:
    Different tools for different jobs.
  16. Like
    tcurran reacted to guinness in UDF for Title Case, Initial Caps, and Sentence Case   
    Thanks for posting.
  17. Like
    tcurran reacted to czardas in UDF for Title Case, Initial Caps, and Sentence Case   
    It's impossible to fix all the user's mistakes, and a large database of abbreviations isn't a particularly watertight solution. If you plan on capitalizing a long list of titles, there will nearly always be some inconsistancies, whatever method you choose. If the method parses over 95% of international names correctly, that's got to be worth the effort. Also if you happen to know which abbreviations are present, you can simply run StringReplace afterwards.

    Edit
    The next post is very much to the point. If you want to fix bbC, then use tcurran's _StringChooseCase
  18. Like
    tcurran got a reaction from czardas in UDF for Title Case, Initial Caps, and Sentence Case   
    Why, you use MY function, of course.

    Edit:
    Different tools for different jobs.
  19. Like
    tcurran reacted to czardas in UDF for Title Case, Initial Caps, and Sentence Case   
    I like the traditional system because it allows the more important words to stand out in a title. The only reason I see for not liking this system is that the rules appear to be ambiguous and therefore hard to code for.

    After adding the (optional) common British English exceptions I listed previously, I'm now thinking of adding another option - common international name exceptions. I have come up with the following list:

    af, av, da, de, de la, de los, del, di, van de, van der, von
    I think this should cover most, although not all, scenarios, eg:
    Leonardo da Vinci. Wernher von Braun, Paco de Lucía

    I think many of these non English words or word combinations are generally written as lower case in titles regardless of whether they form part of a name or not. Unfortunately the above list will not cater for Vincent van Gogh because 'van' is also an English word. Are there any more I'm missing?
  20. Like
    tcurran got a reaction from czardas in UDF for Title Case, Initial Caps, and Sentence Case   
    @TheSaint
    I can appreciate that, in a sense, this is a matter of taste. However, there are rules for title capitalization (see The Chicago Manual of Style, Strunk & White's Elements of Style and many other reference works), and they do dictate that, in general, articles, prepositions and conjunctions are lower case (except when the first word in a title, or a meaningful, principal word).

    The actual rules are very complex and run to about a page in The Chicago Manual of Style. They'd be impossible to code for because they depend on context and value judgements. That's why Title Case mode in uses a subset of articles, prepositions and conjunctions that are most likely to be lower-case in a title (that follows the rules of capitalization).

    @czardas @TheSaint

    The correct British and Amercan version of the title would be:


    "I Went to the Market by Lofty Waters" (by Charles Smith)
    I think what @TheSaint was getting at was that "by Lofty Waters" was somehow ambiguous as to whether that was part of the title or the name of the author, and that all initial caps somehow clears it up. But in fact, the rules of formal English dictate that "by" is supposed to be lower case, and the ambiguity is supposed to be cleared up with the use of quotation marks (i.e. inverted commas) or italics.



  21. Like
    tcurran got a reaction from czardas in UDF for Title Case, Initial Caps, and Sentence Case   
    This UDF is intended to improve on the existing _StringProper UDF by using the magic of regular expressions (don't worry, it protects the user from having to know anything about RegEx). In addition to avoiding some of the anomalies associated with _StringProper (such as a cap following each apostrophe--Susan'S Farm), it provides additional functionality:
    Sentence Case: Only the first word of each sentence (following a period, question mark, exclamation point or colon) is capitalized. Title Case: Initial caps for all words except articles (a, the) and some common conjunctions (and, but) and prepositions (in, on). While the actual rules for capitalizing authored works would require hundreds of lines of code and still not be perfect, this will suffice for most uses. Capitalization Exceptions: Permits user selectable exceptions to the default scheme. Mac (as in MacDonald), Mc, and O' are the defaults, but users can pass their own exceptions in an easy-to-use function parameter. I've chosen not to use the term "Proper Case" in the function at all, because a) there are varying opinions about what it means, b ) my equivalent (termed "Initial Caps") works somewhat differently (i.e. better ), and c) "Proper Case" as used in other applications (e.g. Excel) works (or doesn't work) the same as _StringProper in AutoIt.
    I'm posting _StringChooseCase here in hopes of getting some feedback and squashing any bugs I've missed prior to submitting it as a candidate for inclusion as a standard AutoIt UDF.

    UPDATE (3 Jan 2013): I removed the hack noted below using a more bullet-proof method of marking capitalization exceptions, inspired by dany's _StringRegExpSplit function. Also added the colon character as sentence punctuation, and added II, III & IV as default cap exceptions.

    UPDATE (9 Jan 2013): The code is a hair more efficient. #include-once and #include <array.au3> now appear where they're supposed to. "I" is now always capitalized (both as the first person pronoun and the Roman numeral one). Title Case further improved: It now has a more comprehensive list of lower-case words--mainly more prepositions--and the last word of a title will always be capitalized.


    #include-once #include <Array.au3> ;_ArrayToString UDF used in Return ; #FUNCTION# ==================================================================================================================== ; Name...........: _StringChooseCase ; Description ...: Returns a string in the selected upper & lower case format: Initial Caps, Title Case, or Sentence Case ; Syntax.........: _StringChooseCase($sMixed, $iOption[, $sCapExcepts = "Mc^|Mac^|O'^|II|III|IV"]) ;PROSPECTIVE: add param for Ignore mixed case input ; Parameters ....: $sMixed - String to change capitalization of. ; $iOption - 1: Initial Caps: Capitalize Every Word; ; 2: Title Case: Use Standard Rules for the Capitalization of Work Titles; ; 3: Sentence Case: Capitalize as in a sentence. ; $sCapExcepts - [optional] Exceptions to capitalizing set by options, delimited by | character. Use the ^ ; character to cause the next input character (whatever it is) to be capitalized ; Return values .: Success - Returns the same string, capitalized as selected. ; Failure - "" ; Author ........: Tim Curran <tim at timcurran dot com> ; Remarks .......: Option 1 is similar to standard UDF _StringProper, but avoids anomalies like capital following an apostrophe ; Related .......: _StringProper, StringUpper, StringLower ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _StringChooseCase(ByRef $sMixed, $iOption, $sCapExcepts = "Mc^|Mac^|O'^|I|II|III|IV") Local $asSegments, $sTrimtoAlpha, $iCapPos = 1 $sMixed = StringLower($sMixed) Switch $iOption Case 1 ;Initial Caps $asSegments = StringRegExp($sMixed, ".*?(?:\s|\Z)", 3) ;break by word Case 2 ;Title Case $asSegments = StringRegExp($sMixed, ".*?(?:\s|\Z)", 3) ;break by word Case 3 ;Sentence Case $asSegments = StringRegExp($sMixed, ".*?(?:\.\W*|\?\W*|\!\W*|\:\W*|\Z)", 3) ;break by sentence EndSwitch Local $iLastWord = UBound($asSegments) - 2 For $iIndex = 0 to $iLastWord ;Capitalize the first letter of each element in array $sTrimtoAlpha = StringRegExp($asSegments[$iIndex], "\w.*", 1) If @error = 0 Then $iCapPos = StringInStr($asSegments[$iIndex], $sTrimtoAlpha[0]) If $iOption <> 2 Or $iIndex = 0 Then ;Follow non-cap rules for Title Case if option selected (including cap last word) $asSegments[$iIndex] = StringReplace($asSegments[$iIndex], $iCapPos, StringUpper(StringMid($asSegments[$iIndex], $iCapPos, 1))) ElseIf $iIndex = $iLastWord Or StringRegExp($asSegments[$iIndex], "\band\b|\bthe\b|\ba\b|\ban\b|\bbut\b|\bfor\b|\bor\b|\bin\b|\bon\b|\bfrom\b|\bto\b|\bby\b|\bover\b|\bof\b|\bto\b|\bwith\b|\bas\b|\bat\b", 0) = 0 Then $asSegments[$iIndex] = StringReplace($asSegments[$iIndex], $iCapPos, StringUpper(StringMid($asSegments[$iIndex], $iCapPos, 1))) EndIf ;Capitalization exceptions $asSegments[$iIndex] = _CapExcept($asSegments[$iIndex], $sCapExcepts) Next Return _ArrayToString($asSegments, "") EndFunc ;==> _StringChooseCase Func _CapExcept($sSource, $sExceptions) Local $sRegExaExcept, $iMakeUCPos Local $avExcept = StringSplit($sExceptions, "|") For $iIndex = 1 to $avExcept[0] $sRegExaExcept = "(?i)\b" & $avExcept[$iIndex] $iMakeUCPos = StringInStr($avExcept[$iIndex], "^") If $iMakeUCPos <> 0 Then $sRegExaExcept = StringReplace($sRegExaExcept, "^", "") Else $sRegExaExcept &= "\b" EndIf $avExcept[$iIndex] = StringReplace($avExcept[$iIndex], "^", "") ;remove ^ from replacement text $sSource = StringRegExpReplace($sSource, $sRegExaExcept, $avExcept[$iIndex]) If $iMakeUCPos <> 0 Then Local $iNextUC = _StringRegExpPos($sSource, $sRegExaExcept) Local $iMatches = @extended Local $iCapThis = $iNextUC + $iMakeUCPos For $x = 1 to $iMatches $sSource = StringLeft($sSource, $iCapThis - 2) & StringUpper(StringMid($sSource, $iCapThis - 1, 1)) & StringMid($sSource, $iCapThis) Next EndIf Next Return $sSource EndFunc ;==> _CapExcept Func _StringRegExpPos($sTest, $sPattern, $iOcc = 1, $iStart = 1) Local $sDelim, $iHits If $iStart > StringLen($sTest) Then Return SetError(1) ;Delimiter creation snippet by dany from his version of _StringRegExpSplit For $i = 1 To 31 $sDelim &= Chr($i) If Not StringInStr($sTest, $sDelim) Then ExitLoop If 32 = StringLen($sDelim) Then Return SetError(3, 0, 0) Next Local $aResults = StringRegExpReplace(StringMid($sTest, $iStart + (StringLen($sDelim) * ($iOcc - 1))), "(" & $sPattern & ")", $sDelim & "$1") If @error = 2 Then Return SetError(2, @extended, 0) $iHits = @extended If $iHits = 0 Then Return 0 If $iOcc > $iHits Then Return SetError(1) Local $iPos = StringInStr($aResults, $sDelim, 0, $iOcc) SetExtended($iHits) Return $iStart - 1 + $iPos EndFunc ;<== _StringRegExpPos
    Here's a bit of sample code:

    EDIT (16 Jan 2013): Corrected format of #include to use quotation marks instead of angle brackets.


    #Include "_StringChooseCase.au3" Global $test = "'abcdefghi now it's 'the time for all good men.' 'AND TWELVE MORE MACDONALD'S!'" & @CRLF & "The quick brown fox JUMPED over the lazy MacDonalds. The USA's Usain Bolt ran for the USA." ConsoleWrite(_StringChooseCase($test, 1, "Mc^|Mac^|O'^|USA|FBI|Barack|Obama") & @CRLF) ConsoleWrite(_StringChooseCase('"and the band played on"', 2) & @CRLF)
    Previous downloads: 18
    _StringChooseCase.au3
  22. Like
    tcurran reacted to LarsJ in Rubik's Cube   
    The picture shows Rubik's Cube in the middle of a rotation, wherein the layer is rotated 90 degrees.


    New version for AutoIt 3.3.10

    The scripts were flawed. Fixed in this update.


    08-01-2013: First post

    In the Cubes menu there are six cubes from 2*2*2 to 7*7*7: Pocket Cube, Rubik's Cube, Rubik's Revenge, Professor's Cube, V-Cube 6 and V-Cube 7. See http://en.wikipedia.org/wiki/Rubik's_Cube.

    The Scramble menu scrambles the cube. In the input field in the statusbar you can set the number of scramble steps.

    The Solve menu automatically solves the cube. In this version it just plays back the undo log.

    The Build menu shows how the cubes are created. It also shows how the rotation of a layer is simulated.

    The Scramble, Solve and Build menus puts the program into a Scramble, Solve and Build mode. To leave the Scramble and Solve modes click the menu once more. To leave the Build mode uncheck the menu.

    The program mode or state appears in the statusbar.

    See the Help menu for more information about the menus.


    Rotating a layer in the cube
    Click an edge of the layer with the left mouse button and hold the button down Move the mouse in the direction you want to rotate the layer Release the left mouse button The rotating layer in the picture has probably been clicked somewhere on the blue edge.
    You can't rotate a layer in Scramble, Solve and Build modes.

    The mouse buttons can be switched in the Options.


    Rotating the entire cube
    Click in the window with the right mouse button and hold the button down Move the mouse in the direction you want the cube to rotate Release the right mouse button The description of the mouse rotations can be found in the Help menu.

    Using the keyboard

    Use the arrow keys or <A,a>, <W,w>, <S,s>, <Z,z> to rotate the cube.
    Use <Home> or <H,h> to place the cube in the start position.
    Use <Page Up> or <I,i> and <Page Down> or <O,o> to zoom in and out.
    Use Num 1-6 or 1-6 to show the 6 sides of the cube.


    The program

    Inspiration for the program is from this site: http://rubiksim.sourceforge.net/.

    The graphics is generated with old style OpenGL 1.1. Some OpenGL globals and functions are copied from this thread http://www.autoitscript.com/forum/index.php?showtopic=83581 by trancexx. Especially globals and functions for creating an OpenGL window and a rendering context.


    Zipfile

    The zipfile contains a number of files:
    RubiksCube.au3 - GUI and main loop, run this file MenuFncs.au3 - implements the menu system MenuWins.au3 - creates menu system windows Keyboard.au3 - code for shortcut keys OGLconsts.au3 - OpenGL constants OGLfuncs.au3 - OpenGL functions Cubes.au3 - creates the cubes TurnLayer.au3 - rotate a layer RotateCube.au3 - rotate the cube Scramble.au3 - scramble function SolveCube.au3 - solve functions Build.au3 - build functions Utilities.au3 - calculations (The files are edited with Notepad++ with a tabwidth of 2. This doesn't match the default settings in Scite.)

    21-01-2013: Update #1

    Fixed some errors in the Build menu.
    Added a log to see the colors of all sides at one time. See picture in post #5.


    RubiksCube3.3.10.7z

    Testet on XP 32 bit and Win 7 32/64 bit.


    Previous versions for AutoIt 3.3.8




  23. Like
    tcurran reacted to czardas in Snippet Dump   
    Unicode Compatible Title Case

    This topic has come up quite a lot lately and the following code is really an experiment. Problems associated with proper case are not all possible to resolve. Differentiating between words and acronyms, or identifying common exceptions such as Scottish names beginning Mac or Mc, is very hard. MC is also a Roman numeral. The function does not attempt any of these things. Instead it avoids altering anything which may already be correct. It will not touch abbreviations such as BBC or website URLs and it also caters for various types of hyphenation and apostrophies. You have the option to ignore small word exceptions which are not capitalized in standard British English.

    After you have run the example try using the function on the actual code itself. Mainly the comments will be capitalized and the code will remain mainly untouched and still run, because pre-existing capitals are presumed to be correct. I wrote all the comments in lower case on purpose so you could try this.

    Rules and Guidelines





    #include-once #include <Array.au3> #include <String.au3> Example() Func Example() Local $sExample = _ "the great rock 'n roll swindle" & @LF & _ "old McDonnald had a farm" & @LF & _ "download AutoIt from autoitscript.com." & @LF & _ "download win-1252 from autoitscript.com/forum/topic/135167-win-1252-extended-keyboard/" & @LF & _ "from the 14th to the 21st century" & @LF & _ "BBC iTunes II III IV" & @LF & _ "la época de los árabes" & @LF & _ "on (and on) and on" & @LF & _ "on top of old smokey" & @LF & _ "she's got x-ray vision" & @LF & _ "one,two,three,four" & @LF & _ "werner von bruin" & @LF & _ "paco de lucía y camarón de la isla" ConsoleWrite(_TitleCase($sExample, Default, Default, True) & @LF) EndFunc ;==> Example() Func _TitleCase($sText, $bAP_Exceptions = True, $bIgnoreCaps = True, $bInternational = False, $bIgnoreURL = True) If Not StringLen($sText) Then Return SetError(1, 0, $sText) ; nothing to parse If $bAP_Exceptions = Default Then $bAP_Exceptions = True If $bIgnoreCaps = Default Then $bIgnoreCaps = True If $bInternational = Default Then $bInternational = False If $bIgnoreURL = Default Then $bIgnoreURL = True Local $sWSLeft = "", $sWSRight = "", $sCurrChar For $i = 1 To StringLen($sText) $sCurrChar = StringMid($sText, $i, 1) If StringRegExp($sCurrChar, "\s") Then $sWSLeft &= $sCurrChar ; get leading WS Else ExitLoop EndIf Next For $i = StringLen($sText) To 1 Step -1 $sCurrChar = StringMid($sText, $i, 1) If StringRegExp($sCurrChar, "\s") Then $sWSRight = $sCurrChar & $sWSRight ; get trailing WS Else ExitLoop EndIf Next $sText = StringStripWS($sText, 3) ; remove leading and trailing WS Local $sNewStr = "", $sRegExp = "[0-9]|_", $bExceptions = False If $bIgnoreURL Then $sRegExp &= "|\\|/|(\.\w)" If $bIgnoreCaps Then $sRegExp &= "|[A-Z]" Else $sText = StringLower($sText) EndIf If StringRegExp($sText, $sRegExp) Then ; exceptions may be case sensitive, or include abbreviations $bExceptions = True Local $aArray = StringRegExp($sText, "\A\S+|(\s+\S+)|\s+\z", 3), _ ; find any WS characters followed by any none WS characters $aSubs = _GetMultiSubs($sText, 1) If @error Then Return SetError(2, 0, $sText) ; no suitable delimiter available For $i = 0 To UBound($aArray) -1 $aArray[$i] = StringStripWS($aArray[$i], 1) If Not StringInStr($sNewStr, $aSubs[0] & $aArray[$i], 1) Then $sNewStr &= $aSubs[0] & $aArray[$i] ; get unique exceptions Next $aArray = StringSplit($sNewStr, $aSubs[0], 3) ; overwrite the original array with an array of unique matches $aArray[0] = UBound($aArray) -1 ; get the number of unique matches _ArraySortByLen($aArray, 1, 1) ; reverse order the elements by length. If @error Then Return SetError(3, 0, $sText) ; failure to arrange by element length Local $aIgnore[UBound($aArray) -1], $iCount = 0 ; don't touch - web stuff, or words containing underscore, capitals or numbers For $i = 1 To $aArray[0] If StringRegExp($aArray[$i], $sRegExp) Then $aIgnore[$iCount] = $aArray[$i] ; string to replace $iCount += 1 EndIf Next $aArray = 0 ; no longer needed ReDim $aIgnore[$iCount] $aSubs = _GetMultiSubs($sText, $iCount) If @error Then Return SetError(2, 0, "") ; insufficient substitutes strings available For $i = 0 To $iCount -1 $aSubs[$i] = " " & $aSubs[$i] & " " ; add padding to the replacements $sText = StringReplace($sText, $aIgnore[$i], $aSubs[$i], 0, 1) ; replace all the exceptions Next EndIf Local $CapsNext = 1, $sHyphens = ChrW(8211) & ChrW(8212) & ChrW(173) & "-'" ; en dash, em dash, soft hyphen, hyphen and apostrophe $sNewStr = "" For $i = 1 To StringLen($sText) ; modified code from JCHD $sCurrChar = StringMid($sText, $i, 1) If StringIsAlpha($sCurrChar) Then If $CapsNext Then $sCurrChar = StringUpper($sCurrChar) $CapsNext = 0 EndIf ElseIf StringInStr($sHyphens, $sCurrChar) Then ; changes to the original - hyphenation and apostrophe $CapsNext = 0 Else $CapsNext = 1 EndIf $sNewStr &= $sCurrChar Next If $bAP_Exceptions Then Local $aConj[24] = _ ["A","An","And","As","At","But","By","For", _ "From","In","Into","Nor","Of","On","Onto","Or", _ "Per","So","The","To","Up","Via","With","Yet"] For $i = 0 To 23 $sNewStr = StringReplace($sNewStr, " " & $aConj[$i] & " ", " " & StringLower($aConj[$i]) & " ") $sNewStr = StringReplace($sNewStr, "(" & $aConj[$i] & " ", "(" & StringLower($aConj[$i]) & " ") $sNewStr = StringReplace($sNewStr, " " & $aConj[$i] & ")", " " & StringLower($aConj[$i]) & ")") Next EndIf If $bInternational Then Local $aPartName[20] = _ [" Af "," Av "," Da "," De "," Del "," Der "," Di ", _ " E "," En "," Et "," Het "," La "," Las "," Lo ", _ " Los "," Und "," Van De "," Van Der "," Von "," Y "] For $i = 0 To 19 $sNewStr = StringReplace($sNewStr, $aPartName[$i], StringLower($aPartName[$i])) Next EndIf If $bExceptions Then For $i = $iCount -1 To 0 Step -1 ; put all the exceptions back in the new string $sNewStr = StringReplace($sNewStr, $aSubs[$i], $aIgnore[$i]) Next EndIf $sNewStr = $sWSLeft & $sNewStr & $sWSRight Return $sNewStr EndFunc ;==> _TitleCase() Func _GetMultiSubs($sTest, $iSubs) If Not IsString($sTest) Then Return SetError(1, 0, 0) ; Invalid Input String. If Not IsInt($iSubs) Or $iSubs < 1 Then Return SetError(2, 0, 0) ; Invalid number of substitute strings ; NOTE: The returned order of substitutes may be important. ; Extra padding may be needed to avoid substitutes coming into contact with other control characters. Local $aSubs[$iSubs], $aAscII[31], $iCount = 0, $sChar ; Using Control Characters only. ; First try one character For $i = 1 To 31 $sChar = Chr($i) If Not StringInStr($sTest, $sChar, 1) Then $aSubs[$iCount] = $sChar $iCount +=1 If $iCount = $iSubs Then Return $aSubs EndIf $aAscII[$i - 1] = $sChar ; Needed for the next stage. Next ; That failed - so we try two characters. Local $aDoubleChar = _ArrayCombinations($aAscII, 2, "") For $i = 1 To $aDoubleChar[0] $sChar = $aDoubleChar[$i] If Not StringInStr($sTest, $sChar, 1) Then $aSubs[$iCount] = $sChar $iCount +=1 If $iCount = $iSubs Then Return $aSubs EndIf Next ; That failed - so we try the reverse patterns. ReDim $aDoubleChar[931] $aDoubleChar[0] = 930 For $i = 466 To $aDoubleChar[0] $sChar = _StringReverse($aDoubleChar[$i -465]) If Not StringInStr($sTest, $sChar, 1) Then $aSubs[$iCount] = $sChar $iCount +=1 If $iCount = $iSubs Then Return $aSubs EndIf $aDoubleChar[$i] = $sChar ; Needed for the next stage. Next ; That failed - so we try three characters. For $i = 1 To $aDoubleChar[0] For $j = 0 To 30 $sChar = $aDoubleChar[$i] & $aAscII[$j] If Not StringInStr($sTest, $sChar, 1) Then $aSubs[$iCount] = $sChar $iCount +=1 If $iCount = $iSubs Then Return $aSubs EndIf Next Next ; That failed - so we try four characters. For $i = 1 To $aDoubleChar[0] For $j = 1 To $aDoubleChar[0] $sChar = $aDoubleChar[$i] & $aDoubleChar[$j] If Not StringInStr($sTest, $sChar, 1) Then $aSubs[$iCount] = $sChar $iCount +=1 If $iCount = $iSubs Then Return $aSubs EndIf Next Next ; That failed - so we try five characters. For $i = 1 To $aDoubleChar[0] For $j = 1 To $aDoubleChar[0] For $k = 0 To 30 $sChar = $aDoubleChar[$i] & $aDoubleChar[$j] & $aAscII[$k] If Not StringInStr($sTest, $sChar, 1) Then $aSubs[$iCount] = $sChar $iCount +=1 If $iCount = $iSubs Then Return $aSubs EndIf Next Next Next Return SetError (2, 0, "") ; Not enough substitutions available EndFunc ; _GetMultiSubs() Func _ArraySortByLen(ByRef $aArray, $iDescending =0, $iStart =0, $iEnd =0) If Not IsArray($aArray) Or UBound($aArray, 0) > 1 Then Return SetError(1, 0, 0) ; Not a 1D array If Not IsInt($iStart) Or Not IsInt($iEnd) Then Return SetError(5, 0, 0) ; Parameters need to be integers. Local $iBound = UBound($aArray) Local $aElementLen[$iBound][2] $iBound -=1 For $i = 0 To $iBound $aElementLen[$i][0] = StringLen($aArray[$i]) ; Get the length of the element $aElementLen[$i][1] = $aArray[$i] ; The element to sort Next _ArraySort($aElementLen, $iDescending, $iStart, $iEnd) If @error Then Return SetError(@error, 0, 0) ; See _ArraySort() for error codes 2 to 4. For $i = 0 To $iBound $aArray[$i] = $aElementLen[$i][1] Next Return 1 EndFunc ;==> _ArraySortByLen()
    See also:

    Edit
    Code Updated
×
×
  • Create New...