Hi!
I'd like to write an app which will be displaying different GUIs with tools depending on the active controls in MS Word. However, I don't know how to catch the context, e.g. how will my application know when a table or drawing is active. For example, in the MS Word interface, after selecting an image, the "Drawing Tools" ribbon appears. Is there any related event that I could catch?
Do you know what could I do?
Thanks in advice
Catching the context in MS Word
Re: Catching the context in MS Word
The Word title bar changes according to the selected object, so you could run a Loop or SetTimer containing an ImageSearch or ControlGet. In my version of Word, for example, selecting an image enables the control, "NetUIHWND1", which has a tooltip called, "Repeat Format Object".
Re: Catching the context in MS Word
Hello
You can catch COM events like this:
Then you can see there is an event "WindowSelectionChange".
You can catch COM events like this:
Code: Select all
; Open a MS Word window before running this script
wd := Word_Get()
ComObjConnect(wd, new catchComEvents)
Return
class catchComEvents
{
__New() {
this.info := new infoWindow("x0 y0", "Monitoring COM Events...")
}
__Call(Name, Params*) {
Loop, % Params.MaxIndex() - 1 { ; Skip the last parameter (ComObject)
sParams .= (A_Index>1 ? "," : "") . Params[A_Index]
}
this.info.add(Name " " sParams)
}
}
class infoWindow
{
__New(Options := "", Title := "") {
preDefaultGui := A_DefaultGui
RegExMatch(Options, "i)\bw\K\d+\b", w) ? "" : (w:=400)
RegExMatch(Options, "i)\bh\K\d+\b", h) ? "" : (h:=200)
Gui, New, +HWNDhGui +Resize +Label_infoWindow_On
Gui, Margin, 0, 0
Gui, Add, Edit, w%w% h%h% HWNDhEdit ReadOnly -Wrap +HScroll
Gui, Show, w%w% h%h% %Options%, %Title%
Gui, %preDefaultGui%:Default
this.hEdit := hEdit
this.hGui := hGui
Return this
_infoWindow_OnClose:
Gui, %A_Gui%:Destroy
Return
_infoWindow_OnSize:
if (A_EventInfo != 1)
GuiControl, %A_Gui%:Move, Edit1, w%A_GuiWidth% h%A_GuiHeight%
Return
}
__Delete() {
try
Gui, % this.hGui ":Destroy"
}
Add(ByRef Text) {
this.Edit_AppendLine(this.hEdit, Text)
}
Edit_AppendLine(hEdit, ByRef line) {
pLine := &(line .= "`r`n")
SendMessage, 0x000E, 0, 0,, ahk_id %hEdit% ; WM_GETTEXTLENGTH
SendMessage, 0x00B1, %ErrorLevel%, %ErrorLevel%,, ahk_id %hEdit% ; EM_SETSEL
SendMessage, 0x00C2, 0, %pLine%,, ahk_id %hEdit% ; EM_REPLACESEL
}
}
; Word_Get.ahk: burque505, modified from
; Excel_Get by jethrow (modified)
; Forum: https://autohotkey.com/boards/viewtopic.php?f=6&t=31840
; Github: https://github.com/ahkon/MS-Office-COM-Basics/blob/master/Examples/Excel/Excel_Get.ahk
; With subsequent mods by opiuetasfd - thanks!
Word_Get(WinTitle:="ahk_class OpusApp", _WwG#:=1) {
static h := DllCall("LoadLibrary", "Str", "oleacc", "Ptr")
WinGetClass, WinClass, %WinTitle%
if !(WinClass == "OpusApp")
return "Window class mismatch. (" WinClass ")"
ControlGet, hwnd, hwnd,, _WwG%_WwG#%, %WinTitle%
if (ErrorLevel)
return "Error accessing the control hWnd. (" ErrorLevel ")"
VarSetCapacity(IID_IDispatch, 16)
NumPut(0x46000000000000C0, NumPut(0x0000000000020400, IID_IDispatch, "Int64"), "Int64")
if (hr := DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", -16, "Ptr", &IID_IDispatch, "Ptr*", pacc)) != 0
return "Error calling AccessibleObjectFromWindow. ("
. (hr = 0x80070057 ? "E_INVALIDARG" : hr = 0x80004002 ? "E_NOINTERFACE" : hr) ")"
window := ComObject(9, pacc, 1)
if ComObjType(window) != 9
return "Error wrapping the window object."
try return window.Application
catch e
return "Error accessing the application object. (" SubStr(e.message, 1, 10) ")"
}
Then you can see there is an event "WindowSelectionChange".
Code: Select all
#Persistent
wd := Word_Get()
ComObjConnect(wd, WordEvent)
return
class WordEvent
{
WindowSelectionChange(Selection) {
static wdWithInTable := 12, wdSelectionShape := 8
if Selection.Information(wdWithInTable)
ToolTip, table active
else if (Selection.type = wdSelectionShape)
ToolTip, Shape active
}
}
; Word_Get.ahk: burque505, modified from
; Excel_Get by jethrow (modified)
; Forum: https://autohotkey.com/boards/viewtopic.php?f=6&t=31840
; Github: https://github.com/ahkon/MS-Office-COM-Basics/blob/master/Examples/Excel/Excel_Get.ahk
; With subsequent mods by opiuetasfd - thanks!
Word_Get(WinTitle:="ahk_class OpusApp", _WwG#:=1) {
static h := DllCall("LoadLibrary", "Str", "oleacc", "Ptr")
WinGetClass, WinClass, %WinTitle%
if !(WinClass == "OpusApp")
return "Window class mismatch. (" WinClass ")"
ControlGet, hwnd, hwnd,, _WwG%_WwG#%, %WinTitle%
if (ErrorLevel)
return "Error accessing the control hWnd. (" ErrorLevel ")"
VarSetCapacity(IID_IDispatch, 16)
NumPut(0x46000000000000C0, NumPut(0x0000000000020400, IID_IDispatch, "Int64"), "Int64")
if (hr := DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", -16, "Ptr", &IID_IDispatch, "Ptr*", pacc)) != 0
return "Error calling AccessibleObjectFromWindow. ("
. (hr = 0x80070057 ? "E_INVALIDARG" : hr = 0x80004002 ? "E_NOINTERFACE" : hr) ")"
window := ComObject(9, pacc, 1)
if ComObjType(window) != 9
return "Error wrapping the window object."
try return window.Application
catch e
return "Error accessing the application object. (" SubStr(e.message, 1, 10) ")"
}
Re: Catching the context in MS Word
That's cool!