IDC_PICTURE 坐标上的 OnMouseMove
OnMouseMove on IDC_PICTURE coordinates
我正在 Visual Studio 2017 年 windows 环境中开发一个显示实时 LiDAR 点云的 MFC 应用程序。
现在所有显示功能都运行良好,我已经按如下方式实现了它们:
使用资源编辑器将静态图片元素添加到我的 CDialog
对话框中,将其命名为 IDC_PICTURE
。
在我的 class 的头文件中定义了以下内容:
CStatic m_Picture;
CRect m_rectangle;
将静态图片(IDC_PICTURE
)与CStatic属性(m_picture
)链接如下:
void MyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_PICTURE, m_Picture);
//other static lists and indicators
}
通过关联一个CRect
元素来获取图片尺寸和坐标,我是这样实现的:
在我的 OnInitDialog()
中,我将 m_picture 关联到 m_rectangle
,然后在单独的变量中获得维度,如下所示:
m_Picture.GetWindowRect(m_rectangle);
PicWidth = m_rectangle.Width();
PicHeight = m_rectangle.Height();
然后,为了显示点云,我编写了一个名为 DrawData
的函数,其主体如下:
int MyDlg::DrawData(void)
{
CDC* pDC = m_Picture.GetDC();
CDC memDC;
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC, PicWidth, PicHeight);
//iterate over the points in my point cloud vector
// use memDC.setpixel() method to display the points one by one
//then:
pDC->StretchBlt(0, 0, PicWidth, PicHeight, &memDC, 0, 0, PicWidth, PicHeight, SRCCOPY);
bmp.DeleteObject();
memDC.DeleteDC();
ReleaseDC(pDC);
}
到这里一切都很好。我的问题在下面。
现在我需要仅在矩形内(IDC_PICTURE)根据矩形的坐标系(而不是整个window)显示鼠标光标的坐标.
因此,我通过执行以下操作在我的代码中集成了 OnMouseMove()
函数:
BEGIN_MESSAGE_MAP(CalibrationDLG, CDialog)
ON_WM_PAINT()
ON_WM_MOUSEMOVE() // added this to take mouse movements into account
//OTHER BUTTON MESSAGES..
END_MESSAGE_MAP()
函数体如下所示:
void CalibrationDLG::OnMouseMove(UINT nFlags, CPoint point)
{
CDC* dc;
dc = GetDC();
CString str;
CPoint ptUpLeft = m_rect_calib.TopLeft(); // get the coordinates of the top left edge of the rectangle
CPoint ptDownRight = m_rect_calib.BottomRight(); // get the coordinates of the bottom right edge of the rectangle
if (point.x >= ptUpLeft.x && point.x <= ptUpLeft.x+ m_rect_calib.Width() && point.y >= ptUpLeft.y && point.y <= ptUpLeft.y+ m_rect_calib.Height())
{
str.Format(_T("x: %d y: %d"), point.x, point.y);
dc->TextOut(10, 10, str);
ReleaseDC(dc);
CDialog::OnMouseMove(nFlags, point);
}
}
我的问题是我得到的坐标不正确。
甚至我的条件定义的区域限制:
if (point.x >= ptUpLeft.x &&
point.x <= ptUpLeft.x + m_rect_calib.Width() &&
point.y >= ptUpLeft.y &&
point.y <= ptUpLeft.y + m_rect_calib.Height())
似乎没有限制我要找的区域。 它比真实的 IDC_PICTURE
表面小得多。
有人知道我在这里错过了什么吗? 如何转换鼠标坐标使其仅相对于 IDC_PICTURE 区域?
谢谢
坐标是相对于处理鼠标移动事件的客户区的,在你的例子中是对话框。您希望它们相对于图片控件的客户区。您可以通过识别它们具有共同的屏幕坐标来在它们之间进行转换。
// transform from this dialog's coordinates to screen coordinates
this->ClientToScreen(&point);
// transform from screen coordinates to picture control coordinates
m_picture.ScreenToClient(&point);
如果您不处理整个对话框的鼠标移动,而是从 CStatic
派生您自己的图片 class 并处理它 OnMouseMove
,则您可以取消所有这些转换。那么你接收到的点就已经在图片控件的坐标中了。
我正在 Visual Studio 2017 年 windows 环境中开发一个显示实时 LiDAR 点云的 MFC 应用程序。
现在所有显示功能都运行良好,我已经按如下方式实现了它们:
使用资源编辑器将静态图片元素添加到我的 CDialog
对话框中,将其命名为 IDC_PICTURE
。
在我的 class 的头文件中定义了以下内容:
CStatic m_Picture;
CRect m_rectangle;
将静态图片(IDC_PICTURE
)与CStatic属性(m_picture
)链接如下:
void MyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_PICTURE, m_Picture);
//other static lists and indicators
}
通过关联一个CRect
元素来获取图片尺寸和坐标,我是这样实现的:
在我的 OnInitDialog()
中,我将 m_picture 关联到 m_rectangle
,然后在单独的变量中获得维度,如下所示:
m_Picture.GetWindowRect(m_rectangle);
PicWidth = m_rectangle.Width();
PicHeight = m_rectangle.Height();
然后,为了显示点云,我编写了一个名为 DrawData
的函数,其主体如下:
int MyDlg::DrawData(void)
{
CDC* pDC = m_Picture.GetDC();
CDC memDC;
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC, PicWidth, PicHeight);
//iterate over the points in my point cloud vector
// use memDC.setpixel() method to display the points one by one
//then:
pDC->StretchBlt(0, 0, PicWidth, PicHeight, &memDC, 0, 0, PicWidth, PicHeight, SRCCOPY);
bmp.DeleteObject();
memDC.DeleteDC();
ReleaseDC(pDC);
}
到这里一切都很好。我的问题在下面。
现在我需要仅在矩形内(IDC_PICTURE)根据矩形的坐标系(而不是整个window)显示鼠标光标的坐标.
因此,我通过执行以下操作在我的代码中集成了 OnMouseMove()
函数:
BEGIN_MESSAGE_MAP(CalibrationDLG, CDialog)
ON_WM_PAINT()
ON_WM_MOUSEMOVE() // added this to take mouse movements into account
//OTHER BUTTON MESSAGES..
END_MESSAGE_MAP()
函数体如下所示:
void CalibrationDLG::OnMouseMove(UINT nFlags, CPoint point)
{
CDC* dc;
dc = GetDC();
CString str;
CPoint ptUpLeft = m_rect_calib.TopLeft(); // get the coordinates of the top left edge of the rectangle
CPoint ptDownRight = m_rect_calib.BottomRight(); // get the coordinates of the bottom right edge of the rectangle
if (point.x >= ptUpLeft.x && point.x <= ptUpLeft.x+ m_rect_calib.Width() && point.y >= ptUpLeft.y && point.y <= ptUpLeft.y+ m_rect_calib.Height())
{
str.Format(_T("x: %d y: %d"), point.x, point.y);
dc->TextOut(10, 10, str);
ReleaseDC(dc);
CDialog::OnMouseMove(nFlags, point);
}
}
我的问题是我得到的坐标不正确。 甚至我的条件定义的区域限制:
if (point.x >= ptUpLeft.x &&
point.x <= ptUpLeft.x + m_rect_calib.Width() &&
point.y >= ptUpLeft.y &&
point.y <= ptUpLeft.y + m_rect_calib.Height())
似乎没有限制我要找的区域。 它比真实的 IDC_PICTURE
表面小得多。
有人知道我在这里错过了什么吗? 如何转换鼠标坐标使其仅相对于 IDC_PICTURE 区域? 谢谢
坐标是相对于处理鼠标移动事件的客户区的,在你的例子中是对话框。您希望它们相对于图片控件的客户区。您可以通过识别它们具有共同的屏幕坐标来在它们之间进行转换。
// transform from this dialog's coordinates to screen coordinates
this->ClientToScreen(&point);
// transform from screen coordinates to picture control coordinates
m_picture.ScreenToClient(&point);
如果您不处理整个对话框的鼠标移动,而是从 CStatic
派生您自己的图片 class 并处理它 OnMouseMove
,则您可以取消所有这些转换。那么你接收到的点就已经在图片控件的坐标中了。