screentoclient(ScreenToClient和ClientToScreen )
一、MFC中,鼠标在picture control控件内移动,显示坐标
GetCursorPos获取的是屏幕坐标,GetClientRect是窗口坐标,两个坐标系不匹配,PtInRect结果当然错误。
你这个程序的正确做法:
PtInRect判断应该放在函数首部,如果这个判断返值为FALSE,那么后面的坐标计算根本没有必要,效率提升不说,还避免了坐标系映射之类的可能产生的影响。
在OnMouseMove里面,GetCursorPos没用并且会降低效率。判断坐标应该使用函数参数来进行即可。
遇到坐标系不同的情况,可以使用ScreenToClient/ClientToScreen函数对,将坐标转换为相同的坐标系,再进行运算和判断。
二、MFC tree control中点击树的节点时才弹出右键菜单
参考:MFC TreeCtrl树形控件中限定右键点击节点弹出菜单
voidCGar3Dlg::OnRclickTreePhase(NMHDR*pNMHDR,LRESULT*pResult)
{
//TODO:在此添加控件通知处理程序代码
//动态加载菜单
CMenumenu[3];
menu[0].LoadMenu(IDR_MENU2);
menu[1].LoadMenu(IDR_MENU3);
menu[2].LoadMenu(IDR_MENU4);
CPointpt;
//pt=GetCurrentMessage()->pt;//获取当前鼠标点击消息的坐标点
GetCursorPos(&pt);
m_maintree.ScreenToClient(&pt);//将鼠标的屏幕坐标,转换成树形控件的客户区坐标
UINTuFlags=0;
HTREEITEMhItem=m_maintree.HitTest(pt,&uFlags);//然后做点击测试
if((hItem!=NULL)&&(TVHT_ONITEM&uFlags))//如果点击的位置是在节点位置上面
{
m_maintree.SelectItem(hItem);
//根据不同类型的节点弹出菜单
CMenu*psubmenu;
intnData=m_maintree.GetItemData(hItem);
m_maintree.ClientToScreen(&pt);
switch(nData)
{
case0:
psubmenu=menu[0].GetSubMenu(0);
break;
case1:
psubmenu=menu[1].GetSubMenu(0);
break;
case2:
psubmenu=menu[2].GetSubMenu(0);
break;
default:
break;
}
psubmenu->TrackPopupMenu(TPM_RIGHTBUTTON,pt.x,pt.y,this);
}
*pResult=0;
}