Detect clicking inside listview and show context menu

孤街浪徒 提交于 2019-12-09 18:51:18

问题


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;
    }

回答1:


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).




回答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.



来源:https://stackoverflow.com/questions/12796501/detect-clicking-inside-listview-and-show-context-menu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!