Jump to content

tcurran

Active Members
  • Posts

    36
  • Joined

  • Last visited

Everything posted by tcurran

  1. To reaffirm some of what's been said before: Try compiling... with UPX off with compression set to Low or Lowest/Off launching the 64-bit version of the exe. Sometimes this will work when the 32-bit will not One of the above or some combination of them will very likely work for you.
  2. 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
  3. 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
  4. 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
  5. A3LStructs.au3 and A3LSecurity.au3 appear to be missing from the zip.
  6. qwert-- Those are excellent questions. This approach was suggested to me by "Joe" the developer of ArsClip. I adapted his approach to AutoIT, tested it in my particular application (it worked!!) and posted it here. Your question about browser windows is particularly trenchant, but--since I haven't tested it--I have no answer. Please post back here if you learn whether it does or doesn't work.
  7. Here's a short UDF that will, at least in most cases, detect whether a window can be copied from or pasted to programmatically--for example, by Send()ing ctl-c, ctl-v. This is often disabled when programs (like your AutoIt script) run at a lower UAC integrity level than the application they are trying to operate on. #include <WinAPI.au3> Func _WindowIsPasteable($handle) ;accepts window handle; returns true or false whether a window will accept Ctl-C, Ctl-V Local $bCanPaste = True Local $hTestWindowPID = 0 Local $hTestWindowTID = _WinAPI_GetWindowThreadProcessId($handle, $hTestWindowPID) _WinAPI_AttachThreadInput(_WinAPI_GetCurrentThreadId(), $hTestWindowTID, True);attach to window we want to paste into $bCanPaste = _WinAPI_GetFocus() ;Test whether window is paste-able--returns False if it is not _WinAPI_AttachThreadInput(_WinAPI_GetCurrentThreadId, $hTestWindowTID, False);detach from window thread Return $bCanPaste EndFunc Pass it a window handle; it returns true or false whether a window will accept programmatic pasting. The function may not work on the CMD window, since it handles the clipboard uniquely. This function works by attaching to the program thread of the window whose handle it receives, then attempting to perform a GetFocus on that thread. In most cases, the attempt will fail if the window will not accept programmatic copy-paste.
  8. OK, that wasn't quite right. I forgot to shut down the instance of SndVol.exe Here's the UDF, corrected and complete. Again, thanks! TAC #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 $currentButton = "" Then ;this ElseIf prevents infinite loop if no matching $targetTitle WinClose($mixerHandle) 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
  9. Very useful... exactly what I needed. I did notice one slight problem. If there's no match for $targetTitle, the function will loop infinitely. There's an easy fix, of course. I just added If $currentButton = "" Then Return 0 below $currentButton = ControlGetText("[CLASS:#32770]", "", "[CLASS:ToolbarWindow32; INSTANCE:" & $iButton & "]") and it's good to go. Thanks for the UDF!
  10. As far as I have been able to ascertain, this is the only comprehensive UDF of its kind. I certainly hope you don't give up on it, and in fact bring it up-to-date for Win 8. In any case, you have my thanks for keeping it going as long as you did. TAC
  11. 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. 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. The registry change happened at install time. I did not check the "Open au3 with ISN" setting. I returned Explorer to normal by changing the Properties|General|Opens With setting to "AutoIt v3 Script" This is on Windows 7.
  14. The .91 BETA (installer version) still alters the default for .au3 files from Run to Open in SciTE.
  15. Kip and ileandros: <sarcasm>Another fine example of the rich, nuanced communication enabled by the forum platform.</sarcasm> If ileandros had perhaps said what he evidently meant, "One should not provide a script which is not executable." or if Kip had found some way to convey what may have been a teasing, winking tone, then ileandros need not have stalked off in an anti-trolling huff. It's a shame, really
  16. Why, you use MY function, of course. Edit: Different tools for different jobs.
  17. _StringChooseCase has now been @czardas Just as I've inspired you, you've inspired me. I'm thinking about adding a parameter which would permit users to tell the function to ignore any word (or sentence, when using sentence-case option) that has mixed cases within it. So "apple," "street," and "boot" would all be capitalized, but "House," "iPod," and "VanderVeldon" "SCRAM!" would all be left exactly as input (edit: SCRAM wouldn't be left alone, because it's actually all upper-case). This seems like a useful addition... but is it really? Isn't such a function mostly used for text that is ALL CAPS, or all lower case, or entirely messed up in some other way? How often is it necessary to change capitalization where some text is correctly capitalized and some isn't?
  18. @TheSaint I totally agree. You should capitalize however you want. My function even caters for you: You can pick mode 1 and capitalize every word. Or if someday you need the function to approximate the Formal Rules for Title Capitalization, you can choose mode 2. My only concern as the person who started this thread was not leaving as the final word your view that "true titles" had "each and every word" capitalised. That's a valid viewpoint, but 'technically' or 'formally' incorrect. BTW, I tried to do some research on how title capitalization got to be the way it is in English (including Australian English, incidentally—I did learn that much). But I had no success, other than that is the product of evolution and fashion which varied a lot and was not formalized until the appearance of grammar references and dictionaries in the 19th century.
  19. @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.
  20. This sounds like a good project. Just remember that one frequent use for a such a function is to convert input from ALL CAPS to sentence or title case. Wouldn't an ALL CAPS word be ignored by your function (since it already contains capitals)? Or do you envision completely different uses between your function and mine?
  21. @czardas It's functionally impossible (without some kind of pretty good artificial intelligence) to develop a capitalization function that works in all cases. Even if you had a complete capitalization dictionary, the author's intentions and context come into play: Is this a first-level roman numeral (IV) or second-level (iv)?Is the input a title or a sentence?Is the word a noun (charity) or a person's name (Charity)?Is the word a 'capitonym' (August, august; Cancer, cancer; Catholic, catholic), where the intended definition dictates whether a word is capitalized?etc etc etcIn practical terms, the best a UDF scripter can do is make it easy for developers to provide their own exception list, appropriate for the use of the function in their scripts. Because capitalizing a list of names is a common use case, and because it's helpful to have an in-built example, the _StringChooseCase default assumes the function will be used for proper name capitalization. If you want to use it for something else (e.g. putting an outline into title case), you could and probably should provided a different exception list, following the format of the default list. So, in the case of your example, I would re-write it this way: $sString = "iii. third item, iv. fourth item" MsgBox(0, "", _StringChooseCase($sString, 1, "i|ii|iii|iv|v|vi|vii|viii|ix|x|xi|xii")) ;include Roman numerals up to max in outline Not the most elegant approach, I admit. But the alternatives aren't much prettier: Some Roman numerals are capitalized, some aren't--how do you distinguish?; "I" will always be ambiguous as to whether it is the Roman numeral one or the first-person pronoun; should there be some special regex code to distinguish a Roman number like MCMIX (1909) from a British name like McMillan? It starts to get silly. So I'm still pretty sure the best approach is letting the scripter decide the exception list based on the intended use of the function.
  22. 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
  23. @TheSaint Well, you did say, 'to be completest.' I should have noticed your list suggested you were thinking of movie and CD titles. But a 'complete' list would have to include every organization known commonly by its initials (FBI, CIA, NAACP, AARP and hundreds if not thousands more); every locality abbreviated by its initials (SF, TX); every unusually capitalized surname (diGenova), technology (FTP, iPad, iOS, LaTeX, SciTE(!)) or company name (FedEx, M&M/Mars); medical abbreviations; and on and on and on. A 'complete' list really would run to the thousands. Interestingly, while thinking about this, I came up with a method (using RegEx, of course) for feeding bulk texts with correct capitalization into an AutoIt script and getting out a file consisting of nothing but all the capitalization exceptions contained in the text. Feed in a few dictionaries and directories, and get back a comprehensive exception list! Not sure what you'd do with such a list, since—as I said—you'd need a much better search algorithm than the one in _StringChooseCase to run large texts against a large exception list efficiently. Anyhow, that's a project for another day. I'd love to see your title correction function. It might provide inspiration for improvements.
  24. Exactly! The complete list would run to the thousands, which would create quite a bit of processing overhead. Checking every word in the source against every word in a comprehensive exception list would mean hundreds of thousands or even millions of runs through the exception function. You'd need a much better search algorithm than this simple brute force method. But different scripters will use this function for different things. In some contexts, a user might not want to capitalize AM or PM, for instance. So for simplicity's sake, the defaults assume you'll be using it on a list of English-language names—period—and more by way of example than any effort to be comprehensive. But someone might use it to capitalize news copy. Someone else might use it on scanned legal documents. That's why there's a parameter to pass your own customized exception list. If you needed a really long list (and were willing to pay the performance price) It would be trivial to revise this code to load a text file into the $sCapExcepts parameter. My brief here is coding. I'll leave dictionary building to someone else.
×
×
  • Create New...