c++ - IDC_PICTURE 坐标上的 OnMouseMove

标签 c++ mfc visual-studio-2017 onmousemove

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

现在所有显示功能都工作正常,我已按如下方式实现它们:

使用资源编辑器将静态图片元素添加到我的 CDialog 对话框中,并将其命名为 IDC_PICTURE

在我的类的头文件中定义以下内容:

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,则可以消除所有这些转换。那么您收​​到的点将已经在图片控件的坐标中。

关于c++ - IDC_PICTURE 坐标上的 OnMouseMove,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49492872/

相关文章:

c++ - Exception C++ 第 1 章第 1 部分中的 copy() 算法如何使用?

visual-c++ - MFC:默认使用什么方法将工具栏按钮设置为总工具栏按钮的子集?

Azure 函数 - VS2017 工具 - function.json 中缺少绑定(bind)

c++ - 错误 LNK2038 : mismatch detected for '_MSC_VER' : value '1800' doesn't match value '1900'

c++ - 如何用opencv读取电表指针?

c++ - 计算 cpp 周到当前日期时间的秒数,

c++ - 如何在 mfc 中更正此错误?

python - 为什么 Python 在 Visual Studio 2017 中损坏?

c++ - 您如何检测在运行时静态加载的 DLL?

c++ - SubclassWindow() 函数断言