Linking a help file to a Delphi XE2 application - everything works except for the main form

I am working on setting up a help file with our software. I have added HelpContext numbers for many specific forms / frames / controls, and they all work fine. The problem is that the basic form does not bring any help at all. For all this, I use only F1 to try to get help.

I'm not at all a Delphi specialist or helpfiles, but I will post what I did and where I looked.

Edit:. With some help, I can see that the problem is that the main form is an MDI parent. This still does not solve the problem. It almost seems like a mistake to me, but I believe that for some reason it may be intentional. Endedit

I include this module: HtmlHelpViewer for the viewer. In the main forms of Create constructor, I added Application.Helpfile: = 'asdf.chm'. For all other forms, I just added context numbers, and it worked right away. I tried this on the main form and nothing happens. Therefore, I tried to add the Application.OnHelp event, but this is not called in the main form (and this is done for all other forms where the help works).

The last tool I could think of was to track in the back of the code and see what happens. I ended up in TCustomForm.WMHelp in Vcl.Forms as the place where the separation occurred. The specified function has this loop:

if iContextType = HELPINFO_WINDOW then begin Control := FindControl(hItemHandle); while (Control <> nil) and ( not ControlHasHelp(Control)) do Control := Control.Parent; if Control = nil then Exit; GetHelpInfo(Control, HType, ContextID, Keyword); Pt := Control.ClientToScreen(Point(0, 0)); end 

When the main form called up the help control panel, it would be null and then it would exit. Everything else will be fine.

I obviously don’t know why this is happening. The answer can be very simple. Any ideas would be appreciated!

+6
source share
1 answer

According to your comments, the WM_HELP message is for your MDI client. And since this is not VCL control, it does not respond to the WM_HELP message. You can solve the problem by intercepting the message and asking for the main form:

 type TMainForm = class(TForm) protected procedure WMHelp(var Message: TWMHelp); message WM_HELP; end; .... procedure TMainForm.WMHelp(var Message: TWMHelp); begin if (Message.HelpInfo.iContextType=HELPINFO_WINDOW) and (Message.HelpInfo.hItemHandle=ClientHandle) then Message.HelpInfo.hItemHandle := Handle; inherited; end; 

If you want to be even more protective, you can write it like this:

  if (Message.HelpInfo.iContextType=HELPINFO_WINDOW) and (FindControl(Message.HelpInfo.hItemHandle)=nil) then Message.HelpInfo.hItemHandle := Handle; 

I just looked at my own MDI application, and I see that I have similar code to solve this exact problem. If it had not been written more than 10 years ago, I could have remembered it before!

+6
source

Source: https://habr.com/ru/post/912272/


All Articles