[C][winapi] Menu Kontekstowe a ListView

0

Menu kontekstowe dla kontrolki ListView tworzę dynamicznie podczas obsługi komunikatu WM_NOTIFY o kodzie NM_RCLICK:

if(NotifyHeader->code == NM_RCLICK)
{
    if(((NMITEMACTIVATE *)NotifyHeader)->iItem != -1)
    {
        GetCursorPos(&Point);
        PopupMenu = CreatePopupMenu();

        InsertMenu(PopupMenu, 0, MF_BYPOSITION | MF_STRING, ID_POPUP_01, _T("MenuItem01"));
        InsertMenu(PopupMenu, 0, MF_BYPOSITION | MF_STRING, ID_POPUP_01, _T("MenuItem02"));

        SetForegroundWindow(GetDlgItem(DlgHandle, IDC_LSV_01));

        TrackPopupMenu(PopupMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, Point.x, Point.y, 0, 
        GetDlgItem(DlgHandle, IDC_LSV_01), NULL);
    }
}

Pytanie: jakie zdarzenie jest generowane podczas wyboru jednej z opcji menu? Wydawało mi się, że zostanie wygenerowany komunikat WM_COMMAND ale tak się nie dzieje. Jak określić, który wiersz kontrolki ListView został kliknięty generując menu tak by można było odczytać dane z tego wiersza? Z góry dziękuję za wszelkie wskazówki.

AdrianO

0

witaj,
funkcja trackPopupMenu jako przedostatni parametr przyjmuje uchwyt okna do którego zostanie wysłany WM_COMMAND, wiec powinieneś podać aktualny uchwyt okna , a nie uchwyt listView, bo jego procedury nie obsługujesz.

Jeśli chcesz wiedzieć który element został kliknięty to musisz sworzyć taką strukturę, MenuItemInfo (chbya tak sie nazywa ona). i w niej ustawić odpowiednią maskę, i do jej pola o nazwie bodajże dwItemData przypisać swoją pozycję ((NMITEMACTIVATE *)NotifyHeader)->iItem;
Potem należy użyć funkcjii SetMenuItem (lub jakoś tak podobnie sie nazywającej).

Jak juz otrzymasz WM_COMMAND to wtedy używasz funkcji GetMenuItemInfo() i wniej znowu sie używa tej struktury MenuItemInfo, tylko tym razem otrzymasz to co zapisałeś do elementu dwItemData tej struktury i juz masz pozycje która została kliknięta.

troche namieszałem ale idzie wszytko ogarnąć:)
Pozdro:)

0

g_all dzięki za odpowiedź.

Do podobnego wniosku doszedłem po dokładniejszej analizie tej funkcji i próbowałem przekierować komunikat WM_COMMAND do procedury ListView, którą stworzyłem wcześniej na potrzeby owner draw. Coś musiałem jednak zchrzanić ponieważ komunikat nigdy nie trafiał do tej procedury. Po zmianie tego parametru, tak jak wspomniałeś, wszystko pięknie działa. Nie spodziewałem się, że rozwiązane tego problemu może być aż tak banalne.

A pozyskiwanie elementu menu oraz wiersza listy, do którego to menu dotyczy rozwiązałem w zupełnie inny sposób niż zaproponowany. Nie jestem pewien czy jest to najlepsze rozwiązanie (zwłaszcza analizując Twoją propozycję) ale w moim przypadku spisuje się znakomicie. A oto fragment poprawionego kodu - może komuś się przyda.

WM_NOTIFY
...
if(NotifyHeader->code == NM_RCLICK)
{
    if(((NMITEMACTIVATE *)NotifyHeader)->iItem != -1)
    {
        GetCursorPos(&Point);

        PopupMenu = CreatePopupMenu();

        InsertMenu(PopupMenu, 0, MF_BYPOSITION | MF_STRING, ID_POPUP_01, _T("MenuItem01"));
        InsertMenu(PopupMenu, 0, MF_BYPOSITION | MF_STRING, ID_POPUP_02, _T("MenuItem02"));

        SetForegroundWindow(GetDlgItem(DlgHandle, IDC_LSV_01));

        TrackPopupMenu(PopupMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, Point.x, Point.y, 0, DlgHandle, NULL);
    }
}
...

WM_COMMAND
...
switch(Id)
{
    case ID_POPUP_01:
        ListHandle = GetDlgItem(DlgHandle, IDC_LSV_01);

        SelectedItem = ListView_GetNextItem(ListHandle, -1, LVNI_SELECTED);
		// pobranie zaznaczonego elementu listy
        ListView_GetItemText(ListHandle, SelectedItem, 0, ItemText, 10);
		// pobranie zawartosci elementu znajdującego się w pierwszej kolumnie

        MessageBox(0, ItemText, 0, 0);
    break;

    case ID_POPUP_02:
        ListHandle = GetDlgItem(DlgHandle, IDC_LSV_01);

        SelectedItem = ListView_GetNextItem(ListHandle, -1, LVNI_SELECTED);
        ListView_GetItemText(ListHandle, SelectedItem, 1, ItemText, 10);
		// pobranie zawartosci elementu znajdującego się w drugiej kolumnie

        MessageBox(0, ItemText, 0, 0);
    break;
}
...

Pozdrawiam,
AdrianO

1 użytkowników online, w tym zalogowanych: 0, gości: 1