Autohotkey
February 13, 2023

GetObject в AutoHotKey

🌰 Используйте ComObjActive(...), чтобы управлять программами

Функция ComObjActive — это аналог GetObject из Visual Basic, только в AutoHotKey. Она позволяет подключиться к программам, которые поддерживают интерфейс COM и управлять ими:

word := ComObjActive("Word.Application")
if !word
    MsgBox "Word не запущен."
else
    MsgBox "Сейчас открыт документ " word.ActiveDocument.FullName

Если программа ещё не запущена, то запустить её можно с помощью ComObject(...) — это аналог функции CreateObject из VisualBasic:

ie := ComObject("InternetExplorer.Application") ; запустить браузер
ie.Visible := true  ; Показать окно браузера

Получив в переменную объект приложения (например, word), мы можем обращаться к свойствам и методам этого приложения. Кроме того, мы можем реагировать на события, которые происходят в приложении. Для этого создадим функции с именами по шаблону ПрефиксСобытие:

WD_Quit(app) {
	; Word закрывается
}
WD_DocumentOpen(doc) {
    ; В ворде открыт новый документ
}

В этом коде WD_ — это префикс, а Quit и DocumentOpen — названия событий.

Теперь укажем, что объект word должен реагировать на события путём запуска функций, начинающихся с WD_:

ComObjConnect(word, "WD_")

Чтобы управлять сразу несколькими приложениями из одного скрипта, я использую функцию GetComApp:

GetComApp(&app, force, className, descr, eventFunctionsPrefix := "") {
	if force 
		app := ""
		if force = -1
			return   
	if app {
		return app
	}
	try {
		app := ComObjActive(className)
		Tooltip descr "`nВерсия " app.version
		SetTimer ()=>Tooltip(), -1000
		if eventFunctionsPrefix {
			ComObjConnect app, eventFunctionsPrefix
		}
		return app
	} catch {
		Tooltip descr " не найден`nGetComApp()"
		SetTimer ()=>Tooltip(), -2000
		return
	}
}

У этой функции такие параметры:

  • &app — переменная, в которую помещается объект, например &word. Знак & означает, что это указатель.
  • force — если передать 1, то произойдёт повторное подключение к объекту, даже если оно было выполнено ранее
    а если передать -1, то вернётся пустой объект. Это можно использовать для отключения от объекта приложения.
  • className — название класса приложения, например "Word.Application"
  • descr — понятное название приложения, например, "Ворд"
  • eventFunctionsPrefix — префикс для обработки событий, например, "wd_" (необязательный).

Теперь добавим функции, которые получают ссылки на нужные приложения:

GetWord(Force:=0) {
	static wd := ""
	return GetComApp(&wd, force, "Word.Application", "Word")
}
GetPoint(Force:=0) {
	static pp := ""
	return GetComApp(&pp, force, "PowerPoint.Application", "PowerPoint", "PP_")
}
GetExcel(Force:=0) {
	static xl := ""
	return GetComApp(&xl, force, "Excel.Application", "Excel", "XL_")
}
GetAcad(Force:=0) {
	static acad := ""
	return GetComApp(&acad, force, "AutoCAD.Application", "Автокад", "acad_")
}

Как их использовать? Например, в Word:

GetWord().PrintPreview := true ; Открыть предварительный просмотр в word

или так:

wd := GetWord()
wd.Dialogs(88).Show() ; Открыть диалоговое окно «Печать»

или в экселе:

xl := GetExcel()
xl.Activeworkbook.Close(false) ; Закрыть книгу без сохранения

А вот так можно освободить все переменные, хранящие ссылки на объекты приложений:

	FreeOleServers(*) {
		GetExcel(-1)
		GetWord(-1)
		GetAcad(-1)
		GetPoint(-1)
		Tooltip "Ссылки на эксель, ворд, поинт, очищены."
		SetTimer(()=>Tooltip(), 3000)
	}