Sign in to follow this  
Followers 0
tcurran

How to trigger a tray menu script that acts on the last active window

6 posts in this topic

I have a script that acts on any window with a text box (it does a wide variety of text modifications). It works great triggered from HotKeys, but now I want to also be able to trigger it from tray menu items. So my question is...

How do I capture which window had focus before the autoit tray icon was clicked (thus giving focus to the tray icon)? I need to be able to return focus to that window before running the rest of the script.

Any thoughts?

Share this post


Link to post
Share on other sites



I think WinList returns the window names in the order of which was last active, so try this:

func lastwindow()   
    $var = WinList()
    For $i = 1 to $var[0][0]
      ; Only display visble windows that have a title
      If $var[$i][0] <> "" AND IsVisible($var[$i][1]) Then exitloop
    Next
    ;return $var[$i][0] ; returns the window name
    return $var[$i][1] ; returns the window handle - much better
endfunc

    
Func IsVisible($handle) ; required for lastwindow()
  If BitAnd( WinGetState($handle), 2 ) Then 
    Return 1
  Else
    Return 0
  EndIf
EndFunc

[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Thanks for the hint. Experimentation shows that WinList first returns all "Always on Top" windows (in order of recency) and then returns normal windows, from most recently active to least. (In other words, all windows in Z order.) I'm not quite sure how to get around this, but I can probably come up with something that works for my purposes.

Edited by tcurran

Share this post


Link to post
Share on other sites

For anyone else who is interested in solving this problem...

In the end, I wound up not using the WinList function. Instead, I use the MouseOver tray event ( TraySetOnEvent ) to trigger a simple function that captures the currently active window into a variable if and only if the currently active window is not named "AutoIt v3" (the window name for the tray icon). Then, my various menu functions as their first action give the focus back to that captured window name. It feels slightly klugey -- there ought to be a better way -- but it works fine.

Here're some example code snippets:

#Include <constants.au3>
#Include <string.au3>

Opt("TrayOnEventMode", 1)
Opt("TrayAutoPause", 0)

Dim $ActiveWin

...

;Set All the Tray Menu Items
$TrayIDPasteLower = TrayCreateItem("Make lower case")
TrayItemSetOnEvent($TrayIDPasteLower, "PasteLowercase")

...

TraySetOnEvent($TRAY_EVENT_MOUSEOVER,"StoreActiveWindow")

While 1
   Sleep(100)
Wend

...


Func PasteLowercase()
   WinActivate($ActiveWin)
   $ActiveWin=""
   $PreserveClip = ClipGet()
   Send ("^c")
   $CapsString = ClipGet()
   $LwrString = StringLower($CapsString)
   ClipPut($LwrString)
   Send ("^v")
   ClipPut($PreserveClip)
EndFunc

...

Func StoreActiveWindow()
    If WinGetTitle("") <> "AutoIt v3" Then $ActiveWin = WinGetTitle("")
EndFunc

And while I have your attention, I notice that the Help examples and pretty much everybody uses "-1" as the first parameter in the TrayItemSetOnEvent function, instead of the full name of the previously defined variable. Out of curiosity, where is this shortcut documented? I haven't been able to find it anywhere.

Share this post


Link to post
Share on other sites

Sorry, I missed your original reply. You can get Ontop status like so:

func lastwindow()   
    $var = WinList()
    For $i = 1 to $var[0][0]
      ; Only display visble windows that have a title
      If $var[$i][0] <> "" AND IsVisible($var[$i][1]) AND NOT IsOntop($var[$i][1]) Then exitloop
    Next
    ;return $var[$i][0] ; returns the window name
    return $var[$i][1] ; returns the window handle - much better
endfunc

   
Func IsVisible($handle) ; required for lastwindow()
  If BitAnd( WinGetState($handle), 2 ) Then
    Return 1
  Else
    Return 0
  EndIf
EndFunc


func IsOntop($handle)
  $aEStyle = DllCall("user32.dll", "long", "GetWindowLong", "hwnd", $handle, "int", -20)
  ; above borrowed from AnyGui code - thanks Quaizywabbit
  If BitAnd($aEStyle[0], 8 ) Then
    Return 1
  Else
    Return 0
  EndIf
EndFunc

Hope that's useful.


[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Share this post


Link to post
Share on other sites

For anyone else who is interested in solving this problem...

How cool is that!!!

I was using a msgbox to allow the user to click the window active as I couldn't figure out an alternatve ... this is much better: thanks

- Perry

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0