昨天写了个简单的自绘按钮,使用的几个模式如下:
Factory Method , Abstract Factory , Strategy , Decorator部分代码如下:
//DataInterface.h#ifndef _DATAINTERFACE_H_
#define _DATAINTERFACE_H_/*------------------------------- 说明 ------------------------------
* 功能:简单演示几个模式的使用。该文件中使用的模式有:Strategy Pattern
Factory Method Pattern, Abstract Factory, Decorator Pattern
* 作者:吴龙为,吉首大学,2002-6-18
* 版本:2.0
* 版权所有(c), 可以随便修改和使用,但请将修改后的文件发一份到邮箱:
[email protected] * 修改:该版是2.0版,修改了其中的一个模式.1.0版在实现CSharp类是使用
的是Strategy Pattern,为了支持平面按钮和支持更透明的操作,2.0
版改用了Decorator Pattern,另外还增加了Abstract Factory Pattern * 注意:因为目的只是演示和学习,所以实现都比较简单,也没有很详细的优
化,而且模式的选择可能也不是最好。大家如果有兴趣可以尝试改动
和增加更多的模式,当然,写好后,请别忘了也给我一份学习学习
*------------------------------------------------------------------*/
namespace face
{
/*---------------------该类是一个数据基类---------------------------*/
class CDataBase
{
public:
CDataBase();
virtual ~CDataBase();
public:
virtual void DrawMouseIn(CDC *pDC);
virtual void DrawMouseOut(CDC *pDC);
virtual void DrawNormal(CDC *pDC) = 0;
virtual void DrawFocus(CDC *pDC) = 0;
virtual void DrawDown(CDC *pDC) = 0;
virtual void DrawUp(CDC *pDC) = 0;
public:
void SetBkColor(COLORREF, COLORREF clrBkF = -1, COLORREF clrBkS = -1);
void SetRect(const CRect &rc);
const CRect & GetRect() const;
public:
//CSharp 类要取用该类成员
COLORREF m_clrBkN, m_clrBkF, m_clrBkS;
CRect m_rcBk;
};
//文本数据类
class CTextData: public CDataBase
{
public:
CTextData();
virtual ~CTextData();
public:
virtual void DrawNormal(CDC *pDC);
virtual void DrawFocus(CDC *pDC);
virtual void DrawDown(CDC *pDC);
virtual void DrawUp(CDC *pDC);
public:
void SetTextColor(COLORREF, COLORREF clrTextF = -1, COLORREF clrTextS = -1);
void SetText(CString &szText);
protected:
void InternalDrawText(CDC *pDC, CRect &rc, COLORREF clrText);
protected:
COLORREF m_clrTextN, m_clrTextF,m_clrTextS;
CString m_szText;
};
Factory Method , Abstract Factory , Strategy , Decorator部分代码如下:
//DataInterface.h#ifndef _DATAINTERFACE_H_
#define _DATAINTERFACE_H_/*------------------------------- 说明 ------------------------------
* 功能:简单演示几个模式的使用。该文件中使用的模式有:Strategy Pattern
Factory Method Pattern, Abstract Factory, Decorator Pattern
* 作者:吴龙为,吉首大学,2002-6-18
* 版本:2.0
* 版权所有(c), 可以随便修改和使用,但请将修改后的文件发一份到邮箱:
[email protected] * 修改:该版是2.0版,修改了其中的一个模式.1.0版在实现CSharp类是使用
的是Strategy Pattern,为了支持平面按钮和支持更透明的操作,2.0
版改用了Decorator Pattern,另外还增加了Abstract Factory Pattern * 注意:因为目的只是演示和学习,所以实现都比较简单,也没有很详细的优
化,而且模式的选择可能也不是最好。大家如果有兴趣可以尝试改动
和增加更多的模式,当然,写好后,请别忘了也给我一份学习学习
*------------------------------------------------------------------*/
namespace face
{
/*---------------------该类是一个数据基类---------------------------*/
class CDataBase
{
public:
CDataBase();
virtual ~CDataBase();
public:
virtual void DrawMouseIn(CDC *pDC);
virtual void DrawMouseOut(CDC *pDC);
virtual void DrawNormal(CDC *pDC) = 0;
virtual void DrawFocus(CDC *pDC) = 0;
virtual void DrawDown(CDC *pDC) = 0;
virtual void DrawUp(CDC *pDC) = 0;
public:
void SetBkColor(COLORREF, COLORREF clrBkF = -1, COLORREF clrBkS = -1);
void SetRect(const CRect &rc);
const CRect & GetRect() const;
public:
//CSharp 类要取用该类成员
COLORREF m_clrBkN, m_clrBkF, m_clrBkS;
CRect m_rcBk;
};
//文本数据类
class CTextData: public CDataBase
{
public:
CTextData();
virtual ~CTextData();
public:
virtual void DrawNormal(CDC *pDC);
virtual void DrawFocus(CDC *pDC);
virtual void DrawDown(CDC *pDC);
virtual void DrawUp(CDC *pDC);
public:
void SetTextColor(COLORREF, COLORREF clrTextF = -1, COLORREF clrTextS = -1);
void SetText(CString &szText);
protected:
void InternalDrawText(CDC *pDC, CRect &rc, COLORREF clrText);
protected:
COLORREF m_clrTextN, m_clrTextF,m_clrTextS;
CString m_szText;
};
/*----------------图象的生成类,这是一个Factory Method ---------*/
class CImageMgr;
class CImageMaker
{
public:
//Make Bitmap
CImageMgr *MakeBitmapImage(UINT idBitmap,COLORREF clrTransparent = -1, bool bStretch = false);
CImageMgr *MakeBitmapImage(LPCTSTR szBitmap,COLORREF clrTransparent = -1, bool bStretch = false); //Make Icon
CImageMgr *MakeIconImage(UINT idIcon);
CImageMgr *MakeIconImage(LPCTSTR szIcon);
};
//-------------------------------------------------------------- class CImageData: public CTextData
{
public:
CImageData();
virtual ~CImageData();
public:
//设置图象和文本位置的函数
void SetImageLeft();
void SetImageRight();
void SetImageDown();
void SetImageOnly();
//设置图片
void SetImage(CImageMgr *pImageNormal, CImageMgr *pImageFocus = NULL, CImageMgr *pImageSelected =NULL);
public:
virtual void DrawNormal(CDC *pDC);
virtual void DrawFocus(CDC *pDC);
virtual void DrawDown(CDC *pDC);
virtual void DrawUp(CDC *pDC);
private:
//内部绘制函数
void InternalDrawImage(CDC *pDC,COLORREF &clrText, CImageMgr *pImage);
//文本和图象绘制区域的初始化函数
void InternalInitRect();
private:
CImageMgr *m_pImageMgrN; //Strategy(策略) pattern
CImageMgr *m_pImageMgrF;
CImageMgr *m_pImageMgrS;
private:
CRect m_rcImage; //图象绘制的矩形区域
CRect m_rcText; //文本绘制的矩形区域
private:
bool m_bInitRect; //是否已经初始化了绘制区域
enum enumImageSize { IMAGE_LEFT, IMAGE_RIGHT,
IMAGE_DOWN, IMAGE_ONLY };
enumImageSize m_eImageSize; //图象的绘制范围变量
};
//--------------------------------------------------------------------
/*---------------图象的管理类,这是一个Strategy(策略)模式-----------*/
class CImageMgr
{
public:
virtual ~CImageMgr();
public:
virtual void DrawImage(CDC *pDC, const CRect &rc) = 0;
virtual const CSize & GetImageSize() const;
protected:
CSize m_imageSize;
};
class CImageBitmap : public CImageMgr
{
public:
CImageBitmap(UINT idBitmap,COLORREF clrTransparent = -1, bool bStretch=false);
CImageBitmap(LPCTSTR szBitmap, COLORREF clrTransparent = -1, bool bStretch=false);
virtual ~CImageBitmap();
public:
virtual void DrawImage(CDC *pDC, const CRect &rc);
void SetStretch(bool bStretch);
void SetTransparentColor(const COLORREF clrTransparent);
private:
CBitmap m_imageBitmap;
COLORREF m_clrTransparent;
bool m_bStretch;
};
class CImageIcon : public CImageMgr
{
public:
CImageIcon(UINT idIcon);
CImageIcon(LPCTSTR szIcon);
virtual ~CImageIcon();
public:
virtual void DrawImage(CDC *pDC, const CRect &rc);
private:
HICON m_hIcon;
};
//-------------------------------------------------------------------
/*----------------CSharp类,管理形状,是一个Decorator模式--------*/
class CSharp : public CDataBase
{
public:
CSharp(CDataBase *pDataBase , int nBorderWidth = 2);
virtual ~CSharp();
public:
//CDataBase functions
virtual void DrawMouseIn(CDC *pDC);
virtual void DrawMouseOut(CDC *pDC);
virtual void DrawNormal(CDC *pDC);
virtual void DrawFocus(CDC *pDC);
virtual void DrawDown(CDC *pDC);
virtual void DrawUp(CDC *pDC);
public:
void SetBorderWidth(int nBorderWidth);
void SetFlat(bool bFlat);
private:
virtual void FillSharp(CDC *pDC,COLORREF clrFill) = 0;
virtual void DrawBorder(CDC *pDC, bool bDown) = 0;
virtual void DrawFlat(CDC *pDC,COLORREF &clrPen) = 0;
protected:
CDataBase *m_pDataBase; //Decorator Pattern
int m_nBorderWidth;
bool m_bFlat; //if the sharp 3D or Flat
};
class CRectangle : public CSharp
{
public:
CRectangle(CDataBase *pDataBase, int nBorderWidth = 2);
virtual ~CRectangle();
private:
virtual void FillSharp(CDC *pDC,COLORREF clrFill);
virtual void DrawBorder(CDC *pDC, bool bDown);
virtual void DrawFlat(CDC *pDC, COLORREF &clrPen);
};
class CEllipse : public CSharp
{
public:
CEllipse(CDataBase *pDataBase, int nBorderWidth = 2);
virtual ~CEllipse();
private:
virtual void FillSharp(CDC *pDC,COLORREF clrFill);
virtual void DrawBorder(CDC *pDC,bool bDown);
virtual void DrawFlat(CDC *pDC, COLORREF &clrPen);
}; /*------------------Abstract Factory Pattern -------------------
* 优点:使得产品组合透明和一致
* 缺点:带来许多小的类
*-------------------------------------------------------------*/
class CButtonFactory
{
public:
//Make Sharp
virtual CSharp * MakeSharp(CDataBase *pDataBase, int nBorderWidth = 2) = 0;
public:
//Make data
virtual CDataBase * MakeData() = 0;
};
class CRectangleTextFactory : public CButtonFactory
{
public:
virtual CSharp * MakeSharp(CDataBase *pDataBase, int nBorderWidth = 2);
virtual CDataBase *MakeData();
};
class CRectangleImageFactory : public CButtonFactory
{
public:
virtual CSharp * MakeSharp(CDataBase *pDataBase, int nBorderWidth = 2);
virtual CDataBase *MakeData();
};
class CEllipseImageFactory : public CButtonFactory
{
public:
virtual CSharp *MakeSharp (CDataBase *pDataBase , int nBorderWidth = 2);
virtual CDataBase *MakeData ();
};
class CEllipseTextFactory : public CButtonFactory
{
public:
virtual CSharp *MakeSharp (CDataBase *pDataBase, int nBorderWidth =2);
virtual CDataBase *MakeData();
};
}#endif//_DATAINTERFACE_H_
{
//----------------------CDataBase class ---------------------------
CDataBase::CDataBase()
{
m_clrBkN = m_clrBkF = m_clrBkS = ::GetSysColor(COLOR_BTNFACE);
m_rcBk.SetRectEmpty();
}
CDataBase::~CDataBase ()
{} void CDataBase:<img src="images/smilies/biggrin.gif" border="0" alt="">rawMouseIn (CDC *pDC)
{
DrawFocus(pDC);
}
void CDataBase:<img src="images/smilies/biggrin.gif" border="0" alt="">rawMouseOut (CDC *pDC)
{
DrawNormal(pDC);
} void CDataBase::SetBkColor (COLORREF clrBkN, COLORREF clrBkF, COLORREF clrBkS)
{
m_clrBkN = clrBkN; if(m_clrBkF != -1)
m_clrBkF = clrBkF;
else
m_clrBkF = m_clrBkN;
if(m_clrBkS != -1)
m_clrBkS = clrBkS;
else
m_clrBkS = m_clrBkN;
}
void CDataBase::SetRect (const CRect &rc)
{
m_rcBk.CopyRect (&rc);
}
const CRect & CDataBase::GetRect() const
{
return m_rcBk;
} //---------------------CTextData class --------------------------
CTextData::CTextData()
{
m_clrTextN = m_clrTextF = m_clrTextS = ::GetSysColor(COLOR_BTNTEXT);
m_szText = _T("");
}
CTextData::~CTextData()
{} void CTextData::SetText (CString &szText)
{
m_szText = szText;
}
void CTextData::SetTextColor (COLORREF clrTextN, COLORREF clrTextF, COLORREF clrTextS)
{
m_clrTextN = clrTextN;
if(clrTextF != -1)
m_clrTextF = clrTextF;
else
m_clrTextF = m_clrTextN;
if(clrTextS != -1)
m_clrTextS = clrTextS;
else
m_clrTextS = m_clrTextN;
} inline void CTextData::InternalDrawText (CDC *pDC , CRect &rc, COLORREF clrText)
{
pDC->SetTextColor (clrText);
pDC->SetBkMode (TRANSPARENT);
pDC->DrawText (m_szText, rc, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
} inline void CTextData:<img src="images/smilies/biggrin.gif" border="0" alt="">rawNormal (CDC *pDC)
{
InternalDrawText(pDC, m_rcBk, m_clrTextN);
}
inline void CTextData:<img src="images/smilies/biggrin.gif" border="0" alt="">rawFocus (CDC *pDC)
{
InternalDrawText(pDC, m_rcBk, m_clrTextF); //draw the test, if has
}
inline void CTextData:<img src="images/smilies/biggrin.gif" border="0" alt="">rawDown (CDC *pDC)
{
InternalDrawText(pDC, m_rcBk, m_clrTextS);
}
inline void CTextData:<img src="images/smilies/biggrin.gif" border="0" alt="">rawUp (CDC *pDC)
{
InternalDrawText(pDC, m_rcBk, m_clrTextF);
}
CImageData::CImageData()
:m_bInitRect(false),m_eImageSize(IMAGE_LEFT)
{
m_pImageMgrN = m_pImageMgrF = m_pImageMgrS = NULL;
} CImageData::~CImageData ()
{
if(m_pImageMgrN)
delete m_pImageMgrN;
if(m_pImageMgrF)
delete m_pImageMgrF;
if(m_pImageMgrS)
delete m_pImageMgrS;
} void CImageData::SetImageLeft ()
{
m_eImageSize = IMAGE_LEFT;
}
void CImageData::SetImageRight ()
{
m_eImageSize = IMAGE_RIGHT;
}
void CImageData::SetImageDown ()
{
m_eImageSize = IMAGE_DOWN;
}
void CImageData::SetImageOnly ()
{
m_eImageSize = IMAGE_ONLY;
} //设置图象和文本的绘制区域
void CImageData::InternalInitRect()
{
m_bInitRect = true; //置区域初始化标志位为真
switch(m_eImageSize)
{
case IMAGE_LEFT:
{
//set the image and text rectangle
m_rcImage.SetRect (m_rcBk.left , m_rcBk.top , m_rcBk.left + m_rcBk.Width ()/2,
m_rcBk.bottom );
const CSize &size = m_pImageMgrN->GetImageSize ();
//center the image
m_rcImage.DeflateRect ( (m_rcImage.Width () - size.cx ) /2,
(m_rcImage.Height () - size.cy )/2 );
m_rcText.SetRect (m_rcImage.right, m_rcBk.top , m_rcBk.right ,
m_rcBk.bottom );
}
break;
case IMAGE_RIGHT:
{
m_rcImage.SetRect (m_rcBk.left + m_rcBk.Width ()/2, m_rcBk.top , m_rcBk.right ,
m_rcBk.bottom );
const CSize &size = m_pImageMgrN->GetImageSize ();
m_rcImage.DeflateRect ( (m_rcImage.Width () - size.cx ) /2,
(m_rcImage.Height () - size.cy )/2 );
m_rcText.SetRect (m_rcBk.left , m_rcBk.top , m_rcImage.left ,
m_rcBk.bottom );
}
break;
case IMAGE_DOWN:
{
m_rcImage.CopyRect (&m_rcBk);
const CSize &size = m_pImageMgrN->GetImageSize ();
m_rcImage.DeflateRect ( (m_rcImage.Width () - size.cx ) /2,
(m_rcImage.Height () - size.cy )/2 );
m_rcText.CopyRect (&m_rcBk);
}
break;
case IMAGE_ONLY:
{
m_rcImage.CopyRect (&m_rcBk);
const CSize &size = m_pImageMgrN->GetImageSize ();
m_rcImage.DeflateRect ( (m_rcImage.Width () - size.cx ) /2,
(m_rcImage.Height () - size.cy )/2 );
m_rcText.SetRectEmpty ();
}
break;
default:
break;
}
}
inline void CImageData:<img src="images/smilies/biggrin.gif" border="0" alt="">rawNormal (CDC *pDC)
{
InternalDrawImage(pDC,m_clrTextN, m_pImageMgrN);
}
inline void CImageData:<img src="images/smilies/biggrin.gif" border="0" alt="">rawFocus (CDC *pDC)
{
InternalDrawImage(pDC, m_clrTextF, m_pImageMgrF);
}
inline void CImageData:<img src="images/smilies/biggrin.gif" border="0" alt="">rawDown (CDC *pDC)
{
InternalDrawImage(pDC, m_clrTextS, m_pImageMgrS);
}
inline void CImageData:<img src="images/smilies/biggrin.gif" border="0" alt="">rawUp (CDC *pDC)
{
InternalDrawImage(pDC,m_clrTextF, m_pImageMgrF);
} void CImageData::InternalDrawImage(CDC *pDC, COLORREF &clrText, CImageMgr *pImage)
{
if(!m_bInitRect)
InternalInitRect(); if(pImage)
pImage->DrawImage (pDC, m_rcImage); //draw image
else
m_pImageMgrN->DrawImage (pDC, m_rcImage); if( !m_rcText.IsRectEmpty ())
InternalDrawText(pDC, m_rcText, clrText); //draw text
} void CImageData::SetImage (CImageMgr *pImageNormal, CImageMgr *pImageFocus, CImageMgr *pImageSelected)
{
m_pImageMgrN = pImageNormal;
m_pImageMgrF = pImageFocus;
m_pImageMgrS = pImageSelected;
}