如何保证我获得用户在 CTreeControl 中右键单击的项目的 `HTREEITEM`

How to guarantee that I get the `HTREEITEM` for the item that the user right-clicked on in a CTreeControl

我有一个 window,它有一个 CTreeCtrl。用户可以右键单击任何元素并显示上下文菜单。他们可以从那里选择删除条目。像这样:

这是上下文菜单项处理程序的片段:

void CAssignHistoryDlg::OnDeleteFromAssignmentHistory()
{
    CString         strINI = theApp.GetAssignHistoryPath();
    HTREEITEM       hItem = m_treeHistory.GetSelectedItem();
    CString         strName, strDeletedName, strEntry;

    if (m_treeHistory.GetParentItem(hItem) != nullptr)
    {
        // The user has picked one of the history dates.
        // So the parent should be the actual name.
        hItem = m_treeHistory.GetParentItem(hItem);

        // Now OK to proceed
    }

    strName = ExtractName(hItem);

    GetParent()->EnableWindow(FALSE);
    strEntry.Format(IDS_TPL_SURE_DELETE_FROM_ASSIGN_HIST, strName);
    if (AfxMessageBox(strEntry, MB_YESNO | MB_ICONQUESTION) == IDNO)
    {

图片显示了我的问题。如果我首先点击测试,那么它是selected和亮蓝色然后然后右击,在弹出信息中显示Test。这可以。但是...

如果名字最初selected,我继续直接对-单击 Test,即使它看起来变成蓝色(好像 selected),m_treeHistory.GetSelectedItem() 正在返回原来的名字。我觉得我描述的不是很好

简而言之,我想保证我得到了用户右击的项目的HTREEITEM。我的也不是100%万无一失

如果有帮助,这是我显示上下文菜单的方式:

void CAssignHistoryDlg::OnNMRclickTreeHistory(NMHDR *pNMHDR, LRESULT *pResult)
{
    CMenu           mnuContext, *pMnuEdit = nullptr;
    CPoint          ptLocal;
    LPNMTREEVIEW    pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);

    GetCursorPos(&ptLocal);

    mnuContext.LoadMenu( IDR_MENU_SM_ASSIGN_HIST_POPUP );
    pMnuEdit = mnuContext.GetSubMenu( 0 );
    if (pMnuEdit != nullptr)
    {
        pMnuEdit->TrackPopupMenu( TPM_LEFTALIGN|TPM_LEFTBUTTON,
                    ptLocal.x, ptLocal.y, this, nullptr );
    }

    *pResult = 0;
}

所以回顾一下,目前用户必须物理左键单击树中的项目才能 select 它。然后他们可以右键单击,它会提出删除此人。但是如果他们继续并右击任何人,它不会提供删除那个人。

您可以使用 CTreeCtrl class 的 HitTest() 成员在任何给定点获取 actual 树项。具体如何 在何处 执行此操作将取决于您的代码设计,但是,如果您有一个指向 CTreeCtrl 的指针(下面代码中的 pwTree),那么你可以这样做:

CPoint ptLocal;
GetCursorPos(&ptLocal);
pWTree->ScreenToClient(&ptLocal); // May not be required in certain handlers?
HTREEITEM hItem = pWTree->HitTest(ptLocal); // Remember to check for NULL return!

然后您可以直接使用返回的 hItem,或使用它 显式 设置树的选择(到该项目),然后再进行任何进一步处理。

MS 文档:https://docs.microsoft.com/en-us/cpp/mfc/reference/cwnd-class?view=vs-2019 没有“点击”处理程序,它有 CWnd::OnRButtonDblClkCWnd::OnRButtonDownCWnd::OnRButtonUp。你在处理哪一个?

您的缺陷的原因可能是您没有让树控件处理那个右键事件(select那个新项目)。

我建议改用 CWnd::OnContextMenu