3

I have a listview created as a resource and loaded on a dialog window. I want to detect and show a context menu only when items within the listview have been clicked.

 MESSAGE_HANDLER(WM_CONTEXTMENU,OnContextMenu)

        LRESULT OnContextMenu(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
            {
                int iSelected = -1;
    int iFocusGroup = -1;
    iSelected = SendMessage((HWND)wParam, LVM_GETNEXTITEM, -1,LVNI_SELECTED);
    iFocusGroup = ListView_GetFocusedGroup((HWND)wParam);
    if( iSelected != -1 && iFocusGroup == -1) {
                    hPopupMenu = CreatePopupMenu();
                    Insert

Menu(hPopupMenu,  0,     MF_BYCOMMAND | MF_STRING | MF_ENABLED, ID_SHREDTASK_CTXMENU_DELETE, TEXT("Delete"));
                TrackPopupMenu(hPopupMenu, TPM_TOPALIGN | TPM_LEFTALIGN, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0, m_hWnd, NULL); 
            }
            return 0;
        }

OK, I've edited this and it works the way it is presented here but the question still stands and can someone explain to me what's the thing with focus group here and why if I send the LVM_GETNEXTITEM message while in the dialog it returns != -1 ? isn't it solely for Listviews ?

EDIT :

Here is another alternative that I've worked out based on your responses:

LRESULT OnNotifyRClick(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
          switch (uMsg)
        {
            case WM_NOTIFY:
                switch (((LPNMHDR)lParam)->code)
                {
                case NM_RCLICK:
                    if (((LPNMHDR)lParam)->idFrom == IDC_LISTTASKFILES)
                    {                       
                         int iSelected = -1;
                         iSelected = SendMessage(GetDlgItem(IDC_LISTTASKFILES), LVM_GETNEXTITEM, -1,LVNI_SELECTED);

                        if( iSelected != -1 ) {
                            hPopupMenu = CreatePopupMenu();
                            InsertMenu(hPopupMenu,  0,     MF_BYCOMMAND | MF_STRING | MF_ENABLED, ID_SHREDTASK_CTXMENU_DELETE, TEXT("Delete"));
                            TrackPopupMenu(hPopupMenu, TPM_TOPALIGN | TPM_LEFTALIGN, ((CPoint)GetMessagePos()).x, ((CPoint)GetMessagePos()).y, 0, m_hWnd, NULL); 
                        }
                         bHandled = true;

                        return TRUE;
                    }
                    break; 

                break;
                }

        }
          return false;
    }
fire xzanderr
  • 213
  • 2
  • 13
  • I don't quite understand: You mix MFC and raw WINAPI. What's the point? Try to be consistent first: Either all MFC or all WINAPI but mixing both is not a good idea. – Serge Wautier Oct 09 '12 at 19:16
  • I don't use MFC at all. I use WTL & winapi. – fire xzanderr Oct 10 '12 at 07:18
  • Oops, sorry, I was misleaded by the MESSAGE_HANDLER macro that looks like the ON_MESSAGE MFC macro... and by you tagging the question as MFC! You should then remove this tag – Serge Wautier Oct 10 '12 at 07:37
  • Ok, you can put the blame on me, I just thought that MFC pple would know winapi in general. Anyway, removed it. – fire xzanderr Oct 10 '12 at 07:50

2 Answers2

2

You will have OnContextMenu handler called regardless of click position within the listview. Now your task is to see where exactly click happened and decide on the action you want.

Your question make me think that you grabbed the code with ListView_GetFocusedGroup from internet as opposed to intentially writing it yourself. What you need to do however, is to send "hit test" message back to list view providing the point of interest (which is the click point): ListView_HitTest, ListView_HitTestEx.

Having this done you obtain the item and/or subitem in this location, and you can decide what to do next.

Roman R.
  • 68,205
  • 6
  • 94
  • 158
  • I didn't grabbed the code from the internet, it's just they I thought it would work.. I was trying to detect when the Listview is in focus, and while searching for functions & properties I found that function. but I don't think I actually did it the right way. – fire xzanderr Oct 10 '12 at 07:20
  • That's OK too. It was just not quite clear why you look for focused group exactly. Instead the first thing you want is to see where exactly the click took place. Having *item number* on hands you can check if it is focused, selected, belong to a group etc. – Roman R. Oct 10 '12 at 07:31
2

NM_RCLICK is your friend.

But it doesn't solve the whole problem, such as displaying a context menu when user hits the Windows menu key on his keyboard. This KB article shows how to combine NM_RCLICK and WM_CONTEXTMENU. (It's for the CTreeCtrl but adapting the code to CListView is trivial).

Serge Wautier
  • 21,494
  • 13
  • 69
  • 110