在IDC_PICTURE坐标上进行amousemove

OnMouseMove on IDC_PICTURE coordinates

本文关键字:amousemove 坐标 IDC PICTURE      更新时间:2023-10-16

我正在开发一个MFC应用程序,该应用程序在Windows环境中在Visual Studio 2017上显示实时LIDAR点云。

现在所有的显示功能都可以正常工作,我已经实现了以下内容:

使用资源编辑器将其称为IDC_PICTURE,在我的CDialog对话框中添加了一个静态图片元素。

在我的类的标题文件中定义了以下内容:

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(,并根据矩形的坐标系(不是整个窗口(。。因此,我通过执行以下操作将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派生并处理它的OnMouseMove,则可以消除所有这些转换。那么您收到的点已经在图片控制的坐标中。