1

Тема: AHK: Получить ссылку из неактивного окна браузера

Можно ли получить содержимое адресной строки (ссылку) из свернутого или неактивного окна Мозиллы или Оперы?

2

Re: AHK: Получить ссылку из неактивного окна браузера

f11::
msgbox % GetBrowserURL_DDE("MozillaWindowClass")

GetBrowserURL_DDE(sClass) {
	WinGet, sServer, ProcessName, % "ahk_class " sClass
	StringTrimRight, sServer, sServer, 4
	iCodePage := A_IsUnicode ? 0x04B0 : 0x03EC ; 0x04B0 = CP_WINUNICODE, 0x03EC = CP_WINANSI
	DllCall("DdeInitialize", "UPtrP", idInst, "Uint", 0, "Uint", 0, "Uint", 0)
	hServer := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", sServer, "int", iCodePage)
	hTopic := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", "WWW_GetWindowInfo", "int", iCodePage)
	hItem := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", "0xFFFFFFFF", "int", iCodePage)
	hConv := DllCall("DdeConnect", "UPtr", idInst, "UPtr", hServer, "UPtr", hTopic, "Uint", 0)
	hData := DllCall("DdeClientTransaction", "Uint", 0, "Uint", 0, "UPtr", hConv, "UPtr", hItem, "UInt", 1, "Uint", 0x20B0, "Uint", 10000, "UPtrP", nResult) ; 0x20B0 = XTYP_REQUEST, 10000 = 10s timeout
	sData := DllCall("DdeAccessData", "Uint", hData, "Uint", 0, "Str")
	DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hServer)
	DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hTopic)
	DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hItem)
	DllCall("DdeUnaccessData", "UPtr", hData)
	DllCall("DdeFreeDataHandle", "UPtr", hData)
	DllCall("DdeDisconnect", "UPtr", hConv)
	DllCall("DdeUninitialize", "UPtr", idInst)
	csvWindowInfo := StrGet(&sData, "CP0")
	StringSplit, sWindowInfo, csvWindowInfo, `" ;"; comment to avoid a syntax highlighting issue in autohotkey.com/boards
	Return sWindowInfo2
}
+ DD

3 (изменено: stealzy, 2016-09-11 09:09:28)

Re: AHK: Получить ссылку из неактивного окна браузера

Malcev, а для Оперы и остальных браузеров на Blink?
Дабы не изобретать заново изобретенное, рекомендую универсальную библиотеку для всех браузеров:
https://translate.google.com/#ru/en/пол … и браузера.
http://ru.lmgtfy.com/?q=get+the+content … autohotkey.
Если хотим из неактивного окна, заменяем "A" в командах на идентификатор окна браузера.

+ DD

4

Re: AHK: Получить ссылку из неактивного окна браузера

Для оперы также должно работать, только класс оперы надо поставить.
Свой код я вырезал из той же универсальной библиотеки, только непонятно зачем автор скрипта с фаерфоксом использует ACC, когда через DDE быстрее.

5 (изменено: stealzy, 2016-09-11 17:01:46)

Re: AHK: Получить ссылку из неактивного окна браузера

Мы ведь не про Opera Presto говорим? На Blink не работает, как и на всех прочих хромоногах.
По поводу firefox'a - я сам удивился, т.к. в прошлой версии (а она у меня сохранилась :-) он использовал DDE.
Почитав ветку, узнал, что последний firefox nightly dde уже вроде не поддерживает.

Медленно происходит только первый поиск контрола. Потому что сейчас ищется по всем контролам браузера (для firefox он проходит 360 контролов у меня). Со второго раза он быстрее DDE.
Я предложил использовать предустановленные пути для старта поиска контролов в ветке библиотеки, подожду отзывов у какого какие пути - может совсем разные у всех.

6

Re: AHK: Получить ссылку из неактивного окна браузера

Круто, спасибо!

7

Re: AHK: Получить ссылку из неактивного окна браузера

Malcev, у меня, когда окно FF свёрнуто, скрипт, который ты привёл, выдает пустую строку.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

8

Re: AHK: Получить ссылку из неактивного окна браузера

Странно. У меня на нескольких компьютерах FF 48.0.2 на win7 работает.

9

Re: AHK: Получить ссылку из неактивного окна браузера

А, понял, у меня просто был ещё почтовый клиент thunderbird в это время открыт, он имеет тот же класс.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

10

Re: AHK: Получить ссылку из неактивного окна браузера

stealzy, какое именно окно?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

11

Re: AHK: Получить ссылку из неактивного окна браузера

Malcev пишет:
f11::
msgbox % GetBrowserURL_DDE("MozillaWindowClass")
...

Почему, когда запущено две Оперы, с классами "Chrome_WidgetWin_1" и "OperaWindowClass", при активном первом окне — выводится URL второго?

12

Re: AHK: Получить ссылку из неактивного окна браузера

Потому что:

На Blink не работает, как и на всех прочих хромоногах.

Используйте полный вариант библиотеки по ссылке с 5 поста.

+ DD

13

Re: AHK: Получить ссылку из неактивного окна браузера

Не могу понять, по какой причине приведенный ниже код отдельно работает, но если запускать из моего постоянного скрипта, со множеством меток, по горячей клавише выводит пустое окно? —


f6::
	;nTime := A_TickCount
	WinGetClass, sClass, A
	URL := GetBrowserURL(sClass)
	MsgBox, % URL
Return


GetBrowserURL(sClass) {
	Static AccBrowsersClass := "MozillaWindowClass,Chrome_WidgetWin_0,Chrome_WidgetWin_1,Maxthon3Cls_MainFrm,Slimjet_WidgetWin_1"
	Static DDEBrowsersClass := "MozillaWindowClass,IEFrame,OperaWindowClass"
	If sClass In % AccBrowsersClass
		Return GetBrowserURL_ACC(sClass)
	Else If sClass In % DDEBrowsersClass
		Return GetBrowserURL_DDE(sClass)
}
GetBrowserURL_DDE(sClass) {
	WinGet, sServer, ProcessName, % "ahk_class " sClass
	StringTrimRight, sServer, sServer, 4
	iCodePage := A_IsUnicode ? 0x04B0 : 0x03EC ; 0x04B0 = CP_WINUNICODE, 0x03EC = CP_WINANSI
	DllCall("DdeInitialize", "UPtrP", idInst, "Uint", 0, "Uint", 0, "Uint", 0)
	hServer := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", sServer, "int", iCodePage)
	hTopic := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", "WWW_GetWindowInfo", "int", iCodePage)
	hItem := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", "0xFFFFFFFF", "int", iCodePage)
	hConv := DllCall("DdeConnect", "UPtr", idInst, "UPtr", hServer, "UPtr", hTopic, "Uint", 0)
	hData := DllCall("DdeClientTransaction", "Uint", 0, "Uint", 0, "UPtr", hConv, "UPtr", hItem, "UInt", 1, "Uint", 0x20B0, "Uint", 10000, "UPtrP", nResult) ; 0x20B0 = XTYP_REQUEST, 10000 = 10s timeout
	sData := DllCall("DdeAccessData", "Uint", hData, "Uint", 0, "Str")
	DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hServer)
	DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hTopic)
	DllCall("DdeFreeStringHandle", "UPtr", idInst, "UPtr", hItem)
	DllCall("DdeUnaccessData", "UPtr", hData)
	DllCall("DdeFreeDataHandle", "UPtr", hData)
	DllCall("DdeDisconnect", "UPtr", hConv)
	DllCall("DdeUninitialize", "UPtr", idInst)
	csvWindowInfo := StrGet(&sData, "CP0")
	StringSplit, sWindowInfo, csvWindowInfo, `" ;"; comment to avoid a syntax highlighting issue in autohotkey.com/boards
	Return sWindowInfo2
}
GetBrowserURL_ACC(sClass) {
	static nWindow, accAddressBar
	If (nWindow != WinExist("ahk_class " sClass)) ; reuses accAddressBar if it's the same window
	{
		nWindow := WinExist("ahk_class " sClass)
		accAddressBar := GetAddressBar(Acc_ObjectFromWindow(nWindow))
	}
	Try sURL := accAddressBar.accValue(0)
	If (sURL == "") {
		WinGet, nWindows, List, % "ahk_class " sClass ; In case of a nested browser window as in the old CoolNovo (TO DO: check if still needed)
		If (nWindows > 1) {
			accAddressBar := GetAddressBar(Acc_ObjectFromWindow(nWindows2))
			Try sURL := accAddressBar.accValue(0)
		}
	}
	If (sURL == "")
		nWindow := -1 ; Don't remember the window if there is no URL
	Return sURL
}
GetAddressBar(accObj, accPath:="") {
	; static a:=0
	; ToolTip % a++ ; 360 for firefox, 47 for modern Opera
	n := 0
	Try If ((accObj.accRole(0) == 42) and accObj.accValue(0))
		Return accObj
	For nChild, accChild in Acc_Children(accObj) {
		n++
		currentPath := accPath n "."
		;ToolTip % currentPath
		If IsObject(accAddressBar := GetAddressBar(accChild, currentPath)) {
			Return accAddressBar
		}
	}
}
;~LButton::ToolTip

Acc_Init() {
	static h
	If Not h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromWindow(hWnd, idObject = 0) {
	Acc_Init()
	If DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr", -VarSetCapacity(IID,16)+NumPut(idObject==0xFFFFFFF0?0x46000000000000C0:0x719B3800AA000C81,NumPut(idObject==0xFFFFFFF0?0x0000000000020400:0x11CF3C3D618736E0,IID,"Int64"),"Int64"), "Ptr*", pacc)=0
	Return ComObjEnwrap(9,pacc,1)
}
Acc_Query(Acc) {
	Try Return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}
Acc_Children(Acc) {
	If ComObjType(Acc,"Name") != "IAccessible"
		ErrorLevel := "Invalid IAccessible Object"
	Else {
		Acc_Init(), cChildren:=Acc.accChildCount, Children:=[]
		If DllCall("oleacc\AccessibleChildren", "Ptr",ComObjValue(Acc), "Int",0, "Int",cChildren, "Ptr",VarSetCapacity(varChildren,cChildren*(8+2*A_PtrSize),0)*0+&varChildren, "Int*",cChildren)=0 {
			Loop %cChildren%
				i:=(A_Index-1)*(A_PtrSize*2+8)+8, child:=NumGet(varChildren,i), Children.Insert(NumGet(varChildren,i-8)=9?Acc_Query(child):child), NumGet(varChildren,i-8)=9?ObjRelease(child):
			Return Children.MaxIndex()?Children:
		} Else
			ErrorLevel := "AccessibleChildren DllCall Failed"
	}
}

14

Re: AHK: Получить ссылку из неактивного окна браузера

Оказалось, мешала строка в моём коде:

DetectHiddenWindows, on

Перед действием её можно отключать (off), а потом включать.