前不久在VCKBASE網上看到一篇關於數字電子鐘的程序,下來以後用了以後感覺很不錯,做的相當漂亮。閒暇琢磨之余,發現了另外一種實現數字鐘的方法,雖然效果沒有前面那位同志好,但本著學習的態度我把我的想法發布一下。希望對大家有借鑒意義。
前面那位作者用的方法是在靜態控件之上繪制數字,然後根據不同的數字在不同的區域上顯示不同的顏色。這樣作的難點在於如何精確計算不同的數字所對應的坐標和區域,而且一旦靜態控件的大小比例不協調,所顯示的數字有很大的變形。我的思路是用靜態控件組成不同的數字,然後在顯示數值時用不同的顏色填充數字以顯示不同的數字。
最終效果圖如下:
具體實現如下:
1.頁面設計
把靜態文本控件按數字顯示格式排列,一個排列好的數字如圖a所示。為了使控件的ID連續以方便函數處理,所設置顯示每一個數字的控件ID是連續的,這樣就可於用前一個控件的ID加減一個整數來得到下一個控件的ID.如圖所示控件的ID順序和控件所顯示的數字一致。為了使界面更美觀,給做好的控件加一個背景矩形控件,每次矩形所顯示的顏色和控件的顏色不同,這樣就可以給人一種動態逼真的感覺。
2.在工程中加入一個類CyColor,用於繪制靜態文本控件的顏色。相應的成員函數和成員變量如下:
PaintStatic用來為繪制靜態文本控件顏色,CWnd *dlg是控件的指針,在調用時用GetDlgItem(ID)獲得指針。COLORREF cr是所選的顏色,CString str是需要顯示的文字。
void MyColor::PaintStatic(CWnd *dlg,COLORREF cr,CString str)
{
CClientDC dc(dlg);
CRect rect;
dlg->GetClientRect(&rect);
CPen pen(PS_SOLID,1,RGB(50,0,10+100));
dc.SelectObject(&pen);
CBrush pBrush(cr);
dc.SelectObject(&pBrush);
dc.Rectangle(rect);
dc.SetBkMode(TRANSPARENT);
dc.TextOut(rect.left+10,rect.top+5,str);
}
COLORREF成員變量c[10],用於存儲顏色,我給它賦予10中個人比較喜愛的顏色;
2.在CClockDlg中加入MyColor型的成員變量mc,用於繪制靜態控件的顏色
3.對顯示數值進行編碼,具體函數如下:
void CClockDlg::DrawHour(int n)//顯示小時
{
//首先小時進行分解十位和各位
int a=n/10;//十位
int b=n%10;//個位
DrawNumber(IDC_STATIC1,a);//畫十位
DrawNumber(IDC_STATIC8,a);//畫個位
}
void CClockDlg::DrawMinute(int m)//顯示分鐘
{
//首先分鐘進行分解十位和各位
int a=m/10;//十位
int b=m%10;//個位
DrawNumber(IDC_STATIC15,a);//畫十位
DrawNumber(IDC_STATIC22,a);//畫個位
}
void CClockDlg::DrawSecond(int s)//顯示秒
{
//首先秒進行分解十位和各位
int a=s/10;//十位
int b=s%10;//個位
DrawNumber(IDC_STATIC29,a);//畫十位
DrawNumber(IDC_STATIC36,a);//畫個位
}
void CClockDlg::DrawDot()//畫點
{
COLORREF C;
if(n%2==0)
C=mc.c[2];
else
C=mc.c[7];//n為奇數或偶數時,顯示不同顏色,以產生閃動
mc.PaintStatic(GetDlgItem(IDC_STATIC43),C,"");
mc.PaintStatic(GetDlgItem(IDC_STATIC44),C,"");
mc.PaintStatic(GetDlgItem(IDC_STATIC45),C,"");
mc.PaintStatic(GetDlgItem(IDC_STATIC46),C,"");
}
void CClockDlg::DrawNumber(UINT nID,int n)
{
// DrawNumber(UINT nID,int n)函數的輸入變量是控件的起始ID和所顯示的數字,用途//////顯示一個數字
if(n==0)
{
int dx[6]={1,2,3,5,6,7};//數值0所對應的靜態控件序號,
for(int j=0;j<6;j++)
mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環繪制
}
if(n==1)
{
int dx[2]={2,5};//數值1所對應的靜態控件序號,
for(int j=0;j<2;j++)
mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環繪制
}
if(n==2)
{
int dx[6]={1,3,4,5,6};//數值2所對應的靜態控件序號,
for(int j=0;j<5;j++)
mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環繪制
}
if(n==3)
{
int dx[5]={1,3,4,6,7};//數值3所對應的靜態控件序號,
for(int j=0;j<5;j++)
mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環繪制
}
if(n==4)
{
int dx[4]={2,3,4,7};//數值4所對應的靜態控件序號,
for(int j=0;j<4;j++)
mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環繪制
}
if(n==5)
{
int dx[6]={1,2,4,6,7};//數值5所對應的靜態控件序號,
for(int j=0;j<6;j++)
mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環繪制
}
if(n==6)
{
int dx[6]={1,2,4,5,6,7};//數值6所對應的靜態控件序號,
for(int j=0;j<6;j++)
mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環繪制
}
if(n==7)
{
int dx[3]={1,3,7};//數值7所對應的靜態控件序號,
for(int j=0;j<3;j++)
mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環繪制
}
if(n==8)
{
int dx[7]={1,2,3,4,5,6,7};//數值8所對應的靜態控件序號,
for(int j=0;j<7;j++)
mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環繪制
}
if(n==9)
{
int dx[6]={1,2,3,4,6,7};//數值9所對應的靜態控件序號,
for(int j=0;j<6;j++)
mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環繪制
}
}
上述所介紹的方法,實現起來簡單,經過簡單的拓展可以用於其它方面如界面數字的顯示等。
本文配套源碼