Сегодня разберемся как в MFC работать с мышкой, мы разберем несколько обработчиков мышки такие как WM_LBUTTONDOWN, WM_MOUSEMOVE и WM_LBUTTONUP. Это три таких основных события мышки, от для них мы попытаемся создать обработчики. и так начнем.
Создаем MFC приложение, самое простое, у вас должно появится такое окошко как ниже на скрине
Теперь добавим 3 обработчика мышки для событий нажание мышки, движения мышки и отпускания клавиш мышки соответственно WM_LBUTTONDOWN, WM_MOUSEMOVE, WM_LBUTTONUP. Дабавим мы их в класс вида, идем в окно классов , выбираем класс вида у меня это Ctest2View, заходим в его свойства, выбираем события и добавляем обработчики для нужных нам событий: WM_LBUTTONDOWN, WM_MOSEMOVE, WM_LBUTTONUP
У вас появится 3 обработчика смотрим код ниже
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
void Ctest2View::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: добавьте свой код обработчика сообщений или вызов стандартного CView::OnLButtonDown(nFlags, point); } void Ctest2View::OnMouseMove(UINT nFlags, CPoint point) { // TODO: добавьте свой код обработчика сообщений или вызов стандартного CView::OnMouseMove(nFlags, point); } void Ctest2View::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: добавьте свой код обработчика сообщений или вызов стандартного CView::OnLButtonUp(nFlags, point); } |
Ани пустые, давайте добавим в обработчик WM_LBUTTONDOWN и WM_LBUTTONUP вывод сообщений, «нажата левая кнопка мышки» и «отпущена кнопка мышки» соответсвенно
1 2 3 4 5 6 7 8 9 |
void Ctest2View::OnLButtonDown(UINT nFlags, CPoint point) { AfxMessageBox(_T("Нажата левая кнопка мышки")); } void Ctest2View::OnLButtonUp(UINT nFlags, CPoint point) { AfxMessageBox(_T("Отпущена левая кнопка мышки")); } |
Откомпилируем и нажмем левую кнопку мышки
теперь нажмите Enter чтобы пропал MessageBox и отпустите клавишу мышки
Дальше давайте изменим обработчик события WM_MOUSEMOVE так чтобы при движении мышки рисовалась линия
1 2 3 4 5 6 7 8 9 10 11 12 |
void Ctest2View::OnMouseMove(UINT nFlags, CPoint point) { CClientDC aDC(this);//создаем контекст устройства if(m_start.x==-1)//если -1 то начало { m_start=point; return; } aDC.MoveTo(m_start);//устанавливаем начальную точку aDC.LineTo(point);//рисуем линию m_start=point;//запоминаем конечную точку } |
Так же мы должны добавить переменную m_start типа Cpoint и инициализировать ее в конструкторе значением Cpoint(-1,-1). Все запускаем и когда мы водим по области вида у нас появляется линия, то есть обрабатывается событие WM_MOUSEMOVE вызывается наша функция и рисуется линия маленькая от одной точки до другой и так из таких маленьких линий формируется наш вид.
Ну тут одна проблема у наш мышка Должна быть захвачена для нашего окна и ее координаты должны следиться и за пределами окна. Как это сделать? Да очень просто давайте добавим строчку в обработчик мышки нажатие клавиши
1 2 3 4 5 6 |
void Ctest2View::OnLButtonDown(UINT nFlags, CPoint point) { AfxMessageBox(_T("Нажата левая кнопка мышки")); SetCapture();//захват мышки для окна, перехвачивает //все сообщения мышки и за пределами ока } |
Но опять же чтобы не перегружать программу и не вызывать каждый раз код рисования, мы должны в обработчике сообщения WM_MOUSEMOVE сделать проверку что курсор принадлежит нашему окну.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
void Ctest2View::OnMouseMove(UINT nFlags, CPoint point) { //если курсор пренадлежит нашему окну, то тогда рисуем if(this==GetCapture()) { CClientDC aDC(this);//создаем контекст устройства if(m_start.x==-1)//если -1 то начало { m_start=point; return; } aDC.MoveTo(m_start);//устанавливаем начальную точку aDC.LineTo(point);//рисуем линию m_start=point;//запоминаем конечную точку } } |
и конечно нужно освободить курсор, это мы сделаем в функции отжатия левой клавиши мышки с помощью функции ReleaseCapture .
1 2 3 4 5 6 |
void Ctest2View::OnLButtonUp(UINT nFlags, CPoint point) { if(this==GetCapture());//Если захвачен курсор мышки, освободить ReleaseCapture(); AfxMessageBox(_T("Отпущена левая кнопка мышки")); } |
Все у нас курсор начинает рисовать, когда мы нажимаем левую клавишу мышки, а когда мы отпускаем ее он перестает рисовать. Ну в общем я чуток не правильно сформулировал, курсор захвачивается , а рисует он потому что захвачен и освобождается он по отпусканию мышки, но тут я подметил, что курсор так же перестает рисовать когда мы какой нить AfxMessageBox вызываем, так же само перестает уже рисовать, то есть збивается захват.
Давайте чуток изменим код, что б только при нажатии левой клавиши мышки можно было рисовать, а если мы ее отпускаем, то рисовать уже нельзя.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
void Ctest2View::OnLButtonDown(UINT nFlags, CPoint point) { //AfxMessageBox(_T("Нажата левая кнопка мышки")); SetCapture();//захват мышки для окна, перехвачивает //все сообщения мышки и за пределами ока m_start=point; } void Ctest2View::OnMouseMove(UINT nFlags, CPoint point) { //если курсор пренадлежит нашему окну, то тогда рисуем if((nFlags&MK_LBUTTON)&&(this==GetCapture())) { CClientDC aDC(this);//создаем контекст устройства aDC.MoveTo(m_start);//устанавливаем начальную точку aDC.LineTo(point);//рисуем линию m_start=point;//запоминаем конечную точку } } void Ctest2View::OnLButtonUp(UINT nFlags, CPoint point) { if(this==GetCapture());//Если захвачен курсор мышки, освободить ReleaseCapture(); // AfxMessageBox(_T("Отпущена левая кнопка мышки")); } |
и мы можем уже рисовать изображения как в Painte
В коде выше мы проверяем флаг nFlags там он может содержать несколько значений
Символические значения используемые в аргументе nFlags
Флаг | Описание |
MK_CONTROL | Соответствует нажатой клавише <Ctrl> |
MK_LBUTTON | Соответствует нажатию левой кнопки мыши |
MK_MBUTTON | Соответствует нажатию средней кнопки мыши |
MK_RBUTTON | Соответствует нажатию правой кнопки мыши |
MK_XBUTTON1 | Соответствует нажатию первой дополнительной кнопки мыши |
MK_XBUTTON2 | Соответствует нажатию второй дополнительной кнопки мыши |
MK_SHIFT | Соответствует нажатию клавиши <Shift> |
На это пока все, в принципе запрограммировать мышь мы уже сможем, там ничего сложного нету, в двух слава, создаем обработчик для сообщения мышки и обрабатываем это сообщение и все!
[youtube]https://www.youtube.com/watch?v=aGKkALykGow[/youtube]