AutoHotkey Community

It is currently May 26th, 2012, 3:39 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: March 17th, 2009, 8:57 pm 
Offline

Joined: October 9th, 2006, 8:19 pm
Posts: 236
Location: Finland
Although AutoHotkey Help is splendid, it can be improved.
Actually, the annoyance is caused by the browser, "Microsoft® HTML Help Executable".
It doesn't show the page title/header on the title bar, so it isn't seen when scrolled down.

My script fixes the problem.
In addition to the title it shows the header, if there's only one header of same type ( eg. <H2>).

It retrieves the source code using Get HTML source code from current window in IE.

Tested with AutoHotkey.chm and VirtualDub.chm.

Requires COM Standard Library.

Code:
AutoTrim Off

#IfWinActive ahk_class HH Parent

~LButton Up::
MouseGetPos, m_x, m_y, m_hw_target
SendMessage, 0x84, , (m_y << 16)|m_x, , ahk_id %m_hw_target%
If (ErrorLevel = 3 Or ErrorLevel = 20)
   Return
~Enter::
~NumPadEnter::
~!Right::
~!Left::

;Get HTML source code from current window in IE
ControlGet, hIESvr, Hwnd,, Internet Explorer_Server1, ahk_class HH Parent ;  IEFrame
WinGetClass, class, ahk_id %hIESvr%
If (!hIESvr or class != "Internet Explorer_Server")
   ExitApp
COM_CoInitialize()
WM_HTML_GETOBJECT := DllCall("RegisterWindowMessage", "str", "WM_HTML_GETOBJECT")
SendMessage, WM_HTML_GETOBJECT, , , , ahk_id %hIESvr%
lResult := ErrorLevel
DllCall("oleacc\ObjectFromLresult", "uint", lResult
, "uint", COM_GUID4String(IID_IHTMLDocument2,"{332C4425-26CB-11D0-B483-00C04FD90119}")
, "int", 0, "uint*", pDoc)
DocEle:=COM_Invoke(pDoc, "documentElement")
htmlcode:=COM_Invoke(DocEle,"innerHTML")

;search title and header and include it/them into window title bar
title_start := InStr(htmlcode, "<TITLE>")
title_end := InStr(htmlcode, "</TITLE>")
title_length := title_end - title_start - 7
header =
Loop 9
{
   header_code := "H" . A_Index . ">"
   header_start := InStr(htmlcode, "<" . header_code)
   If header_start
   {
      header_end := InStr(htmlcode, "</" . header_code)
      header_length := header_end - header_start - 4
      header := SubStr(htmlcode, header_start + 4, header_length)
      Loop
      {
         tag_start := InStr(header, "<")
         If !tag_start
            Break
         tag_end := InStr(header, ">")
         tag := SubStr(header, tag_start, tag_end - tag_start + 1)
         StringReplace header, header, %tag%, , All
      }
      StringReplace header, header, &amp;, &, All
      multi_header? := InStr(htmlcode, "<" . header_code, FALSE, header_end + 4)
         If multi_header?
            header =
      Break
   }
}
title := SubStr(htmlcode, title_start + 7, title_length)
If (header = title)
   header =
Else
   If header
      header := " <" . header . ">"
WinGetTitle, wT
; StringReplace, wT, wT, AutoHotkey, AHK ; Addit. space for title+header
m := InStr(wT, "-")
If m
   wT := SubStr(wT, 1, InStr(wT, "-") - 2)
WinSetTitle, , , %wT% - %title%%header%
Return


Additional information: Microsoft Compiled HTML Help.

_________________
Pekka Vartto


Last edited by svi on March 19th, 2009, 8:03 am, edited 3 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 17th, 2009, 9:26 pm 
Offline

Joined: May 2nd, 2006, 11:16 pm
Posts: 800
Location: Greeley, CO
It works, but I get a ton of COM errors (from both versions).

_________________
Image
SoggyDog
Dwarf Fortress:
"The most intriguing game I've ever played."


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 17th, 2009, 9:48 pm 
Offline

Joined: October 9th, 2006, 8:19 pm
Posts: 236
Location: Finland
Maybe you're using Vista?

I've never got any errors (XP SP2).

Does Get HTML source code from current window in IE work for you?

_________________
Pekka Vartto


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 17th, 2009, 10:02 pm 
it works on win7 without errors.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: March 17th, 2009, 10:16 pm 
Offline

Joined: October 9th, 2006, 8:19 pm
Posts: 236
Location: Finland
I just got the first COM error when I closed VirtualDub Help (AutoHotkey Help still open).
I've got to see it later (it's almost midnight in Finland).

Edit:
I've corrected the original scripts to "ignore" clicks on SysMenu or Close buttons to prevent error message when closing the Help window with "left" mouse button.

_________________
Pekka Vartto


Last edited by svi on March 18th, 2009, 2:43 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2009, 1:25 am 
Offline

Joined: July 30th, 2007, 11:32 pm
Posts: 581
Nice work!
This is especially useful when you have multiple AHK help windows open.
I removed the whole WinGetTitle part so that the window title becomes the page title (with no "AHK - " before). Very useful!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2009, 10:29 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
How about including more detail of where the user navigated to? In the AutoHotkey help file, there are several very large pages which cover very broad topics. It can be narrowed down by the part after # in the URL, though the user can scroll away.

The current URL (which includes the path of the chm file) can simply be retrieved with COM_Invoke(pDoc,"URL").

I believe it would also be feasible to use DOM/MSHTML to determine which part of the document the user is viewing.

Edit: I've been experimenting with DOM. From DocEle:= (inclusive) to the end of the title := line can be replaced with:
Code:
Loop 9 {   ; Get all H%A_Index% elements.
    if pAllH := COM_Invoke(pDoc,"all.tags", "H" A_Index)
    {   ; If there is exactly one,
        if (COM_Invoke(pAllH,"length") = 1) && (pH := COM_Invoke(pAllH,"item",0))
        {   ; use its text.
            header := COM_Invoke(pH,"innerText")
            COM_Release(pH), COM_Release(pAllH)
            break
        }
        COM_Release(pAllH)
    }
} ; Get the title directly via DOM.
title := COM_Invoke(pDoc,"title")
Additionally, the #hash part of the URL (i.e. bookmark) may be included by inserting this before WinGetTitle, wT:
Code:
if (hash := COM_Invoke(pDoc,"location.hash"))
    header .= " - " hash

Unfortunately, the changes give me occasional "Access is denied" errors attempting to access random DOM properties. I got around it by calling COM_Error() to disable error reporting.


Btw, please do not include the contents of COM.ahk directly in a post. Aside from the reaction Sean has had to this in the past, because it has very long lines which don't wrap, it causes a lot of otherwise unnecessary horizontal scrolling (especially on lower resolution screens). This makes posts painful to read.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2009, 9:31 pm 
Offline

Joined: October 9th, 2006, 8:19 pm
Posts: 236
Location: Finland
I'm not going to add the #hash part (because I personally don't need it) unless someone shows a relevant use of it. When you scroll the window, the information is outdated. Anyone can add those two lines themselves/himself :roll: .
Thanks anyway for showing such a simple way.

Lexikos wrote:
Btw, please do not include the contents of COM.ahk directly in a post...it causes a lot of otherwise unnecessary horizontal scrolling (especially on lower resolution screens).

I removed it.

I doubted a little if it was appropriate to include part of a funtion library, but COM.ahk is so big, and I don't have another use for it so far.
If someone else wants to edit (remove unused functions) COM.ahk for his personal use, I say: it'll take time...

I noticed the hor. scrolling issue (fullscreen, width 1280), was going to wrap those few lines...

I'd like to show back/forward items, with a hotkey.
Is the simpliest way to log all urls, or is there a way to get them some other way?

_________________
Pekka Vartto


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 19th, 2009, 12:37 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
Quote:
unless someone shows a relevant use of it
Navigating to "A_EventInfo" for instance, shows "Variables and Expressions - #EventInfo" instead of "Variables and Expressions". There are very many entry-points into this page.
Quote:
When you scroll the window, the information is outdated.
That's what I meant to suggest by "though the user can scroll away." It is useful mainly on very large pages, where it is already difficult to quickly find information by scrolling. Also, I tend to navigate by the index between topics, and scroll only within a topic.
Quote:
Anyone can add those two lines themselves/himself :roll: .
Yes, now that I've posted them...
Quote:
I'd like to show back/forward items, with a hotkey.
Is the simpliest way to log all urls, or is there a way to get them some other way?
Logging the URLs is probably the only way. I doubt MSHTML would allow easy access to the user's history, especially since much of it is accessible to Javascript.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 19th, 2009, 10:53 pm 
Offline

Joined: October 9th, 2006, 8:19 pm
Posts: 236
Location: Finland
I decided to include #hash part and exclude title, though it was interesting sometimes.

Including sub-header is planned, as time (and title bar space) allows. I hope I can find a nice way to reload the page to restore its original scroll state, when navigating back/forward and when pressing F5, so those items would be more useful.

This script has been working well after I added a 0.1 s. Sleep:
Code:
AutoTrim Off
CoordMode, Mouse, Screen

#IfWinActive ahk_class HH Parent

~LButton Up::
MouseGetPos, m_x, m_y, m_hw_target
SendMessage, 0x84, , (m_y << 16)|m_x, , ahk_id %m_hw_target%
If (ErrorLevel = 3 Or ErrorLevel = 20)
   Return
~Enter::
~NumPadEnter::
~!Right::
~!Left::

Sleep 100
;Get HTML source code from current window in IE
ControlGet, hIESvr, Hwnd,, Internet Explorer_Server1, ahk_class HH Parent ;  IEFrame
WinGetClass, class, ahk_id %hIESvr%
If (!hIESvr or class != "Internet Explorer_Server")
   Return
COM_CoInitialize()
WM_HTML_GETOBJECT := DllCall("RegisterWindowMessage", "str", "WM_HTML_GETOBJECT")
SendMessage, WM_HTML_GETOBJECT, , , , ahk_id %hIESvr%
lResult := ErrorLevel
DllCall("oleacc\ObjectFromLresult", "uint", lResult
, "uint", COM_GUID4String(IID_IHTMLDocument2,"{332C4425-26CB-11D0-B483-00C04FD90119}")
, "int", 0, "uint*", pDoc)
Loop 9 ; Get all H%A_Index% elements.
{
   If pAllH := COM_Invoke(pDoc,"all.tags", "H" A_Index)
   { ; If there is exactly one,
      If (COM_Invoke(pAllH, "length") = 1) && (pH := COM_Invoke(pAllH, "item", 0))
      { ; use its text.
         header := COM_Invoke(pH, "innerText")
         ; remove all cr:s/lf:s from header
         StringReplace header, header, % Chr(10), , All
         StringReplace header, header, % Chr(13), , All
         COM_Release(pH), COM_Release(pAllH)
         Break
   }
      COM_Release(pAllH)
}
} ; Get the title directly via DOM.
If header = ; hardly ever!(?)
   header := COM_Invoke(pDoc,"title")
If (hash := COM_Invoke(pDoc,"location.hash"))
   header .= " - " hash
WinGetTitle, wT
;StringReplace, wT, wT, AutoHotkey, AHK ; Addit. space for header
m := InStr(wT, "-")
If m
   wT := SubStr(wT, 1, InStr(wT, "-") - 2)
WinSetTitle, , , %wT% - %title%%header%
Return

_________________
Pekka Vartto


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 16 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group