Как в приложении Win32 определить - на котором объекте D2D1PathGeometry была нажата левая клавиша мыши, если в окне несколько таких объектов?
В своём приложении Win32 на Visual C++, я создал два объекта D2D1PathGeometry. Вот они ниже:
// Функция для рисования.
HRESULT MyClass::OnRender()
{
HRESULT hr = S_OK;
. . . . .
// Создать первый объект (m_pDirect2dFactory это экземпляр ID2D1Factory, созданный ранее).
hr = m_pDirect2dFactory->CreatePathGeometry(&m_pMyGeom_1);
if (SUCCEEDED(hr))
{
// pSink это экземпляр ID2D1GeometrySink, созданный ранее.
hr = pMyGeom_1->Open(&pSink);
if (SUCCEEDED(hr))
{
pSink->SetFillMode(D2D1_FILL_MODE_WINDING);
// Добавить дугу.
pSink->BeginFigure(m_InitialPoint_1, D2D1_FIGURE_BEGIN_FILLED);
pSink->AddArc(D2D1::ArcSegment(m_EndPoint_1, m_Radius, 0.0f, D2D1_SWEEP_DIRECTION_CLOCKWISE, D2D1_ARC_SIZE_SMALL));
pSink->EndFigure(D2D1_FIGURE_END_CLOSED);
// Добавить линию.
pSink->BeginFigure(m_InitialPoint_1, D2D1_FIGURE_BEGIN_HOLLOW);
pSink->AddLine(m_EndPoint_1);
pSink->EndFigure(D2D1_FIGURE_END_CLOSED);
}
hr = pSink->Close();
}
// Создать второй объект.
hr = m_pDirect2dFactory->CreatePathGeometry(&m_pMyGeom_2);
if (SUCCEEDED(hr))
{
hr = m_pMyGeom_2->Open(&pSink);
if (SUCCEEDED(hr))
{
pSink->SetFillMode(D2D1_FILL_MODE_WINDING);
// Добавить дугу.
pSink->BeginFigure(m_InitialPoint_2, D2D1_FIGURE_BEGIN_FILLED);
pSink->AddArc(D2D1::ArcSegment(m_BackEndPoint_2, m_Radius, 0.0f, D2D1_SWEEP_DIRECTION_CLOCKWISE, D2D1_ARC_SIZE_SMALL));
pSink->EndFigure(D2D1_FIGURE_END_CLOSED);
// Добавить линию.
pSink->BeginFigure(m_InitialPoint_2, D2D1_FIGURE_BEGIN_HOLLOW);
pSink->AddLine(m_EndPoint_2);
pSink->EndFigure(D2D1_FIGURE_END_CLOSED);
}
hr = pSink->Close();
}
. . . . .
SafeRelease(&pSink);
// Начать отрисовку (m_pRenderTarget это созданный ранее экземпляр ID2D1HwndRenderTarget).
m_pRenderTarget->BeginDraw();
. . . . .
m_pRenderTarget->FillGeometry(m_pMyGeom_1, m_pMidnightBlueBrush);
m_pRenderTarget->FillGeometry(m_pMirror_2, m_pMidnightBlueBrush);
. . . . .
hr = m_pRenderTarget->EndDraw();
}
Затем, я добавил сообщения WM_LBUTTONDOWN, WM_MOUSEMOVE и WM_LBUTTONUP в WindowProc и определил для них соответствующие обработчики: OnLButtonDown(int pixelX, int pixelY, DWORD flags), OnMouseMove(int pixelX, int pixelY, DWORD flags) and OnLButtonUp().
// Нажата левая клавиша мыши.
void MyClass::OnLButtonDown(int pixelX, int pixelY, DWORD flags)
{
// Получить координаты мыши в момент нажатия её левой клавиши.
POINT mouseLocation;
mouseLocation.x = pixelX;
mouseLocation.y = pixelY;
// Если курсор мыши наведён на объект ID2D1PathGeometry в окне приложения:
if (DragDetect(m_hwnd, mouseLocation))
{
// Перевести физические пиксели в системные DPI и запомнить как текущие координаты мыши.
ptMouse = PixelsToDips(pixelX, pixelY);
SetCapture(m_hwnd);
// Приготовиться к drag-and-drop объекта геометрии ID2D1PathGeometry.
f_DragMode = true;
}
}
// Пользователь перемещает мышь.
void MyClass::OnMouseMove(int pixelX, int pixelY, DWORD flags)
{
// Проверить, нажата ли левая клавиша мыши.
if ((flags & MK_LBUTTON) && f_DragMode)
{
const D2D1_POINT_2F dips = PixelsToDips(pixelX, pixelY);
// Как определить над каким из 2-х объектов геометрии ID2D1PathGeometry
// в окне приложения находится курсор мыши? !!!НЕ ЗНАЮ!!!
// Поэтому дальше в этом обработчике - ничего существенного не написал.
// Сохранить текущие координаты мыши.
ptMouse = dips;
// Инициировать перерисовку окна.
InvalidateRect(m_hwnd, NULL, FALSE);
}
}
// Пользователь отпустил левую клавишу мыши.
void MyClass::OnLButtonUp()
{
ReleaseCapture();
if (!f_DragMode)
f_DragMode = false;
}
Как определить в программе - над какой из геометрией в окне находится мышь (если DragDetect вернула true)? Пояснений к этому я не нашёл нигде. До этого мне практически не приходилось писать код для событий мыши, да и с Direct2D я знаком только 7-й день. Любая помощь будет принята с благодарностью.
Источник: Stack Overflow на русском