Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

HTML Help context sensitive help from Builder?

87 views
Skip to first unread message

Steve Sutton

unread,
Apr 24, 2000, 3:00:00 AM4/24/00
to
Is it possible in Builder to create context-sensitive help using the new MS
HTML Help system? I've read the MS documentation and sense that it may be
tied to VC++ in subtle ways, although it's hard to tell. I guess what I'm
looking for is a nice little bit of documentation that describes this
process in Builder (API's and so forth).


Rudy Velthuis

unread,
Apr 24, 2000, 3:00:00 AM4/24/00
to
Steve Sutton wrote...

>Is it possible in Builder to create context-sensitive help using the new MS
>HTML Help system? I've read the MS documentation and sense that it may be
>tied to VC++ in subtle ways.

Since it is even possible from Delphi, it should certainly be possible
from BCB. I have no URLs or anything for BCB though.
--
Rudy Velthuis

hz

unread,
Apr 24, 2000, 3:00:00 AM4/24/00
to
"Steve Sutton" <ssu...@trustedsystems.com> wrote:

>Is it possible in Builder to create context-sensitive help using the new MS
>HTML Help system?

Yes.

>I've read the MS documentation and sense that it may be

>tied to VC++ in subtle ways, although it's hard to tell. I guess what I'm
>looking for is a nice little bit of documentation that describes this
>process in Builder (API's and so forth).

Okay, here we go. This is just as far as I got with it, so others
might point out better ways of performing certain tasks. I'm running
this on Win98 SE, executable created with Borland C++ Builder 5 PRO.


- Download and install the most recent version of HtmlHelp from
Microsoft. Be sure to download all the support documents. You should
have the latest versions of these documents: API.CHM, HHAXREF.CHM,
HTMLHELP.CHM and VIEWHLP.CHM. All of this stuff is free for the
picking.


- Run IMPLIB on HHCTRL.OCX, which is in your Windows/System directory:

implib c:\hhborland.lib c:\windows\system\hhctrl.ocx

This will create a Borland C++Builder compatible link library
(HTMLHELP.LIB as shipped with HtmlHelp is only useful for MSVC++).


- Create a new project in BCB and add HHBORLAND.LIB to it.
Also #include <htmlhelp.h>. This file ships with HtmlHelp and can be
#include'd in your BCB source with 0 warnings or errors. You'll find
it in the directory where you installed HtmlHelp, under its ./Include
directory. You can copy it to your BCB headerfiles directory, unless
you already have a file called htmlhelp.h there. BCB 1, 3 and 4 didn't
have a htmlhelp.h, but BCB 5 *does*. Both versions appear to work
equally snazzle berry, but the one that comes with BCB is newer and
has a #pragma on top. I'd suggest to use that one if you have it.


- Call HH_INITIALIZE before using any of the HtmlHelp functions.
This is typically something you could do in the constructor of your
BCB main Form:

__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){

HtmlHelp(
0,
0,
HH_INITIALIZE,
reinterpret_cast <DWORD> (&HtmlHelpCookie)
);

}

HtmlHelpCookie is a private variable of your Form:

// ...

private:
DWORD HtmlHelpCookie;


- Create a destructor too, which will uninitialize HtmlHelp:

__fastcall TForm1::~TForm1(){

HtmlHelp(
0,
0,
HH_UNINITIALIZE,
reinterpret_cast <DWORD> (HtmlHelpCookie)
);

}

- MS states: "The HTML Help API is not thread safe and must be called
from one and only one thread in a process." See HH_PRETRANSLATEMESSAGE
in the HTML Help API Reference (API.CHM). My translation of the code
you find there for BCB looks like this (also see Harold Howe's faq16
over at www.bcbdev.com for details on AppOnMessage)

Add this method to the private section of your Form's class:

void __fastcall AppOnMessage(tagMSG& Message, bool& Handled);

Then code it for instance like this:

void __fastcall TForm1::AppOnMessage(tagMSG& Message, bool& Handled){

Handled = HtmlHelp(
0,
0,
HH_PRETRANSLATEMESSAGE,
reinterpret_cast <DWORD_PTR> (&Message.message)
);

// if Handled remains false, subsequent processing will happen

}

In FormCreate(), make sure Application->OnMessage gets assigned this
new handler:

Application->OnMessage = AppOnMessage;
- Even without any compiled HtmlHelp file (.CHM), you can now test if
you hooked it all up properly. Add a button to your form and let it
call HH_DISPLAY_TEXT_POPUP, for instance like this:

void __fastcall TForm1::PopupTheTimeClick(TObject *Sender){

// define colors for the popup window
COLORREF ForegroundColor = 0x00ffee00; // aqua
COLORREF BackgroundColor = 0x00004400; // green

// define margins for the popup window
const LONG MARGIN = 5L;
RECT Margins = {MARGIN, MARGIN, MARGIN, MARGIN};

// define position of the popup window
POINT CursorPos;
GetCursorPos(&CursorPos);

// define text for the popup window
String PopupText =
Now().FormatString("dddd mmm dd, yyyy hh:mm:ss\"");

// fill out an HH_POPUP struct
HH_POPUP Popup;
Popup.cbStruct = sizeof(HH_POPUP);
Popup.idString = 0;
Popup.pszText = PopupText.c_str();
Popup.pszFont = "Times New Roman,22";
Popup.clrForeground = ForegroundColor;
Popup.clrBackground = BackgroundColor;
Popup.rcMargins = Margins;
Popup.pt = CursorPos;

// display the popup
HtmlHelp(
Handle,
0,
HH_DISPLAY_TEXT_POPUP,
reinterpret_cast <DWORD> (&Popup)
);

}


- Of course you'll want two-way communication between your compiled
help and BCB. If you haven't already, create and compile a HtmlHelp
file using HtmlHelp workshop. It's very easy to use, but takes a
little getting used to. You can use your favorite html editor to
create html pages which you add to the HtmlHelp project. You can do
all kinds of interesting stuff, but we'll only look at two way
communication here. To send a message from HtmlHelp to BCB, add
something like this to a HTML file:

<h4>Send WM_TCARD (wParam: 4321, lParam: 6688) to app:</h4>

<OBJECT id=hhctrl type="application/x-oleobject"
classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
codebase="hhctrl.ocx#Version=4,73,8561,0"
width=0 height=0>
<PARAM name="Command" value="TCard">
<PARAM name="Button" value="Text:WM_TCARD">
<PARAM name="Item1" value="4321, 6688">
</OBJECT>

- In order to catch WM_TCARD from in our application, the easiest
would be to add a message map to your Form. The ending of your Form's
class would look something like this:

private:

// ...

void __fastcall WMTrainingCard(TMessage& Message);

public:

// ...

BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_TCARD, TMessage, WMTrainingCard)
END_MESSAGE_MAP(TForm)

};


Code WMTrainingCard() something like this:

void __fastcall TForm1::WMTrainingCard(TMessage& Message){

TForm::Dispatch(&Message);

String Info;
Info.sprintf(
"Nice meeting you, HTMLHelp\nWPARAM: %lu, LPARAM: %lu",
Message.WParam,
Message.LParam
);
ShowMessage(Info);

}


- Now we also need to be able to start our HtmlHelp file from BCB, and
choose a specific page and/or window definition while we're at it.
If you didn't notice this already: you can define several different
window layouts for your helpsystem in HtmlHelp. This way you can
launch a page with a Explorer look ('Home' and 'Back' buttons and all)
or a very restricted border, where there are no buttons to confuse
your user.

Because I'm using the same htmlhelp file (HH.CHM in my app's
directory) several times, I find out its full name in FormCreate() and
remember HtmlHelpFile as a String, private to my Form:

HtmlHelpFile = ExtractFilePath(Application->ExeName);
int Length = HtmlHelpFile.Length();
if(Length && HtmlHelpFile[Length] != '\\')
HtmlHelpFile += "\\";
HtmlHelpFile += "hh.chm";
// assert(FileExists(HtmlHelpFile));


This way I can launch the same HtmlHelp file like this:

// this will open the HtmlHelp file in its default window type
// using the default opening page

HtmlHelp(
Handle,
HtmlHelpFile.c_str(),
HH_DISPLAY_TOPIC,
0
);
In my .CHM's .HHP, I have two window definitions ('SomeWinType' and
'Bells and whistles'). To open a specific page with a specific window
definition, I can then do..:

// this will open the HtmlHelp file in a second window definition
// (Bells and whistles) using a specified file

HtmlHelp(
Handle,
(HtmlHelpFile + "::/buffy.html>Bells and whistles").c_str(),
HH_DISPLAY_TOPIC,
0
);


- If you need to manipulate an already launched HtmlHelp window, you
can call HH_GET_WIN_HANDLE on it. The returned HWND can be used like a
vanilla Window handle, for instance:

HWND HelpWindowHandle = HtmlHelp(
Handle,
HtmlHelpFile.c_str(),
HH_GET_WIN_HANDLE,
reinterpret_cast <DWORD> ("SomeWinType")
);

// "SomeWinType" is an existing window definition in my .CHM

if(IsWindow(HelpWindowHandle))
ShowWindow(HelpWindowHandle, SW_SHOWMAXIMIZED);
else{
Application->MessageBox(
"helpwindow 'SomeWinType' not running",
"Sorry...",
MB_ICONQUESTION
);
}


- If you Close() your application, you'll notice that HtmlHelp closes
as well. If you only need to close HtmlHelp during the lifespan of
your program, do something like this:

HtmlHelp(0, 0, HH_CLOSE_ALL, 0);


Some more tips:
===============

- Except for the compiled help, all the files created by HtmlHelp
workshop are textfiles. Very handy.

- You can even launch documents and executables from within HtmlHelp:

<h4>Edit win.ini:</h4>

<OBJECT id=hhctrl type="application/x-oleobject"
classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
codebase="hhctrl.ocx#Version=4,73,8561,0"
width=0 height=0>
<PARAM name="Command" value="ShortCut">
<PARAM name="Button" value="Text:Do it now">
<PARAM name="Item1" value=",win.ini">
</OBJECT>

<br><br><hr>

<h4>Launch calc.exe</h4>

<OBJECT id=hhctrl type="application/x-oleobject"
classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"
codebase="hhctrl.ocx#Version=4,73,8561,0"
width=0 height=0>
<PARAM name="Command" value="ShortCut">
<PARAM name="Button" value="Text:Calc.exe">
<PARAM name="Item1" value="calc.exe,calc.exe">
</OBJECT>


Okay, sorry for the long posting. I'm very interested to hear other
people's experience with HtmlHelp using BCB.


Hens Zimmerman


a.ep...@ziggo.nl

unread,
Dec 23, 2018, 4:39:45 PM12/23/18
to
Op maandag 24 april 2000 08:00:00 UTC+1 schreef Steve Sutton:
> Is it possible in Builder to create context-sensitive help using the new MS
> HTML Help system? I've read the MS documentation and sense that it may be
> tied to VC++ in subtle ways, although it's hard to tell. I guess what I'm
> looking for is a nice little bit of documentation that describes this
> process in Builder (API's and so forth).

Dear Hens,

I was reading your answer on Steve Button's question because I seem to have the same problem but in quite different conditions and circumstances. I developed a VS application confronting what is reported to me by Darran Rowe in "https://social.msdn.microsoft.com/Forums/vstudio/en-US/607c7811-6c85-45f5-afd7-eb74c0f55d31/unable-to-compile-a-release-version-on-visual-studio-2017?forum=vssetup#bbe96e62-7a42-4501-9565-0a661165ac5a". That was reason for me to migrate to Embarcadero's C++ Builder( community). At the moment compiling all *.cpp files happens error free but I failed in linking HtmlHelp() by creating hhborland.lib and I remain brand new to C++ Builder! Perhaps I am trying the impossible because the linker also complained about a missing [w]main: considering my program - unjustly - as a console application. I have of course a [w]WinMain() function defined! So far my code is greatly identical and even portable to VS 2006-2017's: I didn't create in it a BCB's application and I am afraid that this might however be necessary: quite a job and also destroying any portability (so far maintained!) to VS. In VS 2017 my 32/64-bits debug builds run perfectly but though both release builds run also both don't pass my - quite severe - test: the correct solution of (nearly) 6.000 mathematical (highschool+) exercises. AND I CAN'T DEBUG MY RELEASE BUILDS!
I checked some BCB project and it even seemed to lack a MainWndProc()! Apparently C++ Builder seems miraculously to be providing it! With all regards!

Ton Epskamp at a.ep...@ziggo.nl.

a.ep...@ziggo.nl

unread,
Dec 27, 2018, 9:27:09 AM12/27/18
to
Op maandag 24 april 2000 08:00:00 UTC+1 schreef Rudy Velthuis:
> Steve Sutton wrote...
> >Is it possible in Builder to create context-sensitive help using the new MS
> >HTML Help system? I've read the MS documentation and sense that it may be
> >tied to VC++ in subtle ways.
>
> Since it is even possible from Delphi, it should certainly be possible
> from BCB. I have no URLs or anything for BCB though.
> --
> Rudy Velthuis

Dear Rudy,

I was reading your answer on Steve Sutton's question because I seem to have the same problem but in quite different conditions and circumstances. I developed a VS application confronting what is reported to me by Darran Rowe in "https://social.msdn.microsoft.com/Forums/vstudio/en-US/607c7811-6c85-45f5-afd7-eb74c0f55d31/unable-to-compile-a-release-version-on-visual-studio-2017?forum=vssetup#bbe96e62-7a42-4501-9565-0a661165ac5a". That was reason for me to migrate to Embarcadero's C++ Builder( community). At the moment compiling all *.cpp files happens error free but I failed in linking HtmlHelp() by creating hhborland.lib and I remain brand new to C++ Builder! Perhaps I am trying the impossible because the linker also complained about a missing [w]main: considering my program - unjustly - as a console application. I have of course a [w]WinMain() function defined! So far my code is greatly identical and even portable to VS 2006-2017's: I didn't create in it a BCB's application and I am afraid that this might however be necessary: quite a job and also destroying any portability (so far maintained!) to VS. In VS 2017 my 32/64-bits debug builds run perfectly but though both release builds run also both don't pass my - quite severe - test: the correct solution of (nearly) 6.000 mathematical (highschool+) exercises. AND I CAN'T DEBUG MY RELEASE BUILDS!
I checked some BCB project and it even seemed to lack a MainWndProc()! Apparently C++ Builder seems miraculously to be providing it! With all regards!

P.S.

Your name sounds Dutch and I am Dutch. Because of readability I suppose we have to continue in English! Perhaps not when the first mentioned statement about the Dutch language and communicating by email would apply.

Ton Epskamp at a.ep...@ziggo.nl.


0 new messages