Loading "cached" web pages in Chrome Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
RobbieWilkes
Posts: 14
Joined: 27 Feb 2018, 21:52

Loading "cached" web pages in Chrome

02 Mar 2018, 13:31

Hello folks, got one that I haven't been able to Google my way out of, so thought I'd come here, hat in hand, and seek the wisdom of the masters. As I've investigated further, I discovered that, although I had presented this question before, I did not really give a clear / adequate explanation of what was needed.

Not sure if I'm wording this correctly, or even understanding exactly what is going on, so please bear with me, but is there any way to load a currently "cached" web page while in Chrome?

As further explanation, here's why...

I am launching YouTube TV in Chrome kiosk mode, via AHK, and then capturing input from my MCE remote controls, for a nicer 10 foot interface. Thus far I've been able to accomplish almost everything I want, and have GREATLY improved the experience.

Currently YouTube TV has 3 different sections - Home, Library and Live, each with their own URL:

https://tv.youtube.com ; the default (home) screen
https://tv.youtube.com/library ; the recorded / on-demand shows
https://tv.youtube.com/live ; the live tv channels

I want to be able to switch between those links using the remote control (right now the numpad1 2 & 3 buttons), and have already tried simply launching the links via the Run command, but doing so takes a LOT longer than just clicking on the links.. which is almost instantaneous. Since I'm no web developer, I'm not sure what's going on behind the scenes, but one would assume that the pages are somehow being "cached", so that they just quickly appear, whereas the Run command causes a full reload.

I'm currently handling it via mouseclicks, which works well, but requires the specific coordinates of the link, and really inhibits scalability on different resolutions, etc.

Maybe I'm missing something simple... such as just simulating a mouseclick on the links, without having to know their location, but, thus far I haven't spotted the command to allow me to do that.

Any thoughts or illumination on how this is being handle by the site would be greatly appreciated.

Here's the current code for my YouTube TV launcher, and I would also love any input / suggestions on how I could improve it or do things more effectively & efficiently.

Code: Select all

;        Autohotkey script - http://www.autohotkey.com/
;
;      YouTube TV MCE Remote Control Implementation Script 
;     Created by Robbie Wilkes - [email protected]
;

Menu, Tray, Icon, YouTubeTV1.ico

#SingleInstance force
#MaxHotkeysPerInterval 500
#UseHook
#InstallKeybdHook
#Persistent
#NoEnv

ModernBrowsers := "ApplicationFrameWindow,Chrome_WidgetWin_0,Chrome_WidgetWin_1,Maxthon3Cls_MainFrm,MozillaWindowClass,Slimjet_WidgetWin_1"
LegacyBrowsers := "IEFrame,OperaWindowClass"

SendMode Input

; ------------------ Launch YouTube TV - Start ------------------
; Get YouTube TV Up & Running with the Library page

;Launch Chrome in Kiosk Mode Loading YouTubeTV
Run, "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --chrome-frame -kiosk https://tv.youtube.com 

;Sleep, 1000

;Test for the STUPID Chrome Restore Pages Error Box and Clear It if Found - Possibly resolved by launching with --app  (HURRAY)

;IfWinExist, Restore pages?
;{
;   MouseClick, left, 1900,21
;}

SLEEP 6000

;Click on Empty Space
MouseClick, left, 960, 120

; ------------------ Launch YouTube TV - End ------------------

; ------------------ Set the Cursor - Start ------------------

;Change the Cursor
Cursor = %A_ScriptDir%\mousecursor.cur
cx := 100, cy := 100
{
   SystemCursors = 32512IDC_ARROW,32513IDC_IBEAM,32514IDC_WAIT,32515IDC_CROSS
   ,32516IDC_UPARROW,32640IDC_SIZE,32641IDC_ICON,32642IDC_SIZENWSE
   ,32643IDC_SIZENESW,32644IDC_SIZEWE,32645IDC_SIZENS,32646IDC_SIZEALL
   ,32648IDC_NO,32649IDC_HAND,32650IDC_APPSTARTING,32651IDC_HELP
   
   Loop, Parse, SystemCursors, `,
   {
        Type = FileCursor
        %Type%%A_Index% := DllCall( "LoadImage", UInt,0, Str,Cursor, UInt,0x2, Int,cx, Int,cy, UInt,0x10 )
        DllCall( "SetSystemCursor", Uint,%Type%%A_Index%, Int,SubStr( A_Loopfield, 1, 5 ) )   
    }
}

; ------------------ Set the Cursor - End --------------------


; ------------------ Direction & Selection Buttons - Start ------------------

PgUP::WheelUp
PgDn::WheelDown
Enter::Click
Space::Click
;Up::MouseMove 0, -150, 1, R;
;Down::MouseMove 0, 150, 1, R
media_play_pause::k
media_prev::Home     ; Beginning of Program
media_next::End      ; End of Program
^+b::Send j          ; Rewind Button
^+f::Send l          ; Fast Forward Button
^r::Send k           ; Record Button - Just pausing until I figure out what to do with it
^E::Send c           ; Red Button - Closed Caption



i::
	sURL := GetActiveBrowserURL()
	WinGetClass, sClass, A
	If (sURL != "")
		MsgBox, % "The URL is: " sURL ""
	Else If sClass In % ModernBrowsers "," LegacyBrowsers
		MsgBox, % "The URL couldn't be determined (" sClass ")"
	Else
		MsgBox, % "Not a browser or browser not supported (" sClass ")"
sURL :=
Return

Right::
{
	sURL := GetActiveBrowserURL()
	WinGetClass, sClass, A
	if sURL contains watch
		send l
	else
		MouseMove 250, 0, 1, R
	Return
}	


Left::
{
	sURL := GetActiveBrowserURL()
	WinGetClass, sClass, A
	if sURL contains watch
		send j
	else
		MouseMove -250, 0, 1, R
	Return
}	



Up::
{
	sURL := GetActiveBrowserURL()
	WinGetClass, sClass, A
	if sURL contains watch
		send Up
	else
		MouseGetPos, xpos, ypos
;		Tooltip %xpos%`, %ypos%
		if (ypos <= 200)
		{
;			MsgBox,48,, Top,5
			Send {WheelUp}
		}
		else
			MouseMove 0, -200, 1, R
	Return
}


Down::
{
	sURL := GetActiveBrowserURL()
	WinGetClass, sClass, A
	if sURL contains watch
		send {Esc}
	else
		MouseGetPos, xpos, ypos
;		Tooltip %xpos%`, %ypos%
		if (ypos >= 880)
		{
;			MsgBox,48,, Bottom,5
			Send {WheelDown}
		}
		else
			MouseMove 0, 200, 1, R
	Return
}


;Stop Button - Pause & Browser_Back
media_stop::
{
	Click
	Send {Esc}
	Return
}

;BackSpace - Previous Page
Backspace::
{
	Send {Browser_Back}
	Return
}


;Library - 1 Button
Numpad1::
{
  	MouseClick, left, 840, 30
;  	MouseClick, left, 840, 150
  	MouseClick, left, 960, 120
  	Return
}

;Home - 2 Button
Numpad2::
{
  	MouseClick, left, 960, 30
;  	MouseClick, left, 960, 150
  	MouseClick, left, 960, 120
  	Return
}

;Live - 3 button
Numpad3::
{
  	MouseClick, left, 1050, 30
;  	MouseClick, left, 1050, 150
  	MouseClick, left, 960, 120
  	Return
}

;Library - 4 Button
Numpad4::
{
	run, https://tv.youtube.com/library
	Return
}

;Home - 5 Button
Numpad5::
{
	run, https://tv.youtube.com/
	Return
}

;Home - 6 Button
Numpad6::
{
	run, https://tv.youtube.com/live
	Return
}


;CLEAR BUTTON - Closes and Ends Script
!F4::
Clear()
{
   	SPI_SETCURSORS := 0x57
   	DllCall( "SystemParametersInfo", UInt,SPI_SETCURSORS, UInt,0, UInt,0, UInt,0 )
   	Send !{f4} 
   	ExitApp
}


;BIG GREEN BUTTON - Closes and Ends Scripts
#!Enter::
BigGreenButton()
{
   	SPI_SETCURSORS := 0x57
   	DllCall( "SystemParametersInfo", UInt,SPI_SETCURSORS, UInt,0, UInt,0, UInt,0 )
   	Send !{f4} 
   	ExitApp
}

; ------------------ Direction & Selection Buttons - End ------------------


; ----------------------- Special KeyStrokes - Start -------------------


;Ctrl-Alt-K - TaskKill for Chrome for Testing "Restore Page" Error
^!K::
KillChrome()
{
	Runwait, taskkill /im chrome.exe /f
   	SPI_SETCURSORS := 0x57
	DllCall( "SystemParametersInfo", UInt,SPI_SETCURSORS, UInt,0, UInt,0, UInt,0 )
	ExitApp
}

;Ctrl-Alt-S - Just Exit the Script
^!S::
StopScript()
{
   	SPI_SETCURSORS := 0x57
   	DllCall( "SystemParametersInfo", UInt,SPI_SETCURSORS, UInt,0, UInt,0, UInt,0 )
   	ExitApp
}


; ----------------------- Special KeyStrokes - End  -------------------

RemoveToolTip:
SetTimer, RemoveToolTip, on
ToolTip
return

; --------------- GetActiveBrowserURL Function by atnbueno - Start -----------------
GetActiveBrowserURL() {
	global ModernBrowsers, LegacyBrowsers
	WinGetClass, sClass, A
	If sClass In % ModernBrowsers
		Return GetBrowserURL_ACC(sClass)
	Else If sClass In % LegacyBrowsers
		Return GetBrowserURL_DDE(sClass) ; empty string if DDE not supported (or not a browser)
	Else
		Return ""
}

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) {
	global 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 != "") and (SubStr(sURL, 1, 4) != "http")) ; Modern browsers omit "http://"
		sURL := "http://" sURL
	If (sURL == "")
		nWindow := -1 ; Don't remember the window if there is no URL
	Return sURL
}

; "GetAddressBar" based in code by uname
; Found at http://autohotkey.com/board/topic/103178-/?p=637687

GetAddressBar(accObj) {
	Try If ((accObj.accRole(0) == 42) and IsURL(accObj.accValue(0)))
		Return accObj
	Try If ((accObj.accRole(0) == 42) and IsURL("http://" accObj.accValue(0))) ; Modern browsers omit "http://"
		Return accObj
	For nChild, accChild in Acc_Children(accObj)
		If IsObject(accAddressBar := GetAddressBar(accChild))
			Return accAddressBar
}

IsURL(sURL) {
	Return RegExMatch(sURL, "^(?<Protocol>https?|ftp)://(?<Domain>(?:[\w-]+\.)+\w\w+)(?::(?<Port>\d+))?/?(?<Path>(?:[^:/?# ]*/?)+)(?:\?(?

<Query>[^#]+)?)?(?:\#(?<Hash>.+)?)?$")
}

; The code below is part of the Acc.ahk Standard Library by Sean (updated by jethrow)
; Found at http://autohotkey.com/board/topic/77303-/?p=491516

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"
	}
}

; --------------- GetActiveBrowserURL Function - Start -----------------

Last edited by RobbieWilkes on 02 Mar 2018, 18:38, edited 1 time in total.
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: Loading "cached" web pages in Chrome

02 Mar 2018, 14:56

Do the URLs change? I believe Ctrl + L in Chrome selects the address bar, so you could simply have a hoykey that presses Ctrl + L and then types in the correct address.
User avatar
RobbieWilkes
Posts: 14
Joined: 27 Feb 2018, 21:52

Re: Loading "cached" web pages in Chrome

02 Mar 2018, 18:23

MaxAstro wrote:Do the URLs change? I believe Ctrl + L in Chrome selects the address bar, so you could simply have a hoykey that presses Ctrl + L and then types in the correct address.
Thanks for respondig MaxAstro.

Yes, the URLs do change (I'm actually monitoring and using that to determine how buttons function), but, as I'm running it in kiosk mode, the address bar is unavailable.

In any event, I have tested, while not in KIOSK, and, if the URL is changed via the address bar, a similar load-time occurs as is experienced with the Run statement. The load, when clicking the links, is nearly instantaneous, which is what led me to use the "caching" terminology... though I have no idea if that is what is actually occurring.
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: Loading "cached" web pages in Chrome

05 Mar 2018, 10:43

Unfortunately I don't think there is a way to locate and click a link directly... If the relative position of the link doesn't change you might be able to tab to it? Otherwise you probably need to write a whole thing to determine the monitor resolution and then click the link based on where it appears with that resolution.
User avatar
RobbieWilkes
Posts: 14
Joined: 27 Feb 2018, 21:52

Re: Loading "cached" web pages in Chrome

06 Mar 2018, 15:41

MaxAstro wrote:Unfortunately I don't think there is a way to locate and click a link directly... If the relative position of the link doesn't change you might be able to tab to it? Otherwise you probably need to write a whole thing to determine the monitor resolution and then click the link based on where it appears with that resolution.
Thanks for responding MaxAstro. I was kinda guessing that might be the case, but hoped I'd find a direct solution in AHK. I'm guessing that, to accomplish what I'm trying to do, it would have to be in calling to something like a VB or javascript, since they can interface directly with Chrome, rather than just interact with it topically. Looks like I've got a lot of learning to do. :D

Much appreciated!
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: Loading "cached" web pages in Chrome  Topic is solved

08 Mar 2018, 11:04

Honestly if you can predict where the links will be in the tab order, tabbing to them might be a workable solution. If there is an area of the screen you can click to make sure there's no cursor focus (somewhere in the upper left that will be empty space at most resolutions), then you can establish a baseline for tabbing to the link.
User avatar
RobbieWilkes
Posts: 14
Joined: 27 Feb 2018, 21:52

Re: Loading "cached" web pages in Chrome

08 Mar 2018, 12:25

MaxAstro wrote:Honestly if you can predict where the links will be in the tab order, tabbing to them might be a workable solution. If there is an area of the screen you can click to make sure there's no cursor focus (somewhere in the upper left that will be empty space at most resolutions), then you can establish a baseline for tabbing to the link.
Geez! Maybe if you hit me in the head with a hammer it would have CLICKED the first time you said it, but I was so focused on clicking, I didn't even test the TAB suggestion. DUH!

You're the man MaxAstro!!

Yes, I can tab between the options!! I just need to determine the best starting location on which to start tabbing, as the positions do change, once the video playback has been activated. It's not a severe change, but one that might cause clicking on the screen to activate something unintended.

There is a logo that sits on the same line as the options, and I'm currently playing with ImageSearch to try and use the found coordinates to act as a "hinge" from which to begin tabbing (or do nothing if not found aka on the video screen). Of course, I'm not having much luck with it right now, as the logo is a transparent .png and it's not finding it. :lol:

Code: Select all


	ImageSearch, FoundX, FoundY, 0, 0, A_ScreenWidth, A_ScreenHeight, YTTVLogo1.png
	{
	if ErrorLevel = 2
    		MsgBox Could not conduct the search.
	else if ErrorLevel = 1
    		MsgBox Icon could not be found on the screen.
	else
    		MsgBox The icon was found at %FoundX%x%FoundY%.
	}
Return

I've even gone so far as to snip the logo from the screen itself, and saved as a jpg, thinking that would make it easier to find, but no luck.

Still, I am having fun learning more about AHK and trying out new functions that I have never played with before.

Thanks again for putting me on the right track!
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: Loading "cached" web pages in Chrome

08 Mar 2018, 12:50

Instead of using AHK's built in ImageSearch, I would suggest using the GDIP image search library. The code is complex, but well documented, and you basically just need to #include the files and then call the appropriate functions. The GDIP search is much faster and a LOT more flexible.

I've attached the two ahk files you'll need to include. You can Google something like "AHK GDIP" for examples.
Attachments
Gdip_ImageSearch.ahk
(32.59 KiB) Downloaded 41 times
Gdip_All.ahk
(95.45 KiB) Downloaded 38 times
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: Loading "cached" web pages in Chrome

08 Mar 2018, 12:51

Also. This might be silly, but considering the GDIP search is powerful: If the background of the site doesn't change, have you considered clipping out a picture of the link itself and image searching that?

And to save you some time searching, here's a quick example of what doing an image match with GDIP looks like:

Code: Select all

if !pToken := Gdip_Startup()	; Start GDI+ for advanced image handling
{
	MsgBox, 48, % "GDI+ error!", % "GDI+ failed to start. Please ensure you have gdiplus on your system!"
	return
}

pNeedle := Gdip_CreateBitmapFromFile(NeedlePath)	; Create the needle from a saved image
pHwnd := WinExist("A")
pHaystack := Gdip_BitmapFromHWND(pHwnd)		; Create the haystack from the active window
Gdip_ImageSearch(pHaystack, pNeedle, ImageCoords)
Pos := InStr(ImageCoords, ",")				; Split the coordinates into X and Y
aX := SubStr(ImageCoords, 1, Pos-1)
aY := SubStr(ImageCoords, Pos+1)

Gdip_DisposeImage(pNeedle)	; You don't need to do this, but it's good drill to free up the memory GDIP uses
Gdip_DisposeImage(pHaystack)
Gdip_Shutdown(pToken)
Last edited by MaxAstro on 08 Mar 2018, 12:57, edited 1 time in total.
gregster
Posts: 8921
Joined: 30 Sep 2013, 06:48

Re: Loading "cached" web pages in Chrome

08 Mar 2018, 12:55

Better use a lossless picture format like bmp or png than lossy jgp.
User avatar
RobbieWilkes
Posts: 14
Joined: 27 Feb 2018, 21:52

Re: Loading "cached" web pages in Chrome

10 Mar 2018, 15:26

Well, I actually managed to find the image by taking both of your advice and saving a better quality snip.

Finds it perfectly, and I'm able to click on it, and use the coordinates as a reference point for other actions. :bravo:

But (isn't there ALWAYS a but) when the screen shifts down, following the start of the a video, it can't find it anymore... which makes absolutely zero sense to me. I mean, the only thing that has changed, as far as I can tell, are the Y coordinates. The associated link still works just fine, but ImageSearch just can't find it. :crazy:

Code: Select all


{
	CoordMode, Pixel, Screen
	ImageSearch, FoundX, FoundY, 0, 0, A_ScreenWidth, A_ScreenHeight, *TransBlack YTTVLogo.png
	if !ErrorLevel
		{
		tooltip %FoundX% x %FoundY%
		Click %FoundX%, %FoundY%
		Return
		}
	else if ErrorLevel = 2
		{
    		MsgBox Error - Possibly Missing Compare Image File
		Return
		}
	else if ErrorLevel = 1
		{
		MsgBox Image Not found on Screen
		Return
		}
}


I've pulled over the GDip libraries and have looked at your code MaxAstro, but I'm gonna need more coffee and reference code to understand how to implement. Thanks for the new avenues to try. I'm having fun... which is hard for my wife to understand when it's riddled with bursts of frustration. :lol:

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: skeerrt, vmech and 143 guests