This demo is only of interest if you're programming in Delphi, and really want's to get hold of the guts deep inside the HHctrl.ocx and its co-worker SHdocvw.dll.


------------
To run the demo - unzip the 4 files and run HHTest.exe.

Try the index "HTML Help Overview" and you'll se a collapsed text section that is automatically expanded.

Try the drop down box and some of the menu items.

Enjoy



--------------------------

I have worked with WinHelp fore quite some years, and expanded its capability trough custom DLL's.
What a friendly application WinHelp is - opposite to HTML help.

It's nice and simple to build large collections of hlp-files that works seamless together. And all those wonderful things you can do with customs WinHelp-DLL's - and yet the best part, with Delphi it's a breeze to add new functionality to those customs DLL's.

Admitted - HTML Help offers some new opportunities that looks interesting - if it only wasn't fore that disheartening limited HH-Api.

Collapsed / expandable text sections is one of the features that got me hooked on HTML-help! 

Did you ever wanted those collapsed text sections to automatically expand when you navigate to a bookmark inside it? - Or if words you found with full text search are inside a collapsed section? - Its no problem - just keep on reading! 


So - in april I decided to conquer the HTML Help beast!

From the architecture of the HTML Help concept, it's easy to see that you has to get hold of a IUnknown pointer to the SHdocvw.dll that HHctrl.ocx loads on start-up - from that point on you can make HTML-Help do whatever you dreaming off.

To let it out in the open - it's not that difficult - you only have to search the Web for a month or so - digest the wealth of information you found - combine what you learnt trough the process - and finally write a com-enabled Delphi-application that takes charge over the HH-Api and the interface to SHdocvw.dll.


I discovered that there are at least two different ways to get hold of SHdocvw.dll 's IUnknown - a Browser Helper Object, and a Com-control embedded in an HTML-page can both do the trick.

I decided to try out the Com-control solution - the only tricky part was to keep a com-control written in Delphi down to an acceptable size. The resulting Com-control is 60 K (without any depending runtime modules).
But as usual the solution was already described on the Web! (Conrad Herrmann - pw2.netcom.com/~cherrman/daxfaqs.htm).

By the way - it's working and delivers the SHdocvw.dll 's IUnknown pointer without troubles.

Now the Com-control must only deliver the IUnknown to the Delphi-application that encapsulates the HH-Api and thus controls the HHctrl.ocx (lest call this application the HH-Controller) - again the solution was already described out there - I gave the HH-Controler a Com-interface, and now they are talking together.

From Marcel van Brakel I got a fresh converted HtmlHelp121.pas header to the HH-Api. On top of that, I have implemented about 70% of the HH-Api functionality up till now - that's about the same level I've found in commercial products.

And now for the last and very very tricky part - whiteout having the
SHdocvw.dll sending notification messages to the HH-Controller your
still left pretty much out in the open in the struggle against the HTML Help beast. Once again the Web cam in handy - Binh Ly - www.intac.com/~bly/Programming/Delphi - has done Somme ground covering work in that area.

When the HH-Controller (the Delphi-application that I wrote) starts-up it - behind the scene - first loads a Html page that contains the small Com-control (I named it WebLurke.dll)- the WebLurke first get the IUnknown from SHdocvw.dll, and then gives it back to the HH-Controller via the HH-Controllers com-interface.

Now, trough the IUnknown, the HH-Controller establishes a sink for Shdocvw events, and loads the CHM-page that it was originally asked fore - the user newer sees the WebLurke HTML-page.
As the WebLurke HTML-page is a separate page that comes as a build-in resource in the HH-Controller, all standard CHM-files uses the HH-Controllers extra functionality.

And now back to the collapsed text sections in a CHM-page that I mentioned earlier.
If you don't know what it is  - open "Help topics" from the HTML-Help Workshop, the first page contains two collapsible text sections.

When the HH-Controller receives a DocumentComplete Event from SHdocvw.dll, the URL from the NavigateComplete2 Event, is search fore a bookmark (the # character) - if the target is a bookmark then - maybe - we are facing a collapsed text section.

From now on you have to know the WebBrowsers Object-model - if you like to understand what's going on.

Starting with the SHdocvw.dll 's IUnknown pointer, the HH-Controller now creates an IWebBrowser2 Interface, and from that interface and onwards nearly everything is possible.

The HH-Controller reads all the text from the CHM-page in to a string
(OuterHtml from Document.Body), searches the string for the bookmark (the bookmark is the part after the # character in the URL), and if found checks to see if the bookmark is inside of a collapsible text section. The same functionality can been done trough the range-object - I tried it (just to prove it's possible), but working with strings in Delphi-code is much simpler and faster than doing the same work inside the WebBrowser.

This is en example of how collapsible text sections look like in pure
HTML:
--------------------------------
<p><a Name = "hh1_OverView" onclick="doExpand(exp1,ar1)" href="#nowhere"> <img src="arrowdn.gif" id="ar1" border=0>Overview</a></p>
<DIV CLASS="expara" ID="exp1" STYLE="display:">
Microsoft&reg; HTML Help consists of an online Help Viewer, related help
components, and help authoring tools from Microsoft Corporation. The
Help
Viewer uses the underlying components of Microsoft Internet Explorer to
display help content. It supports HTML, ActiveX&reg;, Java&trade;,
scripting
languages (JScript&reg;, and Microsoft Visual Basic&reg; Scripting
Edition),
and HTML image formats (.jpeg, .gif, and .png files). The help authoring
tool, HTML Help Workshop, provides an easy-to-use system for creating
and
managing help projects and their related files.
</DIV>
--------------------------------

I took this example from the hh1.htm page in the HTML Help workshop's help-file.

The "hh1_OverView" in the second line is the bookmark that you can navigate to - I added this bookmark. 
The most interesting part is "onclick="doExpand(exp1,ar1)"" - also in the second line. 

The doExpand is a Java script that just toggles the Display style and changes the arrow.gif appropriately - STYLE="display: none;" means hide the text section and STYLE="display:" means show the text section .

The HH-Controller isolates exp1 - which is a reference to the text section, and ar1 - which is a reference to the arrow.gif.

Lastly HH-Controller ask the WebBrowser fore the CHM-pages Document.object, and via an Item-reference toggles STYLE="display" and arrow.gif.

Again you can let HH-Controller call the doExpand java script, but it
simple and much faster to emulate the original java script inside Delphi. 




I'm quit convinced that if you succeeded in reading so fare, you are a
prospect fore the following proposal. 

I would like to mobilize a group of people that shares the interest of conquering the Html Help beast with me. The group will work so to say "off the mail list", but put the resulting code on the Web as Open Source in an appropriate manner.

The works I have done so far do cover a lot of HTML Help related
aspects, but there is a much room for improvements, new ideas and new functionality.
Furthermore I think that it would be a nice goal to put all of the resulting code into one Delphi component, and thus make it more assessable to the average Delphi programmer.

If you would like to participate - drop me a mail about it - you will
then be enrolled and get a copy of my Delphi source to start with.



My goal with all this, is merrily to use the improved functionality of HTML Help in my job, as a sort of Knowledge Manager in a big company.

As mentioned earlier I have worked with WinHelp fore quite some years,
and expanded its capability trough custom DLL's.

The DLL support features like:
A synchronised navigation pane (looks just like the one in HLML Helps tree pain window)
Links to HTML-pages (fires up the Web browser)
Links to Office documents (fires up the right application)
Conditionally links - links between help-files are redirected depending on who the user are
Index- and full text searching reduced / expanded to certain help-files - depending on who the user are
Printing of the original source-document - I use a true single source document systematic in word
Mailing of comments / suggestions directly to the person that is responsible fore the viewed document

By the way if you are interested in the Delphi code fore my custom WinHelp DLL - then you can have it, just drop me a mail explaining what you would like to do with it.


Some time this fall I'm going to change platform from WinHelp to HTML Help - but certainly with even more added feature over what we have today.

Its odd that one has to go to extremes just to manage a decent information site! 
I searched for years fore a commercial application, but no one (that I
know of) delivers the combination of high productivity (little work involved in the process of making hyper-text out of plain text) and extreme user friendliness with a personally interface (everybody has there oven personal collection of information's). So at last I decided to build such a system on top of WinHelp with RoboHelp as "editor".

Now in the age of Web, its time to get a little more aligned with the
Internet. 
Again I searched for a commercial application, and again the conclusion
was, that I once again had to go trough all the agony that is implied in reinvention of the wheel.

It would sure be nice to share the agony, and hopefully the astonishing results, with someone else - and in the age of Web it is possible, the last time I reinvented the wheel I had to do it on my own.

Kurt Senfer

ks@siemens.dk
