Если Вы работали с графическими программами типа Corel Draw или с этим Вы точно работали Pain, то вы должны знать этот прием. Когда выделяете несколько объектов или рисуете приямоугольник, то у Вас появляется резиновый контур, который будет тянуться за мышкой. С технологией программирования данного метода мы и познакомимся.
Создавайте проект MFC AppWizard имя проекта MouseSelect ставьте Single Document и жмите Finish. Вы можете делать по другому скажем для Doc здесь все упрощено ;-)))).
Все методы будут для класса CMouseSelectView. Итак давайте разберемся с логикой.
Нажали мышкой. Тут надо сообщить, что начали рисовать и получить начальные координаты Тащим. Постоянного перерисовываем контур Отпускаем. Прекращаем рисовать о чем сообщаем
Создаем две переменные одна типа CRect, в которой мы будем хранить координаты квадрата вторая BOOL, чтобы определить, что мы действительно рисуем квадрат, а не метаемся по экрану от скуки.
class CMouseSelectView : public CView { ..... BOOL TestDraw; CRect MouseRect; ........ };Теперь нужно начальная инициализация
CMouseSelectView::CMouseSelectView() { // TODO: add construction code here TestDraw=FALSE; }
Нажатие мышкой
void CMouseSelectView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default TestDraw=TRUE; DrawLine(); MouseRect.left=point.x; MouseRect.top=point.y; MouseRect.right =point.x; MouseRect.bottom =point.y; SetCapture(); CView::OnLButtonDown(nFlags, point); }
Тащим
void CMouseSelectView::OnMouseMove(UINT nFlags, CPoint point) { if (TestDraw) { DrawLine(); MouseRect.right=point.x; MouseRect.bottom = point.y; DrawLine(); CView::OnMouseMove(nFlags, point); } }
Отпускаем
void CMouseSelectView::OnLButtonUp(UINT nFlags, CPoint point) { TestDraw=FALSE; ReleaseCapture(); CView::OnLButtonUp(nFlags, point); }
А это загадочная DrawLine:
void CMouseSelectView::DrawLine() { CClientDC dc(this); int oldMode=dc.SetROP2(R2_NOT); CBrush* oldBrush=(CBrush*)dc.SelectStockObject(NULL_BRUSH); CPen* oldPen = (CPen*) dc.SelectStockObject(BLACK_PEN); dc.Rectangle(MouseRect); dc.SelectObject(oldBrush); dc.SelectObject(oldPen); dc.SetROP2(oldMode); }
Итак смотрим. При нажатии левой кнопкой мы устанавливаем координаты MouseRect, в точку. После этого вызываем SetCapture. Это интересная функция. Она скажет Windows, что мышка работает только для данного приложения даже за его приделами. Когда мы мышку перемещаем, то стираем старый прямоугольник и рисуем новый с измененными координатами. В момент когда мышка отпущена освобождаем мышку :-) ReleaseCapture и сбрасываем флаг рисования.
Самое интересно происходит в DrawLine мы получаем контекст устройства, с которым работаем dc(this). Мы устанавливаем режим инвертирования пикселей dc.SetROP2(R2_NOT) сохраняя старый режим. Зачем ? Инвентировали в одну сторону видно, еще раз и изображение восстановилось. Это много лучше, чем перерисовывать весь экран. Дальше устанавливаем перья, рисуем прямоугольник и восстанавливаем режим и перья контекста.
Здесь не предусмотрено много. Например поменяйте размер окна и изображение будет подпорченно. Появится квадрат. Ну это уже не очень большая проблемма. Пишите дополнения :-)))).