VS2010生成的类视图中,树形控件的类是CViewTree,正常情况是可以获得节点的如:
void CViewTree::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: Add your control notification handler code here
DWORD dw = GetMessagePos(); // Mouse position
CPoint p(GET_X_LPARAM(dw), GET_Y_LPARAM(dw));
this->ScreenToClient(&p); UINT htFlags = 0;
HTREEITEM hHitItem= this->HitTest(p, &htFlags); // Find tree item which was clicked.
//hHitItem为当前选中的节点
if(hHitItem == NULL)
return;
if( NULL != hHitItem )
{...}
}
在这个树控件中添加了一个右键菜单,但是点击菜单时获取的树节点出错,总是第二次选择菜单功能时get的坐标以及节点,看了很多资料,看别的用CTreeCtrl m_ctltree来控制获得树节点就可以,我觉得可能是CViewTree的this和m_ctltree不一样的原因。但是不知道怎么解决!求大神帮忙~~~~
void CViewTree::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: Add your control notification handler code here
DWORD dw = GetMessagePos(); // Mouse position
CPoint p(GET_X_LPARAM(dw), GET_Y_LPARAM(dw));
this->ScreenToClient(&p); UINT htFlags = 0;
HTREEITEM hHitItem= this->HitTest(p, &htFlags); // Find tree item which was clicked.
//hHitItem为当前选中的节点
if(hHitItem == NULL)
return;
if( NULL != hHitItem )
{...}
}
在这个树控件中添加了一个右键菜单,但是点击菜单时获取的树节点出错,总是第二次选择菜单功能时get的坐标以及节点,看了很多资料,看别的用CTreeCtrl m_ctltree来控制获得树节点就可以,我觉得可能是CViewTree的this和m_ctltree不一样的原因。但是不知道怎么解决!求大神帮忙~~~~
开头加一句
LPTVITEM pTreeItem=(LPTVITEM)pNMHDR;
pTreeItem->hItem就是HTREEITEM
试了一下,pTreeItem->hItem是空的,貌似获取不到
NMTREEVIEW* pTreeNM=(NMTREEVIEW*)pNMHDR;
里面
TVITEM itemOld;
TVITEM itemNew;可以得知句柄
试了一下,用itemNew.hItem和itemOld.hItem,都是空的,不好意思啊,有没有别的办法啊,主要问题是点击menu会又获取一次节点,所以总是出错
我觉得还是得把代码都贴出来才能找到根~
我的右键弹出menu函数:void CViewTree::OnNMRClick(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: Add your control notification handler code here
POINT pt;
GetCursorPos(&pt);
this->ScreenToClient(&pt);
UINT htFlags = TVHT_ONITEM;
HTREEITEM hHitItem= this->HitTest(pt, &htFlags); // Find tree item which was clicked.
//hHitItem为当前选中的节点
if(hHitItem == NULL)
return;
if( NULL != hHitItem)
{
CString temp = this->GetItemText(hHitItem);
this->SelectItem(hHitItem);
CMenu menu;
menu.LoadMenu(IDR_POPUP_TREE);
CMenu *pop = menu.GetSubMenu(0);
POINT ptMouse;
GetCursorPos(&ptMouse);
pop->TrackPopupMenu (TPM_LEFTALIGN|TPM_LEFTBUTTON,ptMouse.x,ptMouse.y,this);
}
//::AfxMessageBox(GetItemText(hHitItem.hItem));
*pResult = 0;
}菜单响应函数:
void CViewTree::OnNewClass(){
/*1:
POINT pt;
GetCursorPos(&pt);
//DWORD dw = GetCursorPos(pt); // Mouse position
//CPoint p(GET_X_LPARAM(dw), GET_Y_LPARAM(dw));
this->ScreenToClient(&pt); UINT htFlags = 0;
HTREEITEM hHitItem= this->HitTest(pt, &htFlags); */
// 2:
HTREEITEM hHitItem = this->GetSelectedItem();
//hHitItem为当前选中的节点
if(hHitItem == NULL) {
::AfxMessageBox(_T("null"));
}
if( NULL != hHitItem)
{
CString strItem = this->GetItemText(hHitItem);
::AfxMessageBox(strItem);
} //HTREEITEM hNew=this->InsertItem(_T("111"),1,0,this->GetSelectedItem());
}
消息响应函数中1,2两种方法获得selected树节点都不行,都是获取的第二次点击的位置~求助!!~~~
NMTREEVIEW* pTreeNM=(NMTREEVIEW*)pNMHDR;
检查pTreeNM->ptDrag的点位是否有用OnNewClass看上去是一个ON_COMMAND回调?
那么在按下子菜单选择的同时焦点还是在子菜单上,可能有影响,不知道SetFocus有用否?
去掉setforcus还是不行,我想换一种思路,让ClassView类获得CViewTree类的ON_COMMAND,可是总是没有反应,不知道这样写对不对:
void CViewTree::OnNMRClick(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: Add your control notification handler code here
//NMTREEVIEW* pTreeNM=(NMTREEVIEW*)pNMHDR;
//TVITEM hHitItem = pTreeNM->itemNew;
POINT pt;
GetCursorPos(&pt);
//DWORD dw = GetCursorPos(pt); // Mouse position
//CPoint p(GET_X_LPARAM(dw), GET_Y_LPARAM(dw));
this->ScreenToClient(&pt);
/*DWORD dw = GetMessagePos(); // Mouse position
CPoint p(GET_X_LPARAM(dw), GET_Y_LPARAM(dw));
this->ScreenToClient(&p); */ UINT htFlags = TVHT_ONITEM;
HTREEITEM hHitItem= this->HitTest(pt, &htFlags); // Find tree item which was clicked.
//hHitItem为当前选中的节点
if(hHitItem == NULL)
return;
if( NULL != hHitItem)
{
CString temp = this->GetItemText(hHitItem);
if(temp != _T("生理部位")){
this->SelectItem(hHitItem);
//this->SetFocus();
CMenu menu;
menu.LoadMenu(IDR_POPUP_TREE);
CMenu *pop = menu.GetSubMenu(0);
POINT ptMouse;
GetCursorPos(&ptMouse);
CMainFrame *pMain=(CMainFrame *)AfxGetApp()->m_pMainWnd;
CClassView *pView=(CClassView *)pMain->GetActiveView(); pop->TrackPopupMenu(TPM_LEFTALIGN,ptMouse.x,ptMouse.y,pView);
}
}
*pResult = 0;
}
消息响应在ClassWizard加的,可是就是木有反应,不知道大神有什么招没~
//CMainFrame *pMain=(CMainFrame *)AfxGetApp()->m_pMainWnd;
//CClassView *pView=(CClassView *)pMain->GetActiveView();pop->TrackPopupMenu(TPM_LEFTALIGN,ptMouse.x,ptMouse.y,this->GetParent());
这样弹出可以在CClassView响应,响应函数:
void CClassView::OnNewclass()
{
// TODO: Add your command handler code here
HTREEITEM hHitItem = m_wndClassView.GetSelectedItem();
if(hHitItem == NULL) {
::AfxMessageBox(_T("111"));
}
if( NULL != hHitItem)
{
CString strItem = m_wndClassView.GetItemText(hHitItem);
::AfxMessageBox(_T("111"));
::AfxMessageBox(strItem);
}
}
还是获取的是再次点击的节点!郁闷啊!好像点击菜单的时候是再获取一次树控件的焦点,再去响应菜单函数的!怎么搞啊!!!纠结!!
是的是的!!好了!!太感谢了!!!
这是VS2010自动生成的类视图的OnContextMenu函数:
void CClassView::OnContextMenu(CWnd* pWnd, CPoint point)
{
CTreeCtrl* pWndTree = (CTreeCtrl*)&m_wndClassView;
ASSERT_VALID(pWndTree); if (pWnd != pWndTree)
{
CDockablePane::OnContextMenu(pWnd, point);
return;
} if (point != CPoint(-1, -1))
{
// 选择已单击的项:
CPoint ptTree = point;
pWndTree->ScreenToClient(&ptTree); UINT flags = 0;
HTREEITEM hTreeItem = pWndTree->HitTest(ptTree, &flags);
if (hTreeItem != NULL)
{
//pWndTree->SelectItem(hTreeItem); //注释掉
}
} //pWndTree->SetFocus(); //注释掉
CMenu menu;
menu.LoadMenu(IDR_POPUP_SORT); CMenu* pSumMenu = menu.GetSubMenu(0); if (AfxGetMainWnd()->IsKindOf(RUNTIME_CLASS(CMDIFrameWndEx)))
{
CMFCPopupMenu* pPopupMenu = new CMFCPopupMenu; if (!pPopupMenu->Create(this, point.x, point.y, (HMENU)pSumMenu->m_hMenu, FALSE, TRUE))
return; ((CMDIFrameWndEx*)AfxGetMainWnd())->OnShowPopupMenu(pPopupMenu);
UpdateDialogControls(this, FALSE);
}
}就好了!!!!
感谢amoxilin314给我OnContextMenu提示!!
感激不尽!!