Я разрабатываю приложение MFC, которое отображает облака точек LiDAR в реальном времени на Visual Studio 2017 в среде Windows.
Теперь все функции дисплея работают нормально, и я реализовал их следующим образом:
Добавлен статический элемент изображения в мой 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 rectangleif (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
, Тогда полученная вами точка уже будет в координатах элемента управления изображением.
Других решений пока нет …