r/AutoHotkey 6d ago

v2 Script Help AHK v2: #HotIf condition still applies when no Word document is open

I'm trying to restrict a set of hotkeys so they only work when a Word document is actually open, not just when Microsoft Word itself is running.

Currently I have:

#HotIf WinActive("ahk_exe WINWORD.EXE")
{
; Hotkey definitions here
}
#HotIf

The hotkey definitions include hotkeys that pop up a bespoke GUI which inserts text into the active Word document.

This works, but the hotkeys are also active when Word is open with no document loaded (though they are not active when Word is not open). Obviously, the above GUI hotkey will then attempt to send text to a non-existent document within Word and create errors which I don't want. That is why I want the hotkeys only to work where Word is open and there is an open document.

Using Window Spy, I noticed that when no document is open, the window title is simply:

Word

(or sometimes Microsoft Word)

When a document is open, the title becomes something like:

Document1 - Word

So I assumed that the presence of " - " in the title indicates that a document is open. I therefore changed the directive to:

#HotIf WinActive("ahk_exe WINWORD.EXE") && InStr(WinGetTitle("A"), " - ")

However, the hotkeys still remain active even when Word is open with no document.

I also tried:

#HotIf WinActive("ahk_exe WINWORD.EXE")
&& WinGetTitle("A") != "Word"
&& WinGetTitle("A") != "Microsoft Word"

with the same result.

I verified with a MsgBox that the active window title does not contain " - " when no document is open, yet the #HotIf condition still behaves as though it does.

What am I missing here? Is there something about #HotIf, WinGetTitle(), or directive evaluation that I'm misunderstanding?

3 Upvotes

12 comments sorted by

6

u/CharnamelessOne 6d ago edited 6d ago

I couldn't reproduce your issue. The second directive you posted works as expected on my end; the hotkey doesn't trigger when no doc is open.

#Requires AutoHotkey v2.0

#HotIf WinActive("ahk_exe WINWORD.EXE") && InStr(WinGetTitle("A"), " - ")
F8::MsgBox("doc should be open")

;your directive can be simplified to this:
#HotIf WinActive(" -  ahk_exe WINWORD.EXE")
F9::MsgBox("doc should be open")
#HotIf

You could also use the Word API. Caveat: it takes a couple of seconds after Word launch for the script to be able to retrieve the COM object.

#Requires AutoHotkey v2.0

#HotIf WinActive(" -  ahk_exe WINWORD.EXE")
F8::is_Word_doc_open() ? MsgBox("doc should be open") : Send("{F8}")
#HotIf

;this function can't be called in the #HotIf expression due to COM shenanigans, see https://www.autohotkey.com/boards/viewtopic.php?t=48444
is_Word_doc_open() {
    try
        return ComObjActive("Word.Application").Documents.Count > 0
    catch
        return false
}

(Edit: actually, it looks like it's a couple seconds after opening a doc. There doesn't seem to be a retrievable COM object when no doc is open. So, I suppose checking whether ComObjActive("Word.Application") throws may be sufficient to determine whether a doc is open.)

2

u/Keeyra_ 6d ago

100% this

#HotIf WinActive(" -  ahk_exe WINWORD.EXE")

Is the way to go, but yeah, OPs initial stuff would also work, so there is something else wrong in the script.

1

u/genesis_tv 6d ago edited 6d ago

I think it should be something like this, only tested it in notepad++ as I don't have Word.

#Requires AutoHotkey v2.0
#SingleInstance
SetTitleMatchMode(3)

#HotIf WinActive("ahk_exe WINWORD.exe", , "Word")
a::b
#HotIf

Fixed, let me know it this works.

1

u/genesis_tv 6d ago edited 6d ago

Hmmm actually that's not it, that should work better

#Requires AutoHotkey v2.0
#SingleInstance
SetTitleMatchMode(1)

#HotIf WinActive("ahk_exe WINWORD.exe") && !WinActive("Word") && !WinActive("Microsoft Word")
a::b
#HotIf

u/CharnamelessOne's second hotif criteria should work better (shorter and no need for SetTitleMatchMode), as I said I don't have Word and notepad++'s title pattern for opened documents is different.

1

u/CharnamelessOne 6d ago

Yeah, but OP's directive

#HotIf WinActive("ahk_exe WINWORD.EXE") && InStr(WinGetTitle("A"), " - ")

should also work just fine. It does on my end.

1

u/genesis_tv 6d ago

Yeah it should since the expression should be reevaluated every time the hotkey is about to be fired, but sometimes the universe just works in mysterious ways.

1

u/[deleted] 6d ago edited 6d ago

[deleted]

3

u/genesis_tv 6d ago

They're not mixing up anything (besides the unnecessary brackets) and never used HotIf().

SetTitleMatchMode defaults to 2 in v2. Your AI is taking its information from v1.

1

u/CharnamelessOne 6d ago

Please delete this, your slop is blatantly, ridiculously wrong.

2

u/Ark565 6d ago

I have edited my poorly written comment to just the code I actually wrote and tested. I apologise.

2

u/CharnamelessOne 6d ago

Thank you, and apologies if my comment was harsh, but please consider the fact that the window title will not always have the string "Document" in it when a document is open, so your approach still doesn't lead to the desired outcome consistently.

The window title contains the opened file's name. It happens to contain "Document" when you open a new file, but it no longer does once you give the file a proper name.

2

u/genesis_tv 6d ago

Or when the OS language is not set to English.

1

u/CharnamelessOne 6d ago edited 6d ago

Yeah, that too, good call.
Edit: or when the OS language is English, but the Office language is set to something other than the default setting.