C++輔導(dǎo):實(shí)現(xiàn)數(shù)字鐘的另一種方法

字號(hào):

前不久在VCKBASE網(wǎng)上看到一篇關(guān)于數(shù)字電子鐘的程序,下來以后用了以后感覺很不錯(cuò),做的相當(dāng)漂亮。閑暇琢磨之余,發(fā)現(xiàn)了另外一種實(shí)現(xiàn)數(shù)字鐘的方法,雖然效果沒有前面那位同志好,但本著學(xué)習(xí)的態(tài)度我把我的想法發(fā)布一下。希望對(duì)大家有借鑒意義。
    前面那位作者用的方法是在靜態(tài)控件之上繪制數(shù)字,然后根據(jù)不同的數(shù)字在不同的區(qū)域上顯示不同的顏色。這樣作的難點(diǎn)在于如何精確計(jì)算不同的數(shù)字所對(duì)應(yīng)的坐標(biāo)和區(qū)域,而且一旦靜態(tài)控件的大小比例不協(xié)調(diào),所顯示的數(shù)字有很大的變形。我的思路是用靜態(tài)控件組成不同的數(shù)字,然后在顯示數(shù)值時(shí)用不同的顏色填充數(shù)字以顯示不同的數(shù)字。
    最終效果圖如下:
    
    具體實(shí)現(xiàn)如下:
    1.頁面設(shè)計(jì)
    把靜態(tài)文本控件按數(shù)字顯示格式排列,一個(gè)排列好的數(shù)字如圖a所示。為了使控件的ID連續(xù)以方便函數(shù)處理,所設(shè)置顯示每一個(gè)數(shù)字的控件ID是連續(xù)的,這樣就可于用前一個(gè)控件的ID加減一個(gè)整數(shù)來得到下一個(gè)控件的ID.如圖所示控件的ID順序和控件所顯示的數(shù)字一致。為了使界面更美觀,給做好的控件加一個(gè)背景矩形控件,每次矩形所顯示的顏色和控件的顏色不同,這樣就可以給人一種動(dòng)態(tài)逼真的感覺。
    
    
    2.在工程中加入一個(gè)類CyColor,用于繪制靜態(tài)文本控件的顏色。相應(yīng)的成員函數(shù)和成員變量如下:
    PaintStatic用來為繪制靜態(tài)文本控件顏色,CWnd *dlg是控件的指針,在調(diào)用時(shí)用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],用于存儲(chǔ)顏色,我給它賦予10中個(gè)人比較喜愛的顏色;
    3.在CClockDlg中加入MyColor型的成員變量mc,用于繪制靜態(tài)控件的顏色
    4.對(duì)顯示數(shù)值進(jìn)行編碼,具體函數(shù)如下:
    void CClockDlg::DrawHour(int n)//顯示小時(shí)
    {
    //首先小時(shí)進(jìn)行分解十位和各位
    int a=n/10;//十位
    int b=n%10;//個(gè)位
    DrawNumber(IDC_STATIC1,a);//畫十位
    DrawNumber(IDC_STATIC8,a);//畫個(gè)位
    }
    void CClockDlg::DrawMinute(int m)//顯示分鐘
    {
    //首先分鐘進(jìn)行分解十位和各位
    int a=m/10;//十位
    int b=m%10;//個(gè)位
    DrawNumber(IDC_STATIC15,a);//畫十位
    DrawNumber(IDC_STATIC22,a);//畫個(gè)位
    }
    void CClockDlg::DrawSecond(int s)//顯示秒
    {
    //首先秒進(jìn)行分解十位和各位
    int a=s/10;//十位
    int b=s%10;//個(gè)位
    DrawNumber(IDC_STATIC29,a);//畫十位
    DrawNumber(IDC_STATIC36,a);//畫個(gè)位
    }
    void CClockDlg::DrawDot()//畫點(diǎn)
    {
    COLORREF C;
    if(n%2==0)
    C=mc.c[2];
    else
    C=mc.c[7];//n為奇數(shù)或偶數(shù)時(shí),顯示不同顏色,以產(chǎn)生閃動(dòng)
    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)函數(shù)的輸入變量是控件的起始ID和所顯示的數(shù)字,用途//////顯示一個(gè)數(shù)字
    if(n==0)
    {
    int dx[6]={1,2,3,5,6,7};//數(shù)值0所對(duì)應(yīng)的靜態(tài)控件序號(hào),
    for(int j=0;j<6;j++)
    mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環(huán)繪制
    }
    if(n==1)
    {
    int dx[2]={2,5};//數(shù)值1所對(duì)應(yīng)的靜態(tài)控件序號(hào),
    for(int j=0;j<2;j++)
    mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環(huán)繪制
    }
    if(n==2)
    {
    int dx[6]={1,3,4,5,6};//數(shù)值2所對(duì)應(yīng)的靜態(tài)控件序號(hào),
    for(int j=0;j<5;j++)
    mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環(huán)繪制
    }
    if(n==3)
    {
    int dx[5]={1,3,4,6,7};//數(shù)值3所對(duì)應(yīng)的靜態(tài)控件序號(hào),
    for(int j=0;j<5;j++)
    mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環(huán)繪制
    }
    if(n==4)
    {
    int dx[4]={2,3,4,7};//數(shù)值4所對(duì)應(yīng)的靜態(tài)控件序號(hào),
    for(int j=0;j<4;j++)
    mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環(huán)繪制
    }
    if(n==5)
    {
    int dx[6]={1,2,4,6,7};//數(shù)值5所對(duì)應(yīng)的靜態(tài)控件序號(hào),
    for(int j=0;j<6;j++)
    mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環(huán)繪制
    }
    if(n==6)
    {
    int dx[6]={1,2,4,5,6,7};//數(shù)值6所對(duì)應(yīng)的靜態(tài)控件序號(hào),
    for(int j=0;j<6;j++)
    mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環(huán)繪制
    }
    if(n==7)
    {
    int dx[3]={1,3,7};//數(shù)值7所對(duì)應(yīng)的靜態(tài)控件序號(hào),
    for(int j=0;j<3;j++)
    mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環(huán)繪制
    }
    if(n==8)
    {
    int dx[7]={1,2,3,4,5,6,7};//數(shù)值8所對(duì)應(yīng)的靜態(tài)控件序號(hào),
    for(int j=0;j<7;j++)
    mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環(huán)繪制
    }
    if(n==9)
    {
    int dx[6]={1,2,3,4,6,7};//數(shù)值9所對(duì)應(yīng)的靜態(tài)控件序號(hào),
    for(int j=0;j<6;j++)
    mc.PaintStatic(GetDlgItem(nID+dx[j]-1),mc.c[4],""); //用循環(huán)繪制
    }
    }上述所介紹的方法,實(shí)現(xiàn)起來簡(jiǎn)單,經(jīng)過簡(jiǎn)單的拓展可以用于其它方面如界面數(shù)字的顯示等