如何保证我获得用户在 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::OnRButtonDblClk
、CWnd::OnRButtonDown
和 CWnd::OnRButtonUp
。你在处理哪一个?
您的缺陷的原因可能是您没有让树控件处理那个右键事件(select那个新项目)。
我建议改用 CWnd::OnContextMenu
。
我有一个 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::OnRButtonDblClk
、CWnd::OnRButtonDown
和 CWnd::OnRButtonUp
。你在处理哪一个?
您的缺陷的原因可能是您没有让树控件处理那个右键事件(select那个新项目)。
我建议改用 CWnd::OnContextMenu
。