请教,如何获取鼠标单击位置相对于屏幕位置的坐标点

时间:2022-10-14 10:23:33
请教,如何获取鼠标单击位置相对于屏幕位置的坐标点。(这里我可能已经获取了一个相对于控件的坐标,需要转换下)。另外,如何获取状态栏矩形框相对于屏幕位置的坐标也一并说下,谢谢

17 个解决方案

#1


ScreenToClient();
ClientToScreen();
主要就这两个函数

#2


没错,跟风一下

#3


1楼的,这两个函数貌似不行,我明明鼠标点击的位置在屏幕接近*的位置,转化后结果还是被判断成了在状态栏中。

#4


首先,你要确认是哪一个窗口捕获了你鼠标的信息。如果你没有特意的设置鼠标捕获,默认的一般为鼠标下所在Z order的最上层窗口所捕获。
其次,转换坐标时要清楚你获得的鼠标位置是那个窗口的,然后你要转换到那个窗口。如果不能理解成员函数的含义的话可以使用全局函数::ScreenToClient();
::ClientToScreen();

#5


BOOL GetCursorPos( 
  LPPOINT lpPoint
); 
获取鼠标所在位置。。

#6


POINT pMouse;
GetCursorPos(&pMouse);

获取鼠标做在桌面的坐标

#7


引用 5 楼 shen_wei 的回复:
BOOL GetCursorPos( 
  LPPOINT lpPoint
); 
获取鼠标所在位置。。

这个函数使用时是有限制条件的。使用前貌似要判断吧

#8


引用 4 楼 panasonic0804 的回复:
首先,你要确认是哪一个窗口捕获了你鼠标的信息。如果你没有特意的设置鼠标捕获,默认的一般为鼠标下所在Z order的最上层窗口所捕获。
其次,转换坐标时要清楚你获得的鼠标位置是那个窗口的,然后你要转换到那个窗口。如果不能理解成员函数的含义的话可以使用全局函数::ScreenToClient();
::ClientToScreen();


是在这个函数中做的处理

BOOL CMainFrame::PreTranslateMessage(MSG* lpMsg)
{
if (lpMsg->message == WM_LBUTTONDBLCLK)
            int xPos = LOWORD(lpMsg->lParam); // 鼠标双击位置
            int yPos = HIWORD(lpMsg->lParam);

m_wndStatusBar.GetItemRect(0, &(rc));
CPoint pt(xPos, yPos);
ClientToScreen(&rc);
ClientToScreen(&pt);

if (PtInRect(&rc, pt))

}


像上面这样写好像不行。不论在状态信息栏范围内双击还是别的地方双击都被判定为不在范围内,感觉这样转换有问题,如果用::ClientToScreen必须是要指定窗口句柄的,这东西不知道选哪个窗口

#9


如果,我把ClientToScreen(&pt) 改成 ::ClientToScreen(m_hwnd&pt);后,双击信息状态栏和屏幕中间的某个控件,都被判断成了在rect中了。

#10


引用 8 楼 shineheart 的回复:
引用 4 楼 panasonic0804 的回复:
首先,你要确认是哪一个窗口捕获了你鼠标的信息。如果你没有特意的设置鼠标捕获,默认的一般为鼠标下所在Z order的最上层窗口所捕获。
其次,转换坐标时要清楚你获得的鼠标位置是那个窗口的,然后你要转换到那个窗口。如果不能理解成员函数的含义的话可以使用全局函数::ScreenToClient();
::ClientToScreen();

……

唉,我已经说过了。
首先,你看明白你点击鼠标时,是那个窗口捕获鼠标事件的。
其次,你所获得的鼠标坐标为捕获鼠标那个窗口的客户区坐标。
最后,按照上述情况转换到你需要的坐标系。

这样对照你的CMainFrame::PreTranslateMessage(MSG* lpMsg)可以看出至少有几个问题了。同时你的疑惑都在这上面。

#11


你要是单纯单击屏幕的话那就得 PreTranslateMessage(MSG* lpMsg) 里自己处理,这已经和你的对话框毛关系没有了、

#12


10楼的,11楼的,你们看我处理的在哪个函数里头就知道了。代码在上面贴出来了呢

#13


还有没有人。

#14


您好
我是本版版主
此帖已多日无人关注
请您及时结帖
如您认为问题没有解决可按无满意结帖处理
另外本版设置了 疑难问题汇总帖
并已在版面置顶
相关规定其帖子中有说明
您可以根据规定提交您帖子的链接
如您目前不想结帖只需回帖说明
我们会删除此结帖通知

见此回复三日内无回应
我们将强制结帖
相关规定详见界面 界面版关于版主结帖工作的具体办法

#15


版主怎么不给解答一下……

#16


这是ListControl的应用,代码写的比较菜,凑合看下吧!

//判断鼠标点击的是否是图标,
//如果是:则退出;
CPoint mousePoint;
if (GetCursorPos(&mousePoint))
{
CRect icnRect;
if (m_list.GetSubItemRect(pNMListView->iItem, pNMListView->iSubItem, LVIR_ICON, icnRect)){
CPoint icnLTpoint(icnRect.left, icnRect.top);
::ClientToScreen(m_list.m_hWnd, &icnLTpoint);
icnRect.left = icnLTpoint.x;
icnRect.top = icnLTpoint.y;

icnLTpoint = icnRect.BottomRight();
::ClientToScreen(m_list.m_hWnd, &icnLTpoint);
icnRect.right = icnLTpoint.x;
icnRect.bottom = icnLTpoint.y;

if (icnRect.PtInRect(mousePoint)){
return;
}
}
}

#17


,[[touches anyObject] locationInView:self.view

#1


ScreenToClient();
ClientToScreen();
主要就这两个函数

#2


没错,跟风一下

#3


1楼的,这两个函数貌似不行,我明明鼠标点击的位置在屏幕接近*的位置,转化后结果还是被判断成了在状态栏中。

#4


首先,你要确认是哪一个窗口捕获了你鼠标的信息。如果你没有特意的设置鼠标捕获,默认的一般为鼠标下所在Z order的最上层窗口所捕获。
其次,转换坐标时要清楚你获得的鼠标位置是那个窗口的,然后你要转换到那个窗口。如果不能理解成员函数的含义的话可以使用全局函数::ScreenToClient();
::ClientToScreen();

#5


BOOL GetCursorPos( 
  LPPOINT lpPoint
); 
获取鼠标所在位置。。

#6


POINT pMouse;
GetCursorPos(&pMouse);

获取鼠标做在桌面的坐标

#7


引用 5 楼 shen_wei 的回复:
BOOL GetCursorPos( 
  LPPOINT lpPoint
); 
获取鼠标所在位置。。

这个函数使用时是有限制条件的。使用前貌似要判断吧

#8


引用 4 楼 panasonic0804 的回复:
首先,你要确认是哪一个窗口捕获了你鼠标的信息。如果你没有特意的设置鼠标捕获,默认的一般为鼠标下所在Z order的最上层窗口所捕获。
其次,转换坐标时要清楚你获得的鼠标位置是那个窗口的,然后你要转换到那个窗口。如果不能理解成员函数的含义的话可以使用全局函数::ScreenToClient();
::ClientToScreen();


是在这个函数中做的处理

BOOL CMainFrame::PreTranslateMessage(MSG* lpMsg)
{
if (lpMsg->message == WM_LBUTTONDBLCLK)
            int xPos = LOWORD(lpMsg->lParam); // 鼠标双击位置
            int yPos = HIWORD(lpMsg->lParam);

m_wndStatusBar.GetItemRect(0, &(rc));
CPoint pt(xPos, yPos);
ClientToScreen(&rc);
ClientToScreen(&pt);

if (PtInRect(&rc, pt))

}


像上面这样写好像不行。不论在状态信息栏范围内双击还是别的地方双击都被判定为不在范围内,感觉这样转换有问题,如果用::ClientToScreen必须是要指定窗口句柄的,这东西不知道选哪个窗口

#9


如果,我把ClientToScreen(&pt) 改成 ::ClientToScreen(m_hwnd&pt);后,双击信息状态栏和屏幕中间的某个控件,都被判断成了在rect中了。

#10


引用 8 楼 shineheart 的回复:
引用 4 楼 panasonic0804 的回复:
首先,你要确认是哪一个窗口捕获了你鼠标的信息。如果你没有特意的设置鼠标捕获,默认的一般为鼠标下所在Z order的最上层窗口所捕获。
其次,转换坐标时要清楚你获得的鼠标位置是那个窗口的,然后你要转换到那个窗口。如果不能理解成员函数的含义的话可以使用全局函数::ScreenToClient();
::ClientToScreen();

……

唉,我已经说过了。
首先,你看明白你点击鼠标时,是那个窗口捕获鼠标事件的。
其次,你所获得的鼠标坐标为捕获鼠标那个窗口的客户区坐标。
最后,按照上述情况转换到你需要的坐标系。

这样对照你的CMainFrame::PreTranslateMessage(MSG* lpMsg)可以看出至少有几个问题了。同时你的疑惑都在这上面。

#11


你要是单纯单击屏幕的话那就得 PreTranslateMessage(MSG* lpMsg) 里自己处理,这已经和你的对话框毛关系没有了、

#12


10楼的,11楼的,你们看我处理的在哪个函数里头就知道了。代码在上面贴出来了呢

#13


还有没有人。

#14


您好
我是本版版主
此帖已多日无人关注
请您及时结帖
如您认为问题没有解决可按无满意结帖处理
另外本版设置了 疑难问题汇总帖
并已在版面置顶
相关规定其帖子中有说明
您可以根据规定提交您帖子的链接
如您目前不想结帖只需回帖说明
我们会删除此结帖通知

见此回复三日内无回应
我们将强制结帖
相关规定详见界面 界面版关于版主结帖工作的具体办法

#15


版主怎么不给解答一下……

#16


这是ListControl的应用,代码写的比较菜,凑合看下吧!

//判断鼠标点击的是否是图标,
//如果是:则退出;
CPoint mousePoint;
if (GetCursorPos(&mousePoint))
{
CRect icnRect;
if (m_list.GetSubItemRect(pNMListView->iItem, pNMListView->iSubItem, LVIR_ICON, icnRect)){
CPoint icnLTpoint(icnRect.left, icnRect.top);
::ClientToScreen(m_list.m_hWnd, &icnLTpoint);
icnRect.left = icnLTpoint.x;
icnRect.top = icnLTpoint.y;

icnLTpoint = icnRect.BottomRight();
::ClientToScreen(m_list.m_hWnd, &icnLTpoint);
icnRect.right = icnLTpoint.x;
icnRect.bottom = icnLTpoint.y;

if (icnRect.PtInRect(mousePoint)){
return;
}
}
}

#17


,[[touches anyObject] locationInView:self.view