跟江川一起学习制作用于报警功能的STATIC类 作者 戚高
介绍
报警控制在各种工业控制系统中是经常见到的,一般用于报警的方法有很多,有用文本标示,有用图形表示的,其原理不外乎构造CDC类对象然后利用提供的各种基本图元属性进行图形绘制就可以了.这里我们来制作一个能够显示报警文本,当出现某个报警的时候我们然背景进行闪烁就可以实现功能了.
正文
一般进行此类处理的方法我们常用派生的方法去实现.
首先利用VC向导建立一个基于对话框的工程.
然后在对话框界面上我们放置一个STATIC控件,并设置好位置.
为我们的STATIC控件派生一个命名为CStaticRectangle的基于CStatic的类
基本准备工作完成了,我们下一步的任务就是相新派生类里面添加内容达到我们预想的报警的画面的效果.
根据我上一遍文章所叙,采用双缓冲的方法,我们要将MemDC.h,AutoFont.h,AutoFont.cpp三个文件加入工程.AutoFont 类是现在网络上面的关于CFont类的比较好的封装,使用者在创建CFont对象时不用考虑复杂的创建API函数,只需要进行几个简单的参数设置就可以完成功能,所以我们这里用这个类来实现报警文本的字体控制.
定义对象
//颜色的定义各位可以根据实际情况进行增减
#define COLOR_RED RGB(255,0,0)
#define COLOR_GREEN RGB(0,255,0)
protected:
CBitmap *m_pBitmapOldBackground ;//这三个用于双缓冲绘制
CBitmap m_bitmapBackground ;
CDC m_dcBackground;
CRect m_rectCtrl; // 控件区域
short nMillSec; //定时器
CAutoFont *m_pFnt; //构造报警文本字体
public:
COLORREF m_BkColor;//背景颜色
COLORREF m_TextColor;//文字颜色
CString strText;//显示的报警文本
BOOL bGleam;//是否闪烁
在构造函数里面进行变量的初始化:
CStaticRectangle::CStaticRectangle()
{
m_BkColor = COLOR_RED;
m_TextColor = RGB(255,128,64);
nMillSec = 10;
bGleam = FALSE;
m_pFnt = new CAutoFont("隶书");
m_pFnt->SetHeight(28);
m_pFnt->SetWidth(12);
m_pFnt->SetBold(TRUE);
}
析构函数里面进行内存的释放
CStaticRectangle::~CStaticRectangle()
{
if(m_pFnt)
delete m_pFnt;
}
要进行STATIC报警功能的绘制,我们只需要映射WM_PAINT消息,然后进行界面的重新绘制和文本的显示就可以了
void CStaticRectangle::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// 获得控件区域
GetClientRect (&m_rectCtrl);
CMemDC memDC(&dc, &m_rectCtrl);
if(m_dcBackground.GetSafeHdc()== NULL|| (m_bitmapBackground.m_hObject == NULL))
{
m_dcBackground.CreateCompatibleDC(&dc);
m_bitmapBackground.CreateCompatibleBitmap(&dc, m_rectCtrl.Width(), m_rectCtrl.Height()) ;
m_pBitmapOldBackground = m_dcBackground.SelectObject(&m_bitmapBackground) ;
}
DrawRectangleBackground(&m_dcBackground, m_rectCtrl);
memDC.BitBlt(0, 0, m_rectCtrl.Width(), m_rectCtrl.Height(),
&m_dcBackground, 0, 0, SRCCOPY) ;
// Do not call CStatic::OnPaint() for painting messages
}
下面时控制相关的信息显示,这里要注意的是我们的文本的显示,这里要计算文本显示的位置.
我们可以通过pDC->GetTextExtent();获得文本的CSize,然后利用控件的rect就可以得到文本的显示位置了.
这里采用的是居中显示的方法.
void CStaticRectangle::DrawRectangleBackground(CDC *pDC, CRect &rect)
{
CBrush brushFill, *pBrushOld;
int nXSize,nYSize;
CSize szText;
CFont *fOldFont;
nXSize = rect.Width();
nYSize = rect.Height();
brushFill.DeleteObject();
brushFill.CreateSolidBrush(m_BkColor);
pBrushOld = pDC->SelectObject(&brushFill);
pDC->Rectangle(rect);
pDC->SetBkColor(m_BkColor);
pDC->SetTextColor(m_TextColor);
fOldFont = (CFont *)pDC->SelectObject(m_pFnt);
szText = pDC->GetTextExtent(strText);
nXSize = (nXSize - szText.cx)/2;
nYSize = (nYSize - szText.cy)/2;
pDC->TextOut(nXSize,nYSize,strText);
pDC->SelectObject(pBrushOld);
pDC->SelectObject(&fOldFont);
brushFill.DeleteObject();
}
如果要实现报警功能,我们就要利用定时器的功能进行定时的背景颜色的更换然后刷新显示.
到此基本工作已经完成了,下面要做的是提供一个用户可以动态修改的接口.
void CStaticRectangle::SetRectangleText(CString strVal)
{
this->strText = strVal;
}
void CStaticRectangle::SetBackColor(UINT nStyle)//设置背景颜色
{
this->m_BkColor = nStyle;
}
void CStaticRectangle::SetBkGleam(BOOL bShow)
{
if(this->bGleam)
{
if(!bShow)
KillTimer(nMillSec);
}
else
{
if(bShow)
SetTimer(nMillSec,750,NULL);
}
this->bGleam = bShow;
}
好现在我们的功能类已经完成,下面要做的是和界面上的CSTATIC联系起来.
通过CLASSWIZARD建立STATIC控件关联变量(Control类型),然后将派生类型修改成我们的CStaticRectangle,加上设置闪烁效果,我们就可以看到效果了
展开