james3mg Posted January 8, 2010 Author Share Posted January 8, 2010 (edited) james3mg, This is as good as I can get it. It is pretty fast as I have limited the WinList search to tooltips_class32 windows and reduced the _Array* functions to a minimum. [...awesome example...] Never would've thought of that! Since my script is already making extensive use of SQLite, I may be able to take advantage of that instead of the _Array* functions for just a little more efficiency, but all in all, this may be as good as it gets. At least my script has very specific times it creates/destroys the GUIs, so it shouldn't be too hard to keep the burden of all this to a minimum. I'll take a closer look in a few hours when I have a little more time. THANK YOU for your awesome assistance! And to everyone who helped me in this topic! Edit: just had another thought I'll look into as well; my example of trying to delete the tooltip control by number before may have failed because I thought they were controls...your script implies they're actually GUIs unto themselves. Maybe I'll have more luck if I check for the numerical value of GUIs created before and after tooltips- I may be able to use GUIDelete() instead of GUICtrlDelete, since I'm not sure if WinKill() will actually free the resources/address reservation in the AutoIt table... I'll let you know what I discover. Edited January 8, 2010 by james3mg "There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110 Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted January 8, 2010 Moderators Share Posted January 8, 2010 (edited) james3mg.Maybe I'll have more luck if I check for the numerical value of GUIs created before and after tooltipsI would not put too much hope in that. Windows is forever creating and deleting handles so the chances of them being in numerical order are minimal in my experience.Glad I could help - it was fun. M23Edit: A final thought as to why the OS falls over when you do not delete the tooltips. They are not part of the AutoIt control table (because they do not have ControlIDs), just normal Windows handles and Windows has a limit on how many an application can have open at any one time. So busting the limit is very likely to crash Windows rather than AutoIt. Anyway, it is moot now! Edited January 8, 2010 by Melba23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
james3mg Posted January 8, 2010 Author Share Posted January 8, 2010 I don't think it will- IF I understand the way it should work (take my thoughts on this matter with a grain of salt ), I think you're updating a single tooltip control/window rather than creating a new tooltip every time you update the text. My issue is that I'm creating NEW tooltips for NEW controls every time I recreate the children GUIs in my script. "There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110 Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted January 8, 2010 Moderators Share Posted January 8, 2010 Thanubis,As TraySetToolTip only sets/resets a single tip for the app's tray icon, I would imagine that the actual tooltip remains in existence and it is only the text in it which changes. So the "cannot delete" problem does not arise. However, as with much in IT, common sense does not always apply! Certainly I have often changed the text in a script's traytip multiple times without problem - although I have never got as far as 65532 alterations.M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
james3mg Posted January 8, 2010 Author Share Posted January 8, 2010 Most of my scripts don't deal with tons and tons of GUIs like this, as I'm sure you've gathered, so I'm still learning and re-learning all this stuff- thanks for your patience! I had indeed forgotten that GUI handles aren't like control handles, but are "global" for all of Windows, so yeah, finding the numerical value of the GUIs and guessing at the tooltips isn't going to be a good idea. So I ran with what you gave me. I think I improved on the method just a little, to make sure I don't grab tooltips that I shouldn't $GUI1=GUICreate("test",480,480) For $i=1 To 100 GUICtrlCreateLabel($i,0,0,30,20) GUICtrlSetTip(-1,"tip "&$i) Next GUISetState() $timer=TimerInit() $aTips=_ListTips() ConsoleWrite(TimerDiff($timer)&"ms to find "&UBound($aTips)-1&" tooltips" & @CRLF) $timer=TimerInit() For $i=1 To UBound($aTips)-1 WinKill($aTips[$i]) Next $aTips=0 ConsoleWrite(TimerDiff($timer)&"ms to delete all tooltips" & @CRLF) While 1 If GUIGetMsg()=-3 Then Exit Sleep(50) WEnd Func _ListTips() Local $aList1=WinList("[CLASS:tooltips_class32]") Local $aList2[1] For $i=1 To $aList1[0][0] If WinGetProcess($aList1[$i][1])=@AutoItPID Then ReDim $aList2[UBound($aList2)+1] $aList2[UBound($aList2)-1] = $aList1[$i][1] EndIf Next Return $aList2 EndFunc Looks like the tooltips are indeed deleted- thank you! The problem is, though it only takes my machine about 7ms to find 100 tooltips, it takes about 25 seconds to delete them, and the script really bogs down while it's doing it (mouse over the label to see the tooltip, and you see it kind of "pulse" in and out of existence- each pulse represents the time it takes to WinKill() just ONE tooltip. So I'm afraid that, though this is the "answer" I was looking for, it's way too slow to use Slow enough, I haven't run any tests in the 65000 range to see if they no longer count against Windows' "per-process" window limit or not. I tried using GUIDelete(), but it kept returning errors- I'm guessing that tooltips are a GUI belonging to Windows (Explorer?), and not the AutoIt script after all, so that won't be an option. Any chance you know of a quicker way to kill windows? lol P.S. you are the Thanks again. "There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110 Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted January 8, 2010 Moderators Share Posted January 8, 2010 james3mg,I like the WinGetProcess idea. Just shows why this forum is useful - ideas sparking off each other.I cannot, alas, offer a faster WinKill, but I can halve the short time to find the tips. Your code used ReDim every pass - and that is very slow as ReDim rewrites the array each time. It is better to do something like the following when you fill an array of unknown size:expandcollapse popup$GUI1 = GUICreate("test", 480, 480) For $i = 1 To 100 GUICtrlCreateLabel($i, $i * 5, $i * 5, 30, 20) GUICtrlSetTip(-1, "tip " & $i) Next GUISetState() $timer = TimerInit() $aTips = _ListTips() ConsoleWrite(TimerDiff($timer) & "ms to find " & UBound($aTips) - 1 & " tooltips" & @CRLF) $timer = TimerInit() For $i = 1 To $aTips[0] WinKill($aTips[$i]) Next $aTips = 0 ConsoleWrite(TimerDiff($timer) & "ms to delete all tooltips" & @CRLF) While 1 If GUIGetMsg() = -3 Then Exit WEnd Func _ListTips() Local $aList1 = WinList("[CLASS:tooltips_class32]") Local $aList2[2] = [0] For $i = 1 To $aList1[0][0] If WinGetProcess($aList1[$i][1]) = @AutoItPID Then ; Increase count element $aList2[0] += 1 ; Double array size if too small (fewer ReDim needed) If UBound($aList2) <= $aList2[0] + 1 Then ReDim $aList2[UBound($aList2) * 2] ; Add to list $aList2[$aList2[0]] = $aList1[$i][1] EndIf Next ReDim $aList2[$aList2[0] + 1] Return $aList2 EndFunc ;==>_ListTipsThe saving when you deal with seriously big arrays is quite something - and you can always presize the array when declaring to something bigger than 2 to get an even greater effect. I hope it is obvious how it works, but please ask if not. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
james3mg Posted January 8, 2010 Author Share Posted January 8, 2010 (edited) Yep, I get it, and it's a good point. If I end up doing this in my script, I'll probably start with an initial size equal to that of $aList1, since there's no way the shorter list will ever be longer than the longer list! lol. Then only one ReDim is needed However, as it stands right now, my script just isn't going to have any tooltips, since they're too limiting if they remain, and too slow if I delete them. ...I wonder which of the devs might have an idea on either using the straight Windows API for my own tooltips I can destroy or a faster way of killing windows... Edit: down to about 4ms to find all tips, still at 25000 to delete 'em $GUI1=GUICreate("test",480,480) For $i=1 To 100 GUICtrlCreateLabel($i,0,0,30,20) GUICtrlSetTip(-1,"tip "&$i) Next GUISetState() $timer=TimerInit() $aTips=_ListTips() ConsoleWrite(TimerDiff($timer)&"ms to find "&UBound($aTips)-1&" tooltips" & @CRLF) $timer=TimerInit() For $i=1 To UBound($aTips)-1 WinKill($aTips[$i]) Next $aTips=0 ConsoleWrite(TimerDiff($timer)&"ms to delete all tooltips" & @CRLF) While 1 If GUIGetMsg()=-3 Then Exit Sleep(50) WEnd Func _ListTips() Local $aList1=WinList("[CLASS:tooltips_class32]") Local $aList2[UBound($aList1)]=[0] For $i=1 To $aList1[0][0] If WinGetProcess($aList1[$i][1])=@AutoItPID Then $aList2[0]+=1 $aList2[$aList2[0]]=$aList1[$i][1] EndIf Next ReDim $aList2[$aList2[0]+1] Return $aList2 EndFunc Edited January 8, 2010 by james3mg "There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110 Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted January 8, 2010 Moderators Share Posted January 8, 2010 james3mg,Last idea - use Adlib to keep your script active while deleting the tooltips. You need to adjust the timer for the Adlib carefully - on my machine I need to call it at not less than 300ms, any shorter backs up the Adlib function and the whole script stalls.However, if you get the timing right you can keep the script active while the deletion proceeds - for me the deletion takes about 30secs (not much more than a straight loop which was around 25secs) and the ConsoleWrite shows that the script still has some processing power left. If you increased the Adlib time parameter, you could trade deletion time for script responsiveness. The only problem would be that you could not use the same array name again before the deletion process ended.Have a look and see what you think:expandcollapse popup#include <GUIConstantsEx.au3> Global $iBegin, $fFinished = False $GUI1 = GUICreate("test", 480, 480) For $i = 1 To 100 GUICtrlCreateLabel($i, $i * 5, $i * 5, 30, 20) GUICtrlSetTip(-1, "tip " & $i) Next GUISetState() $timer = TimerInit() $aTips = _ListTips() ConsoleWrite(TimerDiff($timer) & "ms to find " & UBound($aTips) - 1 & " tooltips" & @CRLF) ; Start killing tooltips Global $iIndex = 0 AdlibRegister("KillTips", 300) While 1 If GUIGetMsg() = $GUI_EVENT_CLOSE Then Exit ConsoleWrite("Still running at " & @MSEC & @CRLF) If $fFinished = True Then ConsoleWrite("All Done" & @CRLF) ConsoleWrite(TimerDiff($iBegin) & @CRLF) Exit EndIf WEnd Func _ListTips() Local $aList1 = WinList("[CLASS:tooltips_class32]") Local $aList2[2] = [0] For $i = 1 To $aList1[0][0] If WinGetProcess($aList1[$i][1]) = @AutoItPID Then ; Increase count element $aList2[0] += 1 ; Double array size if too small (fewer ReDim needed) If UBound($aList2) <= $aList2[0] + 1 Then ReDim $aList2[UBound($aList2) * 2] ; Add to list $aList2[$aList2[0]] = $aList1[$i][1] EndIf Next ReDim $aList2[$aList2[0] + 1] Return $aList2 EndFunc ;==>_ListTips Func KillTips() $iIndex += 1 ConsoleWrite($iIndex & @CRLF) If $iIndex = 1 Then $iBegin = TimerInit() WinKill($aTips[$iIndex]) If $iIndex = $aTips[0] Then AdlibUnRegister("KillTips") $fFinished = True EndIf EndFuncAnyway, I will bow out now - have fun with the rest of it. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
james3mg Posted January 8, 2010 Author Share Posted January 8, 2010 Thought about that, but I'm not a huge fan of that solution. I'd rather make a second .exe launched from my main script that received the IDs as messages (_SendMessage()) from my main script and put them into a queue, deleting them as quickly as it could and otherwise idling around if there's nothing in the queue. That way, the processes are fully separate, and the main script wouldn't get bogged down unless the whole computer was so underpowered that the "cleanup" exe slowed all of Windows down. But I still consider that a last resort- maybe even behind not having tooltips Thanks for your heap-and-a-half of help! "There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110 Link to comment Share on other sites More sharing options...
GEOSoft Posted January 9, 2010 Share Posted January 9, 2010 I use tool tips often myself and I found that I developed a tendency of adding more of them to lead the blind through the dark. In the end I had to make the decision to only use the ones that mattered the most. In some situations you may be better off to add a status bar and then place the text of the tool tip in there. That way it's only one control. George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!" Link to comment Share on other sites More sharing options...
james3mg Posted January 9, 2010 Author Share Posted January 9, 2010 Hey, thanks for giving me another chance A status bar is a great idea- may be just the ticket I was looking for. The reason I was using tooltips is that most of my controls (primarily clickable labels), by necessity, are too small to display the entire text they contain. So I was using the tooltips to "expand" the missing labels so I'd know what I was clicking on. But a status bar is kind of an innate behavior in this day and age, so maybe that's enough. Thanks for the idea! "There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110 Link to comment Share on other sites More sharing options...
GEOSoft Posted January 9, 2010 Share Posted January 9, 2010 (edited) If Thats the case then you may even be better using ToolTip() instead of GUICtrlSetTip() $Frm = GUICreate("Test") $Lbl1 = GUICtrlCreateLabel("This is some string of text to read", 10, 10, 30, 20) $Lbl2 = GUICtrlCreateLabel("This is an even longer string of text to read", 10, 30, 30, 20) $Lbl3 = GUICtrlCreateLabel("This is the what will be the longest string of text to read", 10, 50, 30, 20) GUISetState() While 1 $Msg = GUIGetMsg() Switch $Msg Case -3 Exit Case $Lbl1 To $Lbl3 ToolTip(GUICtrlRead($Msg)) Case Else ToolTip("") EndSwitch WEnd Or even look in one Example scripts for one of the hover functions. Edited January 9, 2010 by GEOSoft George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!" Link to comment Share on other sites More sharing options...
james3mg Posted January 11, 2010 Author Share Posted January 11, 2010 More great suggestions, thanks!I was already having other things happen if the labels are clicked, but following your advice I found this topic, and found that by adding just the following lines to my script:#include <GUICtrlSetOnHover_UDF.au3> Func LabelHover($iCtrlID) ToolTip(GUICtrlRead($iCtrlId)) EndFunc Func LabelMouseOut($iCtrlID) ToolTip("") EndFuncand replacing GUICtrlSetTip(-1,[control-specific_text]) with_GUICtrl_SetOnHover(-1,"LabelHover","LabelMouseOut")I get basically the same effect, but without the byproducts of creating and having to destroy control-specific tooltips.So, I think that solves all my issues, though it's good to have this topic now, so others can be aware of the hazards of using thousands of GUICtrlSetTip() 's "There are 10 types of people in this world - those who can read binary, and those who can't.""We've heard that a million monkeys at a million keyboards could produce the complete works of Shakespeare; now, thanks to the Internet, we know that is not true." ~Robert Wilensky0101101 1001010 1100001 1101101 1100101 1110011 0110011 1001101 10001110000101 0000111 0001000 0001110 0001101 0010010 1010110 0100001 1101110 Link to comment Share on other sites More sharing options...
nikink Posted January 12, 2010 Share Posted January 12, 2010 This is all so very good to know! I've fallen into a similar state as GEOsoft, whereby I'm adding tooltips to pretty much everything. It's good to see why this is bad, and to see better ways of doing similar functionality. Thanks everyone! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now