Upload
others
View
10
Download
0
Embed Size (px)
Citation preview
Object-oriented programming Lecture №13
Sergey Aksenov
Object-oriented programming Lecture №13
Modify the example from lecture 9 // ChildView.h : the interface of CChildView
//
#pragma once
#include "Circle.h"
#include <vector>
class CChildView : public CWnd {
. . .
//CCircle m_Circles;
//Now we need an arraay of circles
std::vector<Ccircle *> m_Objects;
//bool m_bCatched;
int m_nCatched;
CPoint m_MousePos;
//If the point is inside of a circle,
//the function will return its number, otherwise -1
int FindObject(CPoint point);
. . .
};
2
Object-oriented programming Lecture №13
Modify the example from lecture 9 // ChildView.cpp Implementation of CChildView
. . .
CChildView::CChildView(){
m_nCatched = -1; // Initialization
}
CChildView::~CChildView()
{
// Clear the memory allocated for the circles
for(int i=0; m_Objects(); i++){
delete m_Objects[i];
}
}
. . .
3
Object-oriented programming Lecture №13
Modify the example from lecture 9 // ChildView.cpp Implementation of CChildView . . .
void CChildView::OnPaint()
{
CPaintDC dc(this); // device context for drawing
for(int i=0; i< m_Objects.size(); i++){
m_Objects[i]->Draw(dc);
}
}
int CChildView::FindObject(CPoint point){
int nObj = -1; // if none object found, return -1
for(int i= m_Objects.size()-1; i>=0; i--){
if(m_Objects[i]->IsInside(point.x, point.y)){
nObj = i;
break;
}
}
return nObj;
}
. . .
4
Object-oriented programming Lecture №13
Modify the example from lecture 9 // ChildView.cpp Implementation of CChildView
. . .
void CChildView::OnLButtonDown(UINT nFlags, CPoint point){
m_nCatched =FindObject(point);
if(m_nCatched >=0 ){
m_MousePos = point;
SetCapture();
}
CWnd::OnLButtonDown(nFlags, point);
}
void CChildView::OnLButtonUp(UINT nFlags, CPoint point){
m_nCatched = -1;
ReleaseCapture();
CWnd::OnLButtonUp(nFlags, point);
}
. . .
5
Object-oriented programming Lecture №13
Modify the example from lecture 9 // ChildView.cpp Implementation of CChildView
. . .
void CChildView::OnMouseMove(UINT nFlags, CPoint point){
if(m_nCatched>=0){
CRect rect;
GetClientRect(&rect);
point.x = min(rect.right, max(rect.left, point.x));
point.y = min(rect.bottom, max(rect.top, point.y));
CPoint Delta = point - m_MousePos;
m_Objects[m_nCatched]->Move(Delta.x, Delta.y);
m_MousePos = point;
Invalidate();
}
CWnd::OnMouseMove(nFlags, point);
}
. . .
6
Object-oriented programming Lecture №13
Adding of a toolbar
7
You’ll need three steps to add a toolbar to your MFC application using Visual Studio:
1. Create the toolbar resource
2. Create the toolbar itself
3. Handle the toolbar commands
Object-oriented programming Lecture №13
Creating of the toolbar resource
• To create a new resource right click to a project *.rc file in the Resource explorer and pick “Add resource” from context menu.
8
Object-oriented programming Lecture №13
Creating of the toolbar resource
• Pick “Toolbar” and click “Create”.
9
Object-oriented programming Lecture №13
Creating of the toolbar resource
• The ID of the new toolbar is “IDR_TOOLBAR1”.
10
Object-oriented programming Lecture №13
Creating the toolbar resource
• Use “Oval” tool to draw a button picture.
11
Object-oriented programming Lecture №13
Creating of the toolbar resource
• Pick “properties” from the context menu to set the button ID.
12
Object-oriented programming Lecture №13
Creating of the toolbar resource
• Set the button id “ID_NEWCIRCLE” in the “properties” pane and click “Save all” .
13
Object-oriented programming Lecture №13
Creating of the toolbar resource
• Study the new ID’s automatically added to“resource.h” file
//Resource.h
//
#define IDD_ABOUTBOX 100
#define IDR_MAINFRAME 128
#define IDR_GraphAppTYPE 130
#define IDR_TOOLBAR1 310
#define ID_NEWCIRCLE 32771
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 312
#define _APS_NEXT_COMMAND_VALUE 32772
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 310
#endif
#endif
14
Object-oriented programming Lecture №13
Creating of the toolbar
• Create a member variable for the toolbar in CMainFrame class
// MainFrm.h : the interphase of CMainFrame
//
#pragma once
#include "ChildView.h"
class CMainFrame : public CFrameWnd
{
. . .
CChildView m_wndView;
CToolBar m_wndToolBar; // tollbar
. . .
};
15
Object-oriented programming Lecture №13
Creating of the toolbar • Create the toolbar in OnCreate member class
// MainFrm.cpp : implementation of CMainFrame
//
. . .
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// Creating of the ToolBar
m_wndToolBar.Create(this);
m_wndToolBar.LoadToolBar(IDR_TOOLBAR1);
// Creating of the View
if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL)) {
TRACE0("Failed to create the view\n");
return -1;
}
return 0;
}
16
Object-oriented programming Lecture №13
Creating of the toolbar
• After the modifications your program should look like this
17
Object-oriented programming Lecture №13
Handling the command
• Modify the CChildView to handle the “ID_NEWCIRCLE” command: 1. Add OnNewCircle member function declaration.
// ChildView.h : the interface of CChildView
//
. . .
class CChildView : public CWnd
{
. . .
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnNewCircle();
};
18
Object-oriented programming Lecture №13
Handling the command
• Modify the CChildView to handle the “ID_NEWCIRCLE” command: 2. Add OnNewCircle to the Message Map to bind it with “ID_NEWCIRCLE” command.
// ChildView.cpp the implementation of CChildView
. . .
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_COMMAND(ID_NEWCIRCLE, OnNewCircle)
END_MESSAGE_MAP()
. . .
19
Object-oriented programming Lecture №13
Handling the command
• Modify the CChildView to handle the “ID_NEWCIRCLE” command:
3. Add the OnNewCircle implementation. // ChildView.cpp the implementation of CChildView
. . .
void CChildView::OnNewCircle(){
CRect rect;
GetClientRect(&rect);
m_Objects.push_back(new CCircle(rand()%rect.Width(), rand()%rect.Height(), 10));
Invalidate();
}
. . .
20
Object-oriented programming Lecture №13
Handling the command
• Now your program will respond on clicking the toolbar button by creating a new circle.
21
Object-oriented programming Lecture №13
Create CGrpObject class // GrpObject.h : the interphase of CGrpObject
#pragma once
class CGrpObject
{
public:
CGrpObject(void){}
virtual void Draw(CDC &dc)=0;
virtual bool IsInside(double x, double y)=0;
virtual void Move(double dx, double dy){
m_dCenterX += dx;
m_dCenterY += dy;
}
virtual ~CGrpObject(void){}
protected:
double m_dCenterX;
double m_dCenterY;
};
22
Object-oriented programming Lecture №13
Inherit the CCircle from CGrpObject // Circle.h : the interphase of CCircle
#pragma once
#include "GrpObject.h"
class CCircle : public CGrpObject{
public:
CCircle(double x, double y, double R);
~CCircle(void);
public:
void Draw(CDC &dc);
bool IsInside(double x, double y);
//The Move(…) member function is now implemented in the base class
protected:
double m_dRadius;
//We don't need the m_dCentreX and m_dCentreY members now
//they are declared in the base class
};
23
Object-oriented programming Lecture №13
Modify the CChildView // ChildView.h : the interface of CChildView
#pragma once
#include "GrpObject.h"
#include <vector>
class CChildView : public CWnd
{
. . .
std::vector<CGrpObject *> m_Objects;
. . .
};
________________________________________________________________________________________
• Circle.h should be included to ChildView.cpp in order to create the CCircle
objects in OnNewCircle member function
// ChildView.cpp Implementation of CChildView
. . .
#include "Circle.h"
. . .
24
Object-oriented programming Lecture №13
New derived class
• Create a new class derived from
CGrpObject
//Square.h : the interphase of CSquare
#pragma once
#include "GrpObject.h"
class CSquare : public CGrpObject{
public:
CSquare(double x, double y, double a);
~CSquare(void);
public:
void Draw(CDC &dc);
bool IsInside(double x, double y);
protected:
double m_dA;
};
25
Object-oriented programming Lecture №13
New derived class //Square.cpp : the implementation of CSquare
#include "stdafx.h"
#include "Square.h"
#include <math.h>
CSquare::CSquare(double x, double y, double a){
m_dCenterX = x;
m_dCenterY = y;
m_dA = a;
}
CSquare::~CSquare(void){}
void CSquare::Draw(CDC &dc){
dc.FillSolidRect( m_dCenterX-m_dA*0.5, m_dCenterY-m_dA*0.5,
m_dA, m_dA, RGB(255,255,255));
dc.Draw3dRect(m_dCenterX-m_dA*0.5, m_dCenterY-m_dA*0.5, m_dA, m_dA, 0, 0);
}
bool CSquare::IsInside(double x, double y){
return fabs(x - m_dCenterX) <= m_dA*0.5 && fabs(y - m_dCenterY) <= m_dA*0.5;
}
26
Object-oriented programming Lecture №13
Creating “AddSquare” button
• Add a new button with to the toolbar as it was described in the slides 12-13.
• Rename the ID of the new button to “ID_NEWSQUARE”
• Implement the ID_NEWSQUARE command handler in the CChildView similar as it was shown in slides 18-20.
27
Object-oriented programming Lecture №13
Get rid of the flickering • How to get rid of the flickering during the object dragging?
– 1. Add WM_ERASEBKGND message holder // ChildView.h : the interface of CChildView . . . class CChildView : public CWnd{ . . . afx_msg BOOL OnEraseBkgnd(CDC* pDC); }; ___________________________________________________________________________ // ChildView.cpp Implementation of CChildView . . . BEGIN_MESSAGE_MAP(CChildView, CWnd) . . . ON_WM_ERASEBKGND() END_MESSAGE_MAP() . . . BOOL CChildView::OnEraseBkgnd(CDC* pDC) { //Don’t call base class implementation //return CWnd::OnEraseBkgnd(pDC); return true;//Just return true. }
– 2. Implement double buffering in OnPaint
28
Object-oriented programming Lecture №13
Double buffering when drawing
void CChildView::OnPaint()
{
CPaintDC dc(this); // device context for drawing
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
CRect rect;
GetClientRect(&rect);
CBitmap bmp;
bmp.CreateCompatibleBitmap(&dcMem, rect.Width(), rect.Height());
CBitmap *pOldBmp = dcMem.SelectObject(&bmp);
dcMem.FillSolidRect(0,0,rect.Width(), rect.Height(), 0xFFFFFF);
//0x FFFFFF is similar to RGB(255, 255, 255)
for(int i=0; i<m_Objects.size(); i++){
m_Objects[i]->Draw(dcMem);
}
dc.BitBlt(0,0, rect.Width(), rect.Height(), &dcMem, 0,0,SRCCOPY);
dcMem.SelectObject(pOldBmp);
}
29