3

Delphi2009アプリケーションに状況依存ヘルプを実装しています。1つの場合を除いて正常に動作します。メインメニューにいること、およびどのメニュー項目が開かれたかを識別できません。

私がやりたいのは、ユーザーが[ファイル]メニューを開いていて、開いているときにF1を押しているときに、[ファイル]メニューでヘルプを表示することです。編集メニューを開いてF1キーを押すと、編集メニューなどでヘルプが表示されます。

ApplicationEventsHelpを使用して、ユーザーによるF1の押下を次のように処理しています。

function MainForm.ApplicationEvents1Help(Command: Word; Data: Integer;
  var CallHelp: Boolean): Boolean;
begin
  if Command = HELP_COMMAND then begin
    Application.HelpSystem.ShowTopicHelp(PChar(Data), Application.CurrentHelpFile);
    CallHelp := false;
  end;
  Result := true;
end;

前述したように、これはメインメニュー以外のすべてで機能します。使ってみました

FindVCLWindow(Mouse.CursorPos)

そして、アクティブなコントロールを識別してメニューを識別するかどうかを確認する他のそのようなメソッドですが、そうではないようです。

F1キーが押されたときに開いているメニュー項目(ある場合)を確認する方法はありますか?


皆さんの助けと良いアイデアに感謝します。

私の最終的な解決策を文書化するために、システムはそれがどのコントロールにあるかを理解するのが特に得意ではなく、時々それを間違え、不適切なヘルプページを表示するApplicationEventsHelpに誤ったデータを渡すことがわかりました。

受け入れられた回答のメニューを処理するためのソリューションを実験して使用した後、正しいヘルプ項目を表示するには、どのコントロールを使用しているかを特定するのが最善であることがわかりました。HelpKeywordプロパティを使用することすらしませんでしたが、ハードコーディングしました。コードは明確で、機能します。また、RVEditウィンドウのヘルプがあり、ドキュメントのセクションに応じてさまざまなヘルプページが表示されます(CurCursorIDからわかります)。

私のようにこれをやりたい人のために、ここに方法があります:

function TLogoAppForm.ApplicationEvents1Help(Command: Word; Data: Integer;
  var CallHelp: Boolean): Boolean;
var
  HelpKeyword: string;
  SType: string;

begin
  if Command = HELP_COMMAND then begin
    if PtInRect(RVEdit.ClientRect, RVEdit.ScreenToClient(Mouse.CursorPos)) then begin
      if CurCursorID = 'H' then HelpKeyword := 'RefTopReport'
      else if CurCursorID = 'T' then HelpKeyword := 'RefTableContents'
      else if CurCursorID = '~HNAME' then HelpKeyword := 'RefIndexNames'
      else if copy(CurCursorID, 1, 2) = 'N+' then HelpKeyword := 'RefIndexNames'
      else if CurCursorID = 'B' then HelpKeyword := 'RefBottomReport'
      else if CurCursorID <> '' then HelpKeyword := 'RefInformationArea'
      else HelpKeyword := 'RefEverythingReport';
      Application.HelpSystem.ShowTopicHelp(HelpKeyword, Application.CurrentHelpFile);
    end
    else if PtInRect(ElTree.ClientRect, ElTree.ScreenToClient(Mouse.CursorPos)) then
      Application.HelpSystem.ShowTopicHelp('RefTreeView', Application.CurrentHelpFile)
    else if PtInRect(TopToolbar.ClientRect, TopToolbar.ScreenToClient(Mouse.CursorPos)) then
      Application.HelpSystem.ShowTopicHelp('RefTopToolbar', Application.CurrentHelpFile)
    else if PtInRect(BottomToolbar.ClientRect, BottomToolbar.ScreenToClient(Mouse.CursorPos)) then
      Application.HelpSystem.ShowTopicHelp('RefBottomToolbar', Application.CurrentHelpFile)
    else
      Application.HelpSystem.ShowTopicHelp('RefMainWindow', Application.CurrentHelpFile);
    CallHelp := false;
  end
  else if Command = HELP_CONTEXTPOPUP then begin
    case Data of
      0: HelpKeyword := 'RefMenuBar';
      11: HelpKeyword := 'RefFileMenu';
      12: HelpKeyword := 'RefEditMenu';
      13: HelpKeyword := 'RefSearchMenu';
      14: HelpKeyword := 'RefNavigateMenu';
      15: HelpKeyword := 'RefViewMenu';
      16: HelpKeyword := 'RefOrganizeMenu';
      17: HelpKeyword := 'RefHelpMenu';
      else HelpKeyword := '';
    end;
    if HelpKeyword <> '' then begin
      Application.HelpSystem.ShowTopicHelp(HelpKeyword, Application.CurrentHelpFile);
      CallHelp := false;
    end;
  end;
  Result := true;
end;

7つのメインメニューのMenuItemsのHelpContextプロパティに11から17を入力して、どのメニューを使用しているかに応じて正しいヘルプが表示されるようにする必要がありました。メニュー項目の検出は、この質問に対する答えの助けになります。私に提供してくれました。

良い点は、このコードは(HelpContext番号の代わりにHelpKeywordsを使用して)簡単に追跡でき、DelphiXEおよびFireMonkeyに変換した後でもおそらく機能することです。

4

3 に答える 3

3

toCommand = HELP_COMMANDのキャストを見ると、コンテキスト識別子(HelpType = htKeyword)ではなく、キーワードに基づいたヘルプシステムを使用しているようです。DataPChar

(ここDelphi 7では)メニュー項目にはHelpTypeandHelpKeywordプロパティがないため、次のプロパティを使用する必要がありHelpContextます。

function TForm1.ApplicationEvents1Help(Command: Word; Data: Integer;
  var CallHelp: Boolean): Boolean;
begin
  if Command = HELP_COMMAND then
  begin
    //Application.HelpSystem.ShowTopicHelp(PChar(Data), Application.CurrentHelpFile);
    //Doesn't this do the same?
    Application.HelpKeyword(PChar(Data));
    CallHelp := False;
  end
  else if Command = HELP_CONTEXT then
  begin
    // Convert the context identifier to your keyword, or:
    Application.HelpContext(Data);
    CallHelp := False;
  end;
  Result := True;
end;
于 2011-10-22T07:55:21.030 に答える
2

Windowsメッセージ「WM_MENUSELECT」をトラップすることにより、選択したメニュー項目を追跡することができます。

詳細については、 menuitemhintsを参照してください。

例 :

 type
    TForm1 = class(TForm)
    ...
    private
      fMyCurrentSelectedMenuItem : TMenuItem;
      procedure WMMenuSelect(var Msg: TWMMenuSelect) ; message WM_MENUSELECT;
    end

procedure TForm1.WMMenuSelect(var Msg: TWMMenuSelect) ;
 var
    menuItem : TMenuItem;
    hSubMenu : HMENU;
 begin
    inherited; // from TCustomForm (so that Application.Hint is assigned)

    menuItem := nil;
    if (Msg.MenuFlag <> $FFFF) or (Msg.IDItem <> 0) then
    begin
      if Msg.MenuFlag and MF_POPUP = MF_POPUP then
      begin
        hSubMenu := GetSubMenu(Msg.Menu, Msg.IDItem) ;
        menuItem := Self.Menu.FindItem(hSubMenu, fkHandle) ;
      end
      else
      begin
        menuItem := Self.Menu.FindItem(Msg.IDItem, fkCommand) ;
      end;
    end;

    //miHint.DoActivateHint(menuItem) ;
    fMyCurrentSelectedMenuItem := menuItem;
 end; (*WMMenuSelect*)

したがって、F1ボタンを押すと、fMyCurrentSelectedMenuItemを使用して正しいヘルプをアクティブ化できます。

于 2011-10-22T07:51:28.493 に答える
1

GetMenuItemRect関数を使用できます。1
。メインメニューのすべてのアイテムを確認し、GetMenuItemRectを呼び出してアイテムの位置を取得します。機能はアイテムが表示されている場合にのみ機能します。
2. GetCursorPosとPtInRectを使用して、マウスがメニュー項目の上にあるかどうかを確認し、適切なヘルプトピックを呼び出します。

于 2011-10-22T07:52:36.987 に答える