Здорова ребятки!
Сегодня обсудим такую штуку, как прокрутка представлений в MFC.
Он как вы видите, существуют такие от выделенные красным такие от полосы прокрутки и ползунки на них, от как раз в этом посте мы научимся их создавать, в MFC они создаются с помощью класса CScrollView
И так приступим, будем редактировать приложение которое было разобрано в посте MFC — множественное обновление представления, у нас есть приложение которое там было разработано
Оно умеет рисовать лини, но увы в нем нету полос прокрутки, как же нам быть? Будем добавлять полосы прокрутки, для этого нам нужно изменить класс вида. В нашем приложении класс вида наследуется от класса View, нам нужно что б он наследовался от класса CScrollView, заменим View на CScrollView в заголовочном файле с определением класса у меня это будет
1 2 3 4 5 6 7 8 |
... //class Cmdi1View : public CView class Cmdi1View : public CScrollView { protected: // создать только из сериализации Cmdi1View(); DECLARE_DYNCREATE(Cmdi1View) ... |
и так идем дальше в классе с определением замените так же CView на CScrollView, у меня это
1 2 3 4 5 6 7 |
... //IMPLEMENT_DYNCREATE(Cmdi1View, CView) IMPLEMENT_DYNCREATE(Cmdi1View, CScrollView) //BEGIN_MESSAGE_MAP(Cmdi1View, CView) BEGIN_MESSAGE_MAP(Cmdi1View, CScrollView) ... |
эти строки находятся вначале файла .cpp
Нам еще нужно перегрузить переопределение OnInitialUpdate
1 2 3 4 5 6 7 8 9 |
void Cmdi1View::OnInitialUpdate() { CScrollView::OnInitialUpdate(); //Определить размер документа CSize DocSize(20000,20000); //Установить режим отображения и размер документа SetScrollSizes(MM_TEXT,DocSize,CSize(500,500),CSize(50,50)); } |
здесь мы вызываем функцию SetScrollSizes в которой устанавливаем режим отображения MM_TEXT, вторым параметром идет размер документа 20000 на 20000 пикселей, следующий параметр определяет приращение прокрутки страницы как 500 пикселей и приращение прокрутки строки как 50 пикселей. Все можем компилировать и у нас в приложении появляются полосы прокрутки
Но увы наше приложение работает не правильно, если мы переместимся с помощью полосы прокрутки чуть ниже и попытаемся нарисовать линию у нас ничего не получится
Логические координаты и клиентские
А это происходит все потому что у нас точки сохраняются в клиентских координатах. Клиентские координаты — это координаты которые начинаются из левого угла клиентской области и до правого угла, но мы перекрутили колесико в низ и поэтому у нас линия рисуется в клиентских координатах, то есть она рисуется в начале нашей области так как область определяется в логических координатах. Нам нужно перевести клиентские координаты в логические. Для этого в функциях где мы получаем точки для сохранения в документе, а это обработчик левого клика мышки и обработчик правого клика нам нужно добавить код который будет переводить клиентские координаты в логические
1 2 3 |
CClientDC aDC(this);//получить контекст устройства OnPrepareDC(&aDC);//уточнить начальную точку в логических координатах aDC.DPtoLP(&point);//перевод из клиентских координат в логические |
и соответственно меняем обработчики OnRButtonDown
1 2 3 4 5 6 7 8 9 10 11 12 |
void Cmdi1View::OnRButtonDown(UINT nFlags, CPoint point) { CClientDC aDC(this);//получить контекст устройства OnPrepareDC(&aDC);//уточнить начальную точку в логических координатах aDC.DPtoLP(&point);//перевод из клиентских координат в логические Cmdi1Doc* pDoc=GetDocument(); pDoc->p2=point; //делаем недействительной всю область представления //InvalidateRect(nullptr); pDoc->UpdateAllViews(nullptr);//обновляем все виды } |
и OnLButtonDown
1 2 3 4 5 6 7 8 9 |
void Cmdi1View::OnLButtonDown(UINT nFlags, CPoint point) { CClientDC aDC(this);//получить контекст устройства OnPrepareDC(&aDC);//уточнить начальную точку в логических координатах aDC.DPtoLP(&point);//перевод из клиентских координат в логические Cmdi1Doc* pDoc=GetDocument(); pDoc->p1=point; } |
компилируем программу, запускаем и ВУАЛЯ мы уже можем рисовать линию и когда область представления прокручена
На этом все, прокрутка готова!
[youtube]https://www.youtube.com/watch?v=yYnd_xxqPdQ[/youtube]