MFC CPen

I wirte a simple paint project, and the CPen usage puzzles me.

CElement is the base class, I derived CLine, CRectangle, CRect..., overwirtes the Draw(CDC* pDC) function.

if I add a private data member [quote]CPen aPen;
in the base class, then I use the in the Draw, like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void CRectangle::Draw(CDC* pDC)

{

    if(!aPen.CreatePen(PS_SOLID, m_PenWidth, m_Color))

     {

      AfxMessageBox(TEXT("Creating pen failed"), MB_ICONERROR);

      AfxAbort();

     }
  // ...drawing stuff
}


the program can run, but when I use Rectangle to draw something, it will pop up a Debug Assertion Failed window.

but if I don't add
CPen aPen
in the base class, I use like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
void CRectangle::Draw(CDC* pDC)

{
    Cpen aPen;   // create in the function
    if(!aPen.CreatePen(PS_SOLID, m_PenWidth, m_Color))

     {

      // abort stuff

     }
   // ...drawing stuff
}



[/quote]


I'm wonder why? I have to put the CreatePen in the constructor?


plus, I want to know how to implement the program have select pen and brush style function, can you give me some tip about how to do it?
I have a element.h, element.cpp store the shape, and a elementconstant.h store the COLORREF and some variable stuff.
// this is the function name of my CLine class, the style thing stucks me, I don't know how to handle it.
1
2
virtual void Draw(CDC* pDC);  
CLine(const CPoint& first, const CPoint& end, COLORREF penColor, COLORREF, brushColor);
Last edited on
have you got the actual code.
(if it is too long to post here then drop it on some code pasting site and give us the link(s) ).
hi,
guestgulkan
, I upload my code to the
https://hotfile.com/dl/188002848/2b7772c/Sketcher.rar.html
, hope you can see it and give me some advice.
Last edited on
I've downloaded it and will look at it later today -
but I'm sure it will come down to the usual resource management issue - in that

You cannot repeatly call CreatePen on the same CPen object without first
detaching the previous pen .


But that we mean:
1
2
3
4
CPen somePen;
somePen.CreatePen( /*example blue pen*/);
//do something with the blue pen
somePen.CreatePen(/*say red pen*/); //error somePen is still associated with blue pen 


I'm sure that was the problem when you had the Cpen as part of the CElement classs.
You were probably calling the Draw function (for example for a CLine) which was repeatedly calling CreatePen on the Cpen object in the CElement base class.
The crash doesn't happen when you put a Cpen in the Draw function, because each time the Draw function is called, a new Cpen is created ecah time.

**why is this thread in the Linux forum ??*

EDIT:
You a two choices really:

Choice 1:
Continue the way you have it now - which is creating the pen in the Draw function.

Choice 2
If you want a pen as part of the class - then make a CPen member variable part of the CElement class - create the pen as part of the constructor of the subclasses - and in the Draw function just use the pen (no need to create another pen).
Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class CElement : public CObject
{
protected:
	int m_PenWidth;
	COLORREF m_Color;
	CRect m_EnclosingRect;
	
	CPen m_ThePen; //<<===================
public:
	virtual ~CElement() {};

	virtual void Draw(CDC* pDC) {};

	CRect GetBoundRect()const;
protected:			// make it accessible for inheritance
	CElement() {} ;
};


Now using the CLine derived class as an example:

//Constructor
1
2
3
4
5
6
7
8
9
10
11
CLine::CLine(const CPoint& first, const CPoint& end, COLORREF aColor)
	: m_startPoint(first), m_endPoint(end)
{
	m_PenWidth = 1;
	m_Color = aColor;
	
	m_ThePen.CreatePen(PS_SOLID, m_PenWidth, m_Color); //<<=============
	
	m_EnclosingRect = CRect(first, end);
	m_EnclosingRect.NormalizeRect();
}


and in the Draw function
1
2
3
4
5
6
7
8
9
void CLine::Draw(CDC* pDC)
{
	CPen* pOldPen = pDC->SelectObject(&m_ThePen); //<<============
	
	pDC->MoveTo(m_startPoint);
	pDC->LineTo(m_endPoint);

	pDC->SelectObject(pOldPen);
}

Last edited on
thanks a lot,
guestgulkan
, It's my fault and I don't know why to put this in the linux forum(maybe my eye blinded that time?).

you helped a lot!

Topic archived. No new replies allowed.