Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I am trying to develop a script that should do the following. For example, !W should:

  • check if Word is active (can be open or minimized)
  • if it is minimized, it should be restored to the size and location it had before minimization
  • if it is open, but "hidden" behind other open windows, the script should bring it to the front, making it the frontmost/active window
  • if it is neither minimized nor open, the program should be freshly started

I would like to do this for several programs: !W for Word, !N for Notepad++, !X for excel, !P for powerpoint, !F for firefox. If multiple instance of a program are running, or if multiple tabs are available, it should do the above for the most recent instance or tab. So, when multiple windows of firefox are open, it should restore (or bring to the front) the most recently viewed window with the most recently opened tab. Similarly, if multiple word documents are open, it should do this for the one I was last working on. And, if no Word document is open or minimized, it should open a fresh word instance. I hope this is clear.

I can do some of these things, for some programs, but not consistently, nor in one hotkey (I am still learning the scripting language). How could I achieve this?

Thank you, Peter

share|improve this question
add comment

3 Answers

up vote 7 down vote accepted

My understanding of how Window Activation works is pretty simple. It restores the most recently use window of that type. That default behavior makes coding what you want very simple. In fact, I do something almost identical to what you are after with two simple code blocks.

+#w::
SetTitleMatchMode, 2 ; approximate match
IfWinExist, - Microsoft Word
{
WinActivate, - Micrsoft Word
}
IfWinNotExist, - Microsoft Word
{
Run FullFilePathToMicrosoftWord
}
return

I created a bit of an interesting synergy to work with multiple monitors. Note that on Windows 7, holding shift + windows key and using the arrows to navigate left and right will move the active window between monitors at light speed. So I tried something a bit clever and mapped word to shift + window + w. It restores word if already open or runs a new instance if not. The beauty of the approach is that I never let go of shift + windows key. By doing so I can both active/start word and move it to exactly the position I want using left right arrow keys (up will maximize by the way and down will minimize). Map +#r to restore the active window and you completely control all windows that you normally use effortlessly without the mouse. All you must remember is the first letter of the app you are trying to activate.

In answer to your query about making the script more generic:

1) Consider using

; Allows you to search for an approximate window title match
SetTitleMatchMode, 2  

; For example, you could do the following to activate any existing window with 
; "- Microsoft Word" as part of the title

WinWait, - Microsoft Word, 
IfWinNotActive, - Microsoft Word, , WinActivate, - Microsoft Word, 
WinWaitActive, - Microsoft Word,

; some other code here once you have the window active

Or another possibility:

;Active the window by finding its ahk_class
WinWait, ahk_class OpusApp, 
IfWinNotActive, ahk_class OpusApp, , WinActivate, ahk_class OpusApp, 
WinWaitActive, ahk_class OpusApp,

Note: The code above was just an adaptation of the autoscriptwriter's generic output. It is somewhat redundant but effective. To find something like a window's ahk_class consider using AutoIt3 window spy.

If you need to discover the title of a window you can get active title as shown in the ahk example help file

WinGetActiveTitle, Title
MsgBox, The active window is "%Title%".

Another trick you can use is to set the active title using WinSetTitle

Edit: Given that you have multiple instances of excel/word/powerpoint floating around, also consider solving that problem with officetabs free edition. It will allow you to keep all open excel files in a single instance for example instead of strewn about the taskbar.

share|improve this answer
    
This is perfect! Great tips and very useful code. I am going to add a second monitor, so that part of the answer is also much appreciated. –  Peter Verbeet May 23 '12 at 2:33
    
By the way, I also like the officetabs tip. I didn't know it existed, but it looks very useful. –  Peter Verbeet May 23 '12 at 2:37
    
Luckily, the command "Run, winword" works, so it seems I don't have to supply the full path. –  Peter Verbeet May 23 '12 at 2:41
    
@Coldrainwater: How would one need to change your script above to make it work for Google Chrome? The problem is that the title changes depending on what website is open. –  Lernkurve Sep 8 '13 at 14:46
add comment

I see you already know of the magnificent Autohotkey language ;). I'd use:

  • ifWinActive ; check if window active
  • WinGet, output, MinMax ; check if window minimized
  • ifWinExists ; check if window exists (but not active)
  • Run ; run the program if no process associated
  • Z-order / WinList ; those will help you list all of the instances / determine which instance is the first one

If you have more questions, you should definitely ask them on the autohotkey forum.

; The script activates a Word 2007 window
; The script uses 'winTitle' and 'winClass' variables to match the window
; so set those properly first.
; Press Shift + 1 + w to see how the script works.
;
winTitle := "Document1 - Microsoft Word" ; use Autoit Window Spy to get this
winClass := "OpusApp"
RunWait, winword
return

+1::
    KeyWait, w, D T1 ; KeyboardHook not needed
    if(errorlevel) {
        msgbox, % """Shift + 1 + w"" failed"
        return
    }
    Send, {Backspace} ; erase 'w'
    IfWinNotActive, %winTitle%
    {
        WinActivate, %winTitle%
        WinWaitActive, %winTitle%, , 3
        if(errorlevel)
            MsgBox, % "Failed to activate the window."
    } 
    else ; Last Found Window set
    {
        MsgBox, % "Window already activated."

    }
return


F11::Reload
share|improve this answer
    
Thanks. I have been playing with these, but don't really know how to get an effective if-else loop in there. So, if IfWinActive is false, how do I launch the appropriate Run command as part of an else command? –  Peter Verbeet May 20 '12 at 17:34
    
@PeterVerbeet: see the edit. I've used Word 2007 English version. Press Shift+1+w to see how the script works. –  colemik May 20 '12 at 18:39
    
I've edited this a few times. –  colemik May 20 '12 at 18:57
    
Thanks trismarck, that is really useful. It works great. Is there a way to make it more "generic"? I would like this to run regardless of what document is currently being edited by Word. It seems to me that I would have to change the name manually in the script every time (I use Word a lot and am rarely using "Document1". Can it be done by checking whether Word itself is active, regardless of what document it is active on? –  Peter Verbeet May 20 '12 at 19:06
add comment

It may not be as complicated as some, but here is what I use to launch most of my programs. The toggle allows you to minimize the window if it is already active.

^NumpadDot::ShowStart("Google Chrome", "chrome.exe")

ShowStart(title, exe, toggle = 0)
{
    If WinActive(title) and toggle
        WinMinimize %title%
    Else
        {
            IfWinExist, %title%
                WinActivate
            else
            {
                Run, %exe%
                WinActivate
            }
        }
}
share|improve this answer
    
won't toggle always be 0? –  Sam Hasler Oct 17 '12 at 9:37
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.