Связывание файла справки с приложением Delphi XE2 - все работает, кроме основной формы - PullRequest
6 голосов
/ 03 апреля 2012

Я работаю над настройкой файла справки с нашим программным обеспечением. Я добавил номера HelpContext для множества конкретных форм / фреймов / элементов управления, и все они работают нормально. Проблема в том, что основная форма вообще не вызывает никакой помощи. Для всего этого я использую только F1, чтобы попытаться вызвать помощь.

Я совсем не эксперт по Delphi или файлам помощи, но я опубликую то, что я сделал и где я посмотрел.

Редактировать: Благодаря некоторой помощи теперь я вижу, что проблема в том, что основная форма является родителем MDI. Это все еще не решает проблему ... это почти кажется мне ошибкой, но я полагаю, что это может быть преднамеренным по какой-то причине. EndEdit

Я включаю этот модуль: HtmlHelpViewer для зрителя. В основных формах конструктора Create я добавил Application.Helpfile: = 'asdf.chm'. Для всех других форм я только что добавил номера контекста, и это сработало сразу. Я попробовал это в основной форме, и ничего не происходит. Поэтому я попытался добавить событие Application.OnHelp, но это не вызывается в главной форме (и это происходит для всех других форм, где работает справка).

Последнее средство, о котором я мог подумать, - это проследить вглубь кода и посмотреть, что происходит. Я попал в TCustomForm.WMHelp в Vcl.Forms как место, где происходил раскол. У указанной функции есть этот цикл:

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

Когда главная форма вызывала элемент управления справки, он был равен нулю, а затем выходил. Все остальное будет хорошо.

Я, очевидно, не знаю, почему это происходит. Ответ может быть очень простым. Любые идеи будут оценены!

1 Ответ

6 голосов
/ 04 апреля 2012

Согласно вашим комментариям, сообщение WM_HELP предназначается для вашего окна клиента MDI.А поскольку это не элемент управления VCL, он не отвечает на сообщение WM_HELP.Вы можете решить проблему, перехватив сообщение и попросив основную форму обработать его:

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 (Message.HelpInfo.iContextType=HELPINFO_WINDOW) 
  and (FindControl(Message.HelpInfo.hItemHandle)=nil) then 
    Message.HelpInfo.hItemHandle := Handle;

Я только что посмотрел на свое собственное приложение MDI и вижу, что у меня есть подобный код для решения этой конкретной проблемы.Если бы оно не было написано более 10 лет назад, я бы вспомнил раньше!

...