跟江川一起學習製作用於警報功能的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,加上設定閃爍效果,我們就可以看到效果了
展開