2012-06-29 10 views
7

Mam ListView z ViewStyle = vsReport i dwóch menu podręczne:Jak ustawić wyskakujące menu paska nagłówkowego ListView wraz z menu podręcznym elementów?

  1. Column podręczne menu, którą chcesz otworzyć, gdy użytkownik prawym przyciskiem
  2. Item podręczne menu pasku nagłówka, należy otworzyć kiedy użytkownik kliknie prawym przyciskiem myszy dowolny element listy/podelement lub spacje pod pozycjami poniżej.

Jaki jest najlepszy sposób wyświetlania menu? Z którymi wydarzeniami powinienem sobie poradzić?

Problem polega na tym, że ustawiam właściwość ListView.PopupMenu, a menu podręczne pojawia się po kliknięciu prawym przyciskiem myszy dowolnego punktu w prostokącie klienta ListView.

Kiedy obsługuję zdarzenie ListView.OnColumnRightClick, uruchamiam tylko po kliknięciu nagłówka kolumny, z wyłączeniem wolnego miejsca na pasku nagłówka (po prawej stronie kolumn).

Zdarzenie LisView.OnMouseUp strzela tylko po kliknięciu prawym przyciskiem myszy białych znaków pod pozycjami.

+0

Czy chcesz, aby menu podręczne "PopupMenuItems" było wyświetlane tylko wtedy, gdy skończyłeś pozycję lub nawet, gdy masz już ponad podróbkę? – TLama

+0

@TLama tak, ponad subitem też – Andrew

Odpowiedz

8

Nie trzeba używać własność pogrupowanych PopupMenu, pozostawić wyłączony i można dołączyć do OnContextPopup obsługi zdarzenia i uruchomić cokolwiek menu popup chcesz w zależności od położenia. Przykład:

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

Pokonaj mnie. :-) Kopiowałem swój kod testowy z IDE, aby wkleić do mojej odpowiedzi mówiąc to samo, kiedy pojawił się baner "nowa odpowiedź wysłana". +1. –

+0

@Ken - wydaje mi się dziwne, kiedy to dzieje się na kilkugodzinnym pytaniu, przepraszam .. i dziękuję. :) –

+0

Wstyd mi, masz rację. OnContextPopup! – Andrew

0

Tak to rozwiązałem, ale nie podoba mi się to rozwiązanie. Jeśli masz lepszy, zapisz, przyjmuję to jako poprawny.

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

Co ci się nie podoba w tym rozwiązaniu? – NGLN

+0

@NGLN To trochę dziwne, gdy trzeba skopiować elementy menu. Myślałem, że można zjechać na poziom WinAPI i coś tam zrobić. – Andrew

3

Możesz go znacznie uprościć. Tworzyć dwa popup menu (po jednej dla wiersza nagłówka i kolumn Przyporządkować TListView.PopupMenu menu podręczne kolumny w IDE

użyć tego do obsługi zdarzeń dla 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; 

To nieznacznie różni się od podejścia @ Sertac, nie wywołując ClientToScreen i PtInRect - ponieważ wiemy, że punkt znajduje się w granicach ListView, prosty test wysokości kliknięcia wystarczy, aby wiedzieć, czy jesteśmy w obszarze nagłówka lub kolumny. Zapewnia również, że zawsze jest zawsze co najmniej jedno z menu wyskakujących przypisanych do ListView.

Powiązane problemy