2012-06-29 4 views
7

私はViewStyle = vsReportと2ポップアップメニューでリストビューがあります。ユーザーのヘッダーバー アイテムポップアップメニューと一緒にListViewヘッダーバーのポップアップメニューを設定する方法は?

  • 項目ポップアップメニューを右クリックしたときに、私がオープンしたい

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

    メニューを表示する最も正しい方法は何ですか?どのイベントを処理すればよいですか?

    問題は、ListView.PopupMenuプロパティを設定したときに発生します。ポップアップメニューは、ListViewのクライアント矩形内の任意のポイントを右クリックした後に表示されます。

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

    イベントLisView.OnMouseUpは、アイテムの下の空白を右クリックしてから起動します。

  • +0

    アイテムの上にいるときや、サブアイテムを過ぎているときにだけ、 'PopupMenuItems'メニューポップアップを表示しますか? – TLama

    +0

    @TLamaはい、副題もあります – Andrew

    答えて

    8

    は、未設定のままにしておき、あなたは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; 
    
    +1

    私にそれを打つ。 :-) IDEからテストコードをコピーして、「新しい回答が投稿されました」というバナーが表示されたときに同じことを言う回答を貼り付けました。 +1。 –

    +0

    @Ken - それは数時間前の質問で起こるとき、私はそれが奇妙に思う、ごめんなさい..そしてありがとう。 :) –

    +0

    私には恥ずかしい、あなたは正しい。 OnContextPopup! – Andrew

    0

    これは私が解決した方法ですが、私はこの解決策が嫌いです。あなたがより良いものを持っているなら、書き留めてください、私はそれを正しいものとして受け入れます。あなたは、リストビューのPopupMenuプロパティを使用する必要はありません

    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; 
    
    +0

    この解決策について気に入らないのですか? – NGLN

    +0

    @NGLNメニュー項目をコピーする必要があるときはちょっと変わった感じです。 WinAPIレベルにスライドして何かすることは可能だと思いました。 – Andrew

    3

    かなり簡単にすることができます。あなたの2つのポップアップメニュー(ヘッダー行に1つずつと列を作成IDEでTListView.PopupMenu列のポップアップメニューを割り当てリストビューのイベントハンドラのための

    使用これを:。。

    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; 
    

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

    関連する問題