Delphi, CHM and the help button

This section is for programmers. Please use it for all discussons on interfacing help with your applications and related subjects.

Moderators: Alexander Halser, Michael Schwarzl

Post Reply
kingcad
Posts: 2
Joined: Thu Dec 19, 2002 9:52 pm

Delphi, CHM and the help button

Unread post by kingcad »

By looking at all the topics related to using CHM helpfiles in Delphi I was successful in starting the CHM file when clicking a button with this code
procedure TForm1.BitBtn3Click(Sender: TObject);
begin
Application.HelpCommand(HELP_CONTEXT, 690);
end;

However when using a button with
KIND=bkHelp I was hoping that it would automatically fire up the chm helpfile.
For some reason a BKHELP does not go through the HelpRouter.

How can I get a regular HELP button to activate the HelpRouter without me having to write code in the button's on click event.
User avatar
Alexander Halser
EC-Software Support
Posts: 4098
Joined: Mon Jun 24, 2002 7:24 pm
Location: Salzburg, Austria
Contact:

Unread post by Alexander Halser »

The button style bkHelp doesn't mean much and does exactly nothing. You must assign an OnClick event handler to the button.

Here is how we did it in Help & Manual: when Help & Manual creates a dialog box, it dynamically assigns an event handler to a button called "BtnHelp" in the dialog. This works because every dialog has this button and the button is always named "BtnHelp"

Code: Select all

FrmSomeDialog := TFrmSomeDialog.create(application);
with FrmSomeDialog do
try
   BtnHelp.OnClick := DoInvokeHelp;
   if ShowModal ...

finally
   free;
end;
This is the procedure DoInvokeHelp in the main unit:

Code: Select all

procedure TFrmHelpmanMain.DoInvokeHelp(Sender: TObject);
begin
    Application.helpcommand(HELP_CONTEXT, abs(TForm(sender.owner).helpcontext));
end;
You could write this 1 line into the OnClick handler of the help button directly, it is the same work. But redirecting it to a function in the main unit makes it easier to apply changes in the future without having to change every dialog box.

The OnClick event of the help button delivers "BtnHelp" as the "Sender". Since we know that the button owner is the dialog form and the dialog form does have a help context number (common rule here), we can easily redirect it. The procedure does not have to know further details if the dialog design followed the common rule.

Finally a word about the abs() function: the help context number for forms is always a negative number (another common rule here) and the corresponding help topic for the entire dialog is always displayed in the main help window, not in a popup window.

The negative number is essential if you click the [?] button in the dialog tool bar and then click on the form or on a panel that does not have a help context number (because it's only for grouping controls). In this case, the entire online help machine goes a different route: it's handled by Delphi resp. the component TWhatsThis in the main form handles the help call.

The "intelligence" built into TWhatsThis is, that if the help context number is a positive value, it displays the help topic in a popup window, if it's negative, it displays the help topic in the main help window. Internally, the difference between the help calls looks like this:

Code: Select all

if HC < 0 then Application.HelpCommand(HELP_CONTEXT, abs(HC))
else Application.HelpCommand(HELP_CONTEXTPOPUP, HC);
This command then passes the Application.OnHelp event which is in turn handled by the help router. The help router knows that popup topics are in HLP format, all others in HTML Help and finally makes the necessary help call according to the command.
Alexander Halser
Senior Software Architect, EC Software GmbH
kingcad
Posts: 2
Joined: Thu Dec 19, 2002 9:52 pm

Help Button

Unread post by kingcad »

Alexander, I do appreciate you detailed response.
My existing application which is using the regular HLP format up till now has about 100 different dialog boxes and each one already has a BKHELP kind button on it with the correct context number. I agree that it would not be impossible to go and redirect their onclick events to a certralized function that activates the helprouter.
My next problem is the other multitude of BKCUSTOM buttons whose onclick event actually does a function. On these I still have a context number and the user gets to the helpfile (for the topic of the button) by pressing F1 on the keyboard.
The question. How do I intercept the F1 function that in the past has automatically started the helpfile
User avatar
Alexander Halser
EC-Software Support
Posts: 4098
Joined: Mon Jun 24, 2002 7:24 pm
Location: Salzburg, Austria
Contact:

Unread post by Alexander Halser »

How do I intercept the F1 function that in the past has automatically started the helpfile
It still starts the help file and displays a context sensitive help topic - if the focus control (or one of it's parents) has a help context number.

You cannot really intercept the F1 key. The component TWhatsThis does intercept it but with a serious amount of code (it temporarily installs a hook to the form's default window proc to catch and "eat" the WM_HELP windows message that automatically follows the F1 key). If you use TWhatsThis, this component has an event that is triggered when you press the F1 key.

Without TWhatsThis you can only intercept the Application.OnHelp event (or HelpRouter.OnHelp, if you use this component). You can stop the help commands "HELP_CONTEXT" and "HELP_CONTEXTPOPUP" from beeing executed. These commands usually occur when the user presses F1. But they also occur when the user clicked the question mark button on a dialog window and clicked on a particular control to get help for that. Both methods (mouse help click and F1 key) generate the same help commands and you cannot distinct between mouse and F1 in Application.OnHelp.

By the way, the form's OnKeyPress and OnKeyDown events don't work. When the F1 key press occurs in these events, the help message is already on it's way through the help routing system of Delphi's VCL.
Alexander Halser
Senior Software Architect, EC Software GmbH
Kevin Killion
Posts: 38
Joined: Fri Jun 15, 2012 9:44 pm

Re: Delphi, CHM and the help button

Unread post by Kevin Killion »

The previous posts in this thread are 11 years old, so some freshening up is in order.

In current versions of Delphi, a BitBtn with a Kind pf bkHelp ***does*** do the right thing. For more, see http://docwiki.embarcadero.com/RADStudi ... lp_Buttons

This is the crucial part:
You can specify the help topic properties for a help button directly using the button properties: HelpType (htContext or htKeyword) and HelpContext or HelpKeyword. However, usually you specify help topic properties in properties of the parent form. To delegate the specification of the help topic properties to the form, set HelpType = htContext and HelpContext = 0 (notice that these are the default values of these properties.)
So, set the help info for the form, not the button. Then a click on the button will go to the form's designated help page.

(I'm a newbie on integrating help into the app, but I think I got this right!)

Kevin
User avatar
Tim Green
Site Admin
Posts: 23153
Joined: Mon Jun 24, 2002 9:11 am
Location: Bruehl, Germany
Contact:

Re: Delphi, CHM and the help button

Unread post by Tim Green »

Hi Kevin,

These threads are just completely out of date, so there is no point in referring to them any more. Delphi has had full integrated support for interfacing to CHM files for several years now. 8)
Regards,
Tim (EC Software Documentation & User Support)

Private support:
Please do not email or PM me with private support requests -- post to the forum directly.
Post Reply