7

私は ListViewViewStyle = vsReportと 2 つのポップアップ メニューを持っています。

  1. ユーザーがヘッダーバーを右クリックしたときに開きたい列ポップアップメニュー
  2. アイテム ポップアップ メニューは、ユーザーがリスト アイテム/サブアイテムまたはアイテムの下の空白を右クリックしたときに開く必要があります。

そのメニューを表示する最も正しい方法は何ですか? どのイベントを処理する必要がありますか?

問題は、ListView.PopupMenuプロパティを設定すると、ListView のクライアントの四角形の任意のポイントを右クリックした後にポップアップ メニューが表示されることです。

イベントを処理するListView.OnColumnRightClickと、ヘッダー バー (列の右側) の空き領域を除いて、列ヘッダーをクリックした後にのみ発生します。

イベントLisView.OnMouseUpは、アイテムの下の空白を右クリックした後にのみ発生します。

4

3 に答える 3

8

リストビューのプロパティを使用する必要はありません。PopupMenu未設定のままにしておくと、ハンドラーをOnContextPopupイベントにアタッチして、位置に応じて任意のポップアップ メニューを起動できます。例:

procedure TForm1.ListViewContextPopup(Sender: TObject; MousePos: TPoint;
  var Handled: Boolean);
var
  HeaderRect: TRect;
  Pos: TPoint;
begin
  GetWindowRect(ListView_GetHeader(ListView.Handle), HeaderRect);
  Pos := ListView.ClientToScreen(MousePos);
  if PtInRect(HeaderRect, Pos) then
    PopupMenuColumns.Popup(Pos.X, Pos.Y)
  else
    PopupMenuItems.Popup(Pos.X, Pos.Y);
end;
于 2012-06-29T13:18:26.617 に答える
3

かなり簡素化できます。2 つのポップアップ メニュー (ヘッダー行と列に 1 つずつ) を作成しますTListView.PopupMenu。IDE で列ポップアップ メニューを割り当てます。

これを ListView のイベント ハンドラーに使用します。

procedure TForm1.ListView1ContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
var
  HeaderRect: TRect;
  HeaderHeight: Integer;
  Header: HWnd;
begin
  ListView1.PopupMenu := ColumnMenu;   // Default to ColumnMenu
  Header := ListView_GetHeader(ListView1.Handle);
  GetWindowRect(Header, HeaderRect);
  HeaderHeight := HeaderRect.Bottom - HeaderRect.Top;
  if MousePos.Y < HeaderHeight then
    ListView1.PopupMenu := HeaderMenu;
end;

@Sertac のアプローチとは少し異なります。呼び出さない点ClientToScreenPtInRect- ポイントが ListView の境界内にあることがわかっているため、クリックの高さを簡単にテストするだけで、ヘッダーまたは列領域にいるかどうかを知ることができます。また、常に に割り当てられたポップアップ メニューの少なくとも 1 つが常に存在するようにしますListView

于 2012-06-29T13:41:52.440 に答える
0

これが私がそれを解決した方法ですが、私はこの解決策が好きではありません。あなたがより良いものを持っているならば、書き留めてください、私はそれを正しいものとして受け入れます。

uses
  CommCtrl;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ListView.PopupMenu := TPopupMenu.Create(Self);
  ListView.PopupMenu.OnPopup := ListViewPopup;
end;

procedure TForm1.ListViewPopup(Sender: TObject);
var
  Pos: TPoint;
  SrcMenu: TPopupMenu;
  I: Integer;
  MenuItem: TMenuItem;
  Header: HWND;
  HeaderRect: TRect;
  HeaderHeight: Integer;
begin
  // Re-filling ListView's popup menu
  ListView.PopupMenu.Items.Clear();

  // Getting header height
  Header := ListView_GetHeader(ListView.Handle);
  GetWindowRect(Header, HeaderRect);
  HeaderHeight := HeaderRect.Bottom - HeaderRect.Top;
  Pos := ListView.ScreenToClient(ListView.PopupMenu.PopupPoint);

  // Clicked on header?
  if Pos.Y < HeaderHeight then
    SrcMenu := PopupMenuColumns
  else
    SrcMenu := PopupMenuItems;

  // Copying destired menu to ListView.PopupMenu
  for I := 0 to SrcMenu.Items.Count - 1 do
  begin
    MenuItem := TMenuItem.Create(FListViewPopupMenu);

    with SrcMenu.Items[I] do
    begin
      MenuItem.Action := Action;
      MenuItem.Caption := Caption;
      MenuItem.ShortCut := ShortCut;
      MenuItem.Checked := Checked;
      MenuItem.Enabled := Enabled;
      MenuItem.OnClick := OnClick;
      MenuItem.HelpContext := HelpContext;
      MenuItem.Name := Name;
      MenuItem.ImageIndex := ImageIndex;
    end;

    ListView.PopupMenu.Items.Add(MenuItem);
  end;

  ListView.PopupMenu.Images := SrcMenu.Images;
end;
于 2012-06-29T10:01:16.930 に答える