therks Posted September 8, 2006 Share Posted September 8, 2006 Hey there, I've been trying to figure this out for a little while, but I've gotten stumped. I just want a way to quickly close TrayTips without clicking on them (Will use a hotkey). I know it's simple code, but I'm having trouble identifying the traytip window. Opt('WinTitleMatchMode', 4) HotKeySet('#{SPACE}', '_ClearTrayTips') While 1 Sleep(100) WEnd Func _ClearTrayTips() $aTips = WinList('classname=tooltips_class32') For $i = 1 to $aTips[0][0] WinClose($aWins[$i][1]) Next EndFunc It can't be much more complex than that, right? But the tooltips_class32 classname is attached to more than just TrayTips, so I'm afraid of closing things that should be left open. Any ideas on how I can filter it down to just the TrayTip? My AutoIt Stuff | My Github Link to comment Share on other sites More sharing options...
dandymcgee Posted September 8, 2006 Share Posted September 8, 2006 Well I don't have the slightest clue what the fu** I did, but I made it so tray icons don't even pop-up anymore on my computer whether the script is running or not lol. I turned off windows firewall and it made a weird little sound, but nothing popped up. Like I said, I don't have a clue why this happens but hey, it'll stop them lol... Opt('WinTitleMatchMode', 4) HotKeySet('{Del}', '_ClearTrayTips') While 1 Sleep(100) WEnd Func _ClearTrayTips() $var = WinList('classname=tooltips_class32') For $i = 1 to $var[0][0] WinKill($var[$i][1]) Next EndFunc Be careful, I'm not sure why this works the way it does, and I'm not real great with AutoIt yet... - Dan [Website] Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted September 8, 2006 Moderators Share Posted September 8, 2006 Here's a shot, if your only trying to kill it in your system trayOpt('WinTitleMatchMode', 4) HotKeySet('{END}', '_ClearTrayTips') While 1 Sleep(100) _ClearTrayTips() WEnd Func _ClearTrayTips() $OptWTMM = Opt('WinTitleMatchMode', 4) $OptMCM = Opt('MouseCoordMode', 2) Local $aTips = WinList('classname=tooltips_class32') Local $aCPos = ControlGetPos('classname=Shell_TrayWnd', '', 'ToolbarWindow321') Local $aMpos = MouseGetPos() For $iCC = 1 to $aTips[0][0] If IsArray($aCPos) And IsArray($aMpos) And _ $aMpos[0] >= $aCPos[0] And _ $aMpos[0] <= $aCPos[0] + $aCPos[2] And _ $aMpos[1] >= $aCPos[1] And _ $aMpos[1] <= $aCPos[1] + $aCPos[3] And _ BitAND(WinGetState($aTips[$iCC][1]), 2) Then WinClose($aTips[$iCC][1]) EndIf Next Opt('WinTitleMatchMode', $OptWTMM) Opt('MouseCoordMode', $OptMCM) Return 1 EndFunc Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
therks Posted September 10, 2006 Author Share Posted September 10, 2006 Actually, it turns out that if I actually close (WinClose, WinKill) the traytip (or any tooltip for that matter) it won't popup again until explorer.exe is restarted. I'm guessing that's what happened for you, dandymcgee. I guess when you click a traytip it doesn't close it, it hides it or something, but when I tried hiding it with WinSetState, the majority of the bubble vanishes, but it left it's shadow behind. My AutoIt Stuff | My Github Link to comment Share on other sites More sharing options...
Valik Posted September 11, 2006 Share Posted September 11, 2006 If you actually can find the balloon tip, then try sending ControlClick() to it. You definitely do not want to close that window, it belongs to Explorer, as you've found out. All balloon tips shown in the notification area in that manner use an Explorer controlled balloon tip. Link to comment Share on other sites More sharing options...
therks Posted September 16, 2006 Author Share Posted September 16, 2006 If you actually can find the balloon tip, then try sending ControlClick() to it. You definitely do not want to close that window, it belongs to Explorer, as you've found out. All balloon tips shown in the notification area in that manner use an Explorer controlled balloon tip. Unfortunately, the problem I've encountered with this method is that sometimes a window opens unless the [x] on the balloon is clicked on specifically (The balloon that appears when my wireless network can't connect) this is more the reason I wanted the script. It's easy enough to just click on the balloon, but making sure I hit that [x] with my touchpad was annoying. I'm thinking what I'll do is grab the balloon coords, calculate where the [x] should be and click it. It seems to always the same sized [x] and in the same position from the top right corner of the balloon, regardless of the message or options. Think that will work? My AutoIt Stuff | My Github Link to comment Share on other sites More sharing options...
Valik Posted September 16, 2006 Share Posted September 16, 2006 The only thing you need to keep in mind is not all balloon tips will have a close box. Use TrayTip() without a title to confirm that. Outside of that advice, using MouseClick() really is about all you can do. I just spent a few minutes watching messages as I closed the balloon but I couldn't see anything particularly special that could be used. Link to comment Share on other sites More sharing options...
Valik Posted September 16, 2006 Share Posted September 16, 2006 (edited) On second thought, I did notice something that might be useful. When the shell's balloon tip exists (and is visible), it looks like the very next handle will be to it's SysShadow window (The shadow you saw left behind). Theoretically, the following would work (Requires some DllCall() stuff).Use whatever method you currently use to detect when a balloon tip is visible.Immediately call the Windows API function GetNextWindow() passing in the HWND of the balloon tip and GW_HWNDNEXT.Use the handle returned by GetNextWindow() to detect if it's of class SysShadow and that it is visible (This is probably not necessary but I definitely recommend verifying you're closing the correct shadow).Use WinClose() on the SysShadow handle.Use WinSetState() with @SW_HIDE on the balloon tip.This will hide the balloon and destroy its shadow which should be safe to do. The shadow is re-created every time the balloon tip is shown after it's been hidden.Edit: Spell check needs to learn to read my mind. Spelling a word right but using the wrong word sucks. Edited September 16, 2006 by Valik Link to comment Share on other sites More sharing options...
therks Posted September 19, 2006 Author Share Posted September 19, 2006 (edited) Wow, thanks so much, you have solved my problem. Sorta, heh.The only thing I'm worried about now is how unreliable my method for discerning traytips is. Using GetWindow (Aside: When I tried GetNextWindow, I got @error = 3; function not in DLL. So I'm using GetWindow with the GW_HWNDNEXT flag as noted in the Remarks for GetNextWindow on MSDN) I'm currently just running through all tooltips_class32 windows and checking their "next window." When I hit one where the next window is a class of SysShadow I assume that it's the traytip I'm looking for.I'm not sure if this will have me running into errors, but at the moment the worst I can see is that a tooltip with a shadow will be hidden and lose it's shadow. Any comments/suggestions on this?Anyway, here's the function I have.Deprecated function was here. See below.Interesting side note: Notice the commented line. This is what I had originally instead of the AnimateWindow line, but I noticed two things when I just hid the window. 1) Normally when you click on a traytip it fades out. And 2) There was a noticable pause between the window disappearing, and the shadow disappearing. So I decided to switch to the fadeout Animatewindow. Unfortunately, instead of fading out, the window just disappears right away, BUT, there's no noticable pause between the window and the shadow disappearing. I found it odd myself.Again, thanks for the help, and any more input is more than welcome.*Edit: Forgot to include the constants in my code sample. Edited September 20, 2006 by Saunders My AutoIt Stuff | My Github Link to comment Share on other sites More sharing options...
Valik Posted September 19, 2006 Share Posted September 19, 2006 Come to think of it, GetNextWindow() is probably a pre-processor macro that is expanded to a GetWindow() call so I'm not surprised it's not in the DLL.There are much more reliable ways to determine the correct balloon tip.See if the control has a style of TTS_BALLOON (0x40).See if the parent window is class "Shell_TrayWnd". Use AutoIt to get a handle to the window with that class and then use the Windows API GetParent() to get the parent of the tooltip and finally compare the two handles.If you do both of those I'd say you have a 99% chance of being right. Link to comment Share on other sites More sharing options...
therks Posted September 19, 2006 Author Share Posted September 19, 2006 (edited) Cool, thanks again, I'll be sure to check those out. But I have to admit I just found one strange problem. I used the function I have now to hide the traytip from my wireless connection, and it seemed to work fine, but when the script ended the traytip reappeared. I added a #NoTrayIcon to the top of the script and, again, it seemed to work fine, but then if any other tray icons move the balloon reappears again. I guess when the tray's icons move it refreshes balloon tips.I've discovered since though, that if I WinActivate the tip and Send('{ESC}') it closes the balloon very nicely. Can't believe I never thought of that in the first place. Nevermind, I must have done something else the first couple times cus it's not working now.*Edit: Cleaned up the post a little. Edited September 19, 2006 by Saunders My AutoIt Stuff | My Github Link to comment Share on other sites More sharing options...
Valik Posted September 19, 2006 Share Posted September 19, 2006 Meh. Forgive me for being brain-dead this entire time. I was looking at the problem from the standpoint of treating it as a window and instead I needed to treat it like the control it was. Write some code to reliably find the balloon tip using the comments from above. Once you have it's HWND, use SendMessage() to send TTM_TRACKACTIVATE with wParam and lParam set to 0. This will hide the balloon tip the correct way. Sending that message manually is the exact same thing that happens when the balloon times out or the application that wanted it closes taking it's tray icon with it. That is the proper way to do it. Link to comment Share on other sites More sharing options...
therks Posted September 20, 2006 Author Share Posted September 20, 2006 Awesome, now THAT works perfectly. I have one question though, and I feel stupid asking this, sorry, but earlier you mentioned "See if the control has a style of TTS_BALLOON (0x40)." I don't know how to check the style though. My AutoIt Stuff | My Github Link to comment Share on other sites More sharing options...
Valik Posted September 20, 2006 Share Posted September 20, 2006 GetWindowLong() with the flag GWL_STYLE and use BitAnd() to test for that specific flag. Link to comment Share on other sites More sharing options...
therks Posted September 20, 2006 Author Share Posted September 20, 2006 (edited) Thanks again Valik, I know you don't like stupid questions (or people) so I didn't really want to have to ask such a simple seeming question. Anyway, here's what I've cooked up with your help. Func _CloseTips() Local Const $GWL_STYLE = -16 Local Const $GW_HWNDNEXT = 2 Local Const $TTM_TRACKACTIVATE = 0x411 Local $i_PrevWTMM = Opt('WinTitleMatchMode', 4) Local $a_GetStyle, $a_GetParent, $a_GetClass, $a_NextWin, $a_Tips Local $h_User32 = DllOpen('user32.dll') $a_Tips = WinList('classname=tooltips_class32') For $i = 1 to $a_Tips[0][0] If BitAND(WinGetState($a_Tips[$i][1]), 2) Then $a_GetStyle = DllCall($h_User32, 'int', 'GetWindowLong', 'hwnd', $a_Tips[$i][1], 'int', $GWL_STYLE) If @error Then Return SetError(1, @error, 0) If BitAND($a_GetStyle[0], 0x40) Then $a_GetParent = DllCall($h_User32, 'hwnd', 'GetParent', 'hwnd', $a_Tips[$i][1]) If @error Then Return SetError(2, @error, 0) $a_GetClass = DllCall($h_User32, 'int', 'GetClassName', 'hwnd', $a_GetParent[0], 'str', '', 'int', 255) If @error Then Return SetError(3, @error, 0) If $a_GetClass[2] = 'Shell_TrayWnd' Then $a_NextWin = DllCall($h_User32, 'hwnd', 'GetWindow', 'hwnd', $a_Tips[$i][1], 'int', $GW_HWNDNEXT) If @error Then Return SetError(4, @error, 0) $a_GetClass = DllCall($h_User32, 'int', 'GetClassName', 'hwnd', $a_NextWin[0], 'str', '', 'int', 255) If @error Then Return SetError(5, @error, 0) If $a_GetClass[2] = 'SysShadow' Then DllCall($h_User32, 'int', 'SendMessage', 'hwnd', $a_Tips[$i][1], 'int', $TTM_TRACKACTIVATE, 'int', 0, 'int', 0) EndIf EndIf EndIf EndIf Next DllClose($h_User32) Opt('WinTitleMatchMode', $i_PrevWTMM) EndFunc And as near as I've seen, it seems to work like a hot damn. Edited September 20, 2006 by Saunders My AutoIt Stuff | My Github Link to comment Share on other sites More sharing options...
Valik Posted September 20, 2006 Share Posted September 20, 2006 I don't think you need to be that rigid about finding the window. This should probably suffice. I've also fixed a logic error. You were saving the state of WinTitleMatchMode and restoring it on return - but only if the function succeeded. If the function encountered an error, you just returned without restoring the state (or closing the DLL handle). I've put the bulk of the code in a one-run loop so that instead of returning on error, you set a couple variables and jump out of the loop to the cleanup code at the bottom. expandcollapse popupFunc _CloseTips() Local Const $GWL_STYLE = -16 Local Const $TTM_TRACKACTIVATE = 0x411 Local Const $TTS_BALLOON = 0x40 Local $i_PrevWTMM = Opt('WinTitleMatchMode', 4) Local $a_GetStyle, $a_GetParent, $a_Tips Local $h_User32 = DllOpen('user32.dll') Local $hTray = WinGetHandle("classname=Shell_TrayWnd") $a_Tips = WinList('classname=tooltips_class32') Local $nError = 0, $nExtended = 0 Do For $i = 1 to $a_Tips[0][0] If BitAND(WinGetState($a_Tips[$i][1]), 2) Then $a_GetStyle = DllCall($h_User32, 'int', 'GetWindowLong', 'hwnd', $a_Tips[$i][1], 'int', $GWL_STYLE) If @error Then $nError = 1 $nExtended = @error ExitLoop 2 EndIf If BitAND($a_GetStyle[0], $TTS_BALLOON) Then $a_GetParent = DllCall($h_User32, 'hwnd', 'GetParent', 'hwnd', $a_Tips[$i][1]) If @error Then $nError = 2 $nExtended = @error ExitLoop 2 EndIf If $hTray And $a_GetParent[0] = $hTray Then DllCall($h_User32, 'int', 'SendMessage', 'hwnd', $a_Tips[$i][1], 'int', $TTM_TRACKACTIVATE, 'int', 0, 'int', 0) EndIf EndIf EndIf Next Until True DllClose($h_User32) Opt('WinTitleMatchMode', $i_PrevWTMM) Return SetError($nError, $nExtended, 0) EndFunc Link to comment Share on other sites More sharing options...
therks Posted September 23, 2006 Author Share Posted September 23, 2006 (edited) I don't think you need to be that rigid about finding the window. This should probably suffice. I've also fixed a logic error. You were saving the state of WinTitleMatchMode and restoring it on return - but only if the function succeeded. If the function encountered an error, you just returned without restoring the state (or closing the DLL handle). I've put the bulk of the code in a one-run loop so that instead of returning on error, you set a couple variables and jump out of the loop to the cleanup code at the bottom.Right you are. Thanks for the fix. I'll have to remember this one-run loop trick for other scripts, I can think of times where it would have been handy.*Edit: One little note. Now that I think about it, it should be all right to exit the loop after sending TTM_TRACKACTIVATE, shouldn't it? I mean, as near as I know, there should never be more than one traytip showing, correct? Edited September 23, 2006 by Saunders My AutoIt Stuff | My Github Link to comment Share on other sites More sharing options...
Valik Posted September 23, 2006 Share Posted September 23, 2006 Correct. Only one may show at a time. Exiting the loop after finding the correct tooltip would be a good idea. Link to comment Share on other sites More sharing options...
MDCT Posted April 13, 2007 Share Posted April 13, 2007 Hello, guys I'm a n00b. I use software that blocks registry writes, but each time the software blocks, it displays balloon tip and after sometimes it becomes annoying. The balloon tip always display this text: "...protected registry". I have been trying to keep up with the conversations but unfortunately I could not make the script to work. From what I read "TTM_TRACKACTIVATE" is used to close the balloon tip, so it should be in: DllCall($h_User32, 'int', 'SendMessage', 'hwnd', $a_Tips[$i][1], 'int', $TTM_TRACKACTIVATE, 'int', 0, 'int', 0) After trial and error I couldn't make it to work, even with any balloon tip. And I also try a n00bish test to know if I could treat it as a window and if it able to differentiate balloon tip from other applications, but also no luck. I tried this code with result it hides any balloon tip even with "protected": Opt('WinTitleMatchMode', 4) While 1 Sleep(20) _ClearTrayTips() WEnd Func _ClearTrayTips() $var = WinList('classname=tooltips_class32') For $i = 1 to $var[0][0] WinSetState($var[$i][1],"protected",@SW_HIDE) Next EndFunc To make it short I need a code so the balloon tip from the software could be identified; and a code to close the balloon tip properly (I believe it uses TTM_TRACKACTIVATE). I'm sorry if I ask stupid questions. Thank you. Link to comment Share on other sites More sharing options...
PaulIA Posted April 13, 2007 Share Posted April 13, 2007 Hello, guys I'm a n00b. I use software that blocks registry writes, but each time the software blocks, it displays balloon tip and after sometimes it becomes annoying. The balloon tip always display this text: "...protected registry". I have been trying to keep up with the conversations but unfortunately I could not make the script to work. From what I read "TTM_TRACKACTIVATE" is used to close the balloon tip, so it should be in: DllCall($h_User32, 'int', 'SendMessage', 'hwnd', $a_Tips[$i][1], 'int', $TTM_TRACKACTIVATE, 'int', 0, 'int', 0) After trial and error I couldn't make it to work, even with any balloon tip. And I also try a n00bish test to know if I could treat it as a window and if it able to differentiate balloon tip from other applications, but also no luck. I tried this code with result it hides any balloon tip even with "protected": Opt('WinTitleMatchMode', 4) While 1 Sleep(20) _ClearTrayTips() WEnd Func _ClearTrayTips() $var = WinList('classname=tooltips_class32') For $i = 1 to $var[0][0] WinSetState($var[$i][1],"protected",@SW_HIDE) Next EndFunc To make it short I need a code so the balloon tip from the software could be identified; and a code to close the balloon tip properly (I believe it uses TTM_TRACKACTIVATE). I'm sorry if I ask stupid questions. Thank you.You can do this by using the native ToolTip API calls. Here's a little ditty that will close a ToolTip based on it's text. Run it and then put your cursor over the AutoIt icon in the system tray. You'll need the beta version of AutoIt and Auto3Lib to run this: #include <A3LToolTip.au3> GUICreate("ToolTip Test", 200, 100) GUISetState() do _Lib_PopupClear() _Lib_PopupScan () ; See if we found a ToolTip if (_Lib_PopupCount() > 0) and (_Lib_PopupGetType() = 3) then ; Get the handle to the ToolTip $hToolTip = _Lib_PopupGetHwnd() ; Get the ToolTip info $aToolInfo = _ToolTip_GetCurrentTool($hToolTip) ; See if it's a ToolTip to our program and close it if it is if StringInStr($aToolInfo[8], "AutoIt - ") > 0 then _ToolTip_Pop($hToolTip) endif until GUIGetMsg() = $GUI_EVENT_CLOSE Auto3Lib: A library of over 1200 functions for AutoIt 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