Визуальное редактирование данных
Теперь вы, вероятно, подготовлены к восприятию того, что происходит в следующих трех методах класса CDrawView. Первые два вы должны создать как реакции на сообщения WM_LBUTTONDOWN и WM_MOUSEMOVE, а последний (member function) – просто поместить в файл реализации класса, так как его прототип уже существует:
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point) { //====== В режиме создания нового полигона if (m_bNewPoints) { CTreeDoc *pDoc = GetDocument(); //====== Ссылка на массив точек текущего полигона VECPTSS pts = pDoc › m_Poly.m_Points; //=== Получаем адрес текущего контекста устройства CDC *pDC = GetDC(); //====== Настраиваем его с учетом размеров окна SetDC(pDC); //=== Преобразуем аппаратные координаты в логические pDC › DPtoLP(ipoint); //=== Преобразуем Page-координаты в World-координаты CDPoint pt = pDoc › MapToWorldPt(point); //====== Запоминаем в контейнере pts.push_back (pt); } //====== В режиме готовности к захвату else if (m_bReady) { ra_bLock = true; // Запоминаем состояние захвата m_bReady = false; // Снимаем флаг готовности } //====== В режиме повторного нажатия else if (mJbLock) m_bLock = false; // Снимаем флаг захвата else //В случае бездумного нажатия return; // уходим Invalidated; // Просим перерисовать } void CDrawView::OnMouseMove(UINT nFlags, CPoint point) { //=== В режиме создания нового полигона не участвуем if (m_bNewPoints) return; //====== Получаем и настраиваем контекст CDC *pDC = GetDCO; SetDC(pDC); //=== Преобразуем аппаратные координаты в логические pDC › DPtoLP(Spoint); //=== Преобразуем Page-координаты в World-координаты CTreeDoc *pDoc = GetDocument(); CDPoint pt = pDoc › MapToWorldPt(point); //====== Если был захват, то перерисовываем //====== контуры двух соседних с узлом линий if (m_bLock) { // Курсор должен показывать операцию перемещения SetCursor(m_hGrab); //====== Установка режима pDC › SetROP2(R2_XORPEN); //====== Двойное рисование //====== Сначала стираем старые линии RedrawLines(pDC, pDoc › MapToLogPt (pDoc › m_Poly.m_Points[ra_CurID])); //====== Затем рисуем новые RedrawLines(pDC, point); //====== Запоминаем новое положение вершины pDoc › m_Poly.m_Points[m_CurID] = pt; } //====== Обычный режим поиска близости к вершине else { m_CurID = pDoc › FindPoint(pt); // Если близко, то m_CurID получит индекс вершины // Если далеко, то индекс будет равен -1 m_bReady = m_CurID >= 0; //=== Если близко, то меняем курсор if (m_bReady) SetCursor(m_hGrab); } } //====== Перерисовка двух линий, соединяющих //====== перемещаемую вершину с двумя соседними void CDrawView::RedrawLines (CDC *pDC, CPointS point) { CTreeDoc *pDoc = GetDocument(); //====== Ссылка на массив точек текущего полигона VECPTS& pts = pDoc › m_Poly.m_Points; UINT size = pts.sizeO; //====== Если полигон вырожден, уходим if (size < 2) return; //====== Индексы соседних вершин int i1 = m_CurID == 0? size -1: m_CurID -1; int 12 = m_CurID == size -1? 0: m_CurID + 1; // ====== Берем перо и рисуем две линии pDC › SelectObject(Sm_penLine); pDC › MoveTo(pDoc › MapToLogPt(pts[11])); pDC › LineTo(point); pDC › LineTo(pDoc › MapToLogPt(pts[12])); }