好玩的Windows编程之"本地时间"(3) BigBen

来源:互联网 发布:手机如何查看淘宝等级 编辑:程序博客网 时间:2024/05/01 16:26

______________________________________

最近又有新的想法了,编一个有指针的钟,名字就叫BigBen.(下载页面)http://pan.baidu.com/s/1slBZAsX

原理很简单:首先要取得本地时间,然后把时间转化成钟的指针画上去,最后再把边沿剪切掉,就是一个桌面指针时钟了.

开工了!!!

_______________________________________

原理


时针走时角度是圆的十二等分,走一刻度的角度 alpha=360/12(角度)=PI/180*360/12(弧度)
秒和分针走时角度是圆的六十等分,走一刻度角度alpha=360/60(角度)=PI/180*360/60(弧度)

 
圆心的坐标pt0(m,n)和半径r是已知的,我们可以算出秒针的轨迹坐标pt(x,y)=(r*cos(sec*alpha)+m,r*sin(sec*alpha)+n)

把秒数代入公式得到pt(x,y)=(r*cos(sec*PI/180*360/60)+m,r*sin(sec*PI/180*360/60)+n),然后从圆心pt(m,n)画线到pt(x,y)就是秒针,或者分针了,慢着!什么地方错了.

由于时钟是以90度计为0秒,不是0度,所以要减去90度(即PI/2弧度),所以上面的公式修正为pt(x,y)=(r*cos(sec*PI/180*360/60-PI/2)+m,r*sin(sec*PI/180*360/60-PI/2)+n)=(r*cos(sec*PI/30-PI/2)+m,r*sin(sec*PI/30-PI/2)+n),这样还是有点错误,在C语言下,整数代入计算可能会因为求整,舍去小数而产生误差.于是再把公式改成这样子pt(x,y)=(r*cos(sec*PI/30.0-PI/2.0)+m,r*sin(sec*PI/30.0-PI/2.0)+n)

 

SYSTEMTIME  current_time;POINT pt0;POINT pt;GetLocalTime(&ct);pt.x=r*cos(ct.wSecond*PI/30.0-PI/2.0)+pt0.x;pt.y=r*sin(ct.wSecond*PI/30.0-PI/2.0)+pt0.yMoveToEx(hdc,pt0.x,pt0.y,NULL);LineTo(hdc,pt.x,pt.y);


 




 


同样的方法,我们可以得出分针,时针的公式,同样也容易算出刻度的坐标

 

                m_alpha_min=m_time.wMinute*PI/30.0-PI/2;                m_alpha_hour=m_time.wHour*PI/6.0-PI/2.0;                m_ptmin.x=m_rmin*cos(m_alpha_min)+m_pt0.x;                m_ptmin.y=m_rmin*sin(m_alpha_min)+m_pt0.y;                m_pthour.x=m_rhour*cos(m_alpha_hour)+m_pt0.x;                m_pthour.y=m_rhour*sin(m_alpha_hour)+m_pt0.y);


下图是出现BUG时的截图












这就是雏形,不过还有几点问题,数字电子表上,小时数是在分钟从59变00时,才加1,跳变的,如果直接画在表上,会产生什么呢,分针到了59秒时,时针突然从上一个刻度上跳变!!!有白天见鬼的感觉,而且容易让人产生错觉,所以时针计算公式还要改进.也就是分针行进过程,时针要缓缓前行,然后自然而然地随着分针到了59,00时,小时也到了下一个刻度.想想...想想--走60分钟,时针行进一刻度,也就是PI/180*(360/12)弧度,那走一分钟就是  +PI/180*(360/12)*((m_time.wMinute/60));这是就在原来时针走的角度上加上这个微小的角度.

 

m_alpha_hour=m_time.wHour*PI/6.0-PI/2.0+PI/360.0*m_time.wMinute;


有了这个想法,我想我们也可以改动秒针让它也,缓缓移动.一般情况下秒针一秒跳一次,或许你也见过平滑流动行走的秒针吧,那就要请出微秒

 

m_alpha_sec=(m_time.wSecond+( m_bsmooth ? m_time.wMilliseconds/1000.0 :0.0 ) )*PI/30.0-PI/2;//平滑秒针跳走second+m_time.wMilliseconds/1000.0

  

 半成品


然后有了罗马数字,并剪除了多余的正方形边框






最后用上汉字,完工



 

 

//BigBen.h//程序名:BigBen  //作者wisepragma  //主页:http://blog.csdn.net/wisepragma  #pragma once#include <cmath>//#define EDGE_LENGTH 600//#define FONT_WIDTH 14//#define FONT_HIGHT 14//#define EDGE_LENGTH 400//#define FONT_WIDTH 14//#define FONT_HIGHT 14#define EDGE_LENGTH 250#define FONT_WIDTH 5#define FONT_HIGHT 5//时钟的外观设定#define COLOR_HOUR  (RGB(224,63,196))#define COLOR_MINUTE (RGB(255,0,0))#define COLOR_SECOND (RGB(0,255,255)) #define COLOR_BACK (RGB(0,0,0))TCHAR *clktxt[]={TEXT("天"),TEXT("道"),TEXT("酬"),TEXT("勤"),TEXT("静"),TEXT("以"),TEXT("修"),TEXT("身"),TEXT("检"),TEXT("以"),TEXT("养"),TEXT("德")};//TCHAR *clktxt[12]={TEXT("XII"),TEXT("I"),TEXT("II"),TEXT("III"),TEXT("IV"),TEXT("V"),TEXT("VI"),TEXT("VII"),TEXT("VIII"),TEXT("IX"),TEXT("X"),TEXT("XI")};////TCHAR *clktxt[]={TEXT("待"),TEXT("我"),TEXT("君"),TEXT("临"),TEXT("天"),TEXT("下"),TEXT("许"),TEXT("你"),TEXT("四"),TEXT("海"),TEXT("为"),TEXT("家")};//////TCHAR *clktxt[]={TEXT("历"),TEXT("史"),TEXT("尘"),TEXT("封"),TEXT("了"),TEXT("锁"), TEXT("在"),TEXT("岁"),TEXT("月"),TEXT("的"),TEXT("橱"),TEXT("窗")}; //       //  TCHAR *clktxt[]={TEXT("12"),TEXT("1"),TEXT("2"),TEXT("3"),TEXT("4"),TEXT("5"),TEXT("6"),TEXT("7"),TEXT("8"),TEXT("9"),TEXT("10"),TEXT("11")}; class XPEN{private:        HPEN m_hpen,m_hpenold;        HDC m_hdc;public:         XPEN(HDC hdc,COLORREF clr,int width=1)        {                                m_hdc=hdc;                m_hpen=CreatePen(PS_SOLID,width,clr);                m_hpenold=static_cast<HPEN>(SelectObject(m_hdc,m_hpen));             }        void select(COLORREF clr,int width=1)        {                SelectObject(m_hdc,m_hpenold);                DeleteObject(m_hpen);                  m_hpen=CreatePen(PS_SOLID,width,clr);                m_hpenold=(HPEN)SelectObject(m_hdc,m_hpen);              }        ~XPEN()        {                SelectObject(m_hdc,m_hpenold);                DeleteObject(m_hpen);              }};class XBRUSH{private:        HBRUSH m_hbrush,m_hbrold;        HDC m_hdc;public:        XBRUSH(HDC hdc,int br)        {                                 m_hdc=hdc;                m_hbrush=static_cast<HBRUSH>(GetStockObject(br));//会自动填充白色画刷而覆盖其他色彩                 m_hbrold=static_cast<HBRUSH>(SelectObject(m_hdc,m_hbrush));        }        XBRUSH(HDC hdc,COLORREF clr)        {                m_hdc=hdc;                m_hbrush=static_cast<HBRUSH>(CreateSolidBrush(clr));//会自动填充白色画刷而覆盖其他色彩                 m_hbrold=static_cast<HBRUSH>(SelectObject(m_hdc,m_hbrush));        }        void select(COLORREF clr)        {                SelectObject(m_hdc,m_hbrold);                DeleteObject(m_hbrush);                  m_hbrush=CreateSolidBrush(clr);                m_hbrold=static_cast<HBRUSH>(SelectObject(m_hdc,m_hbrold));              }        HBRUSH get()        {                return m_hbrush;        }        ~XBRUSH()        {                SelectObject(m_hdc,m_hbrold);                DeleteObject(m_hbrush);              }};class XBigBen{private:        COLORREF m_clrHour,m_clrMinute,m_clrSecond,m_clrBack;           SYSTEMTIME  m_time;        unsigned int  m_r,m_rsec_tail,m_rhour,m_rmin,m_rsec;        POINT m_pt0,m_ptedge,m_ptsec,m_ptmin,m_pthour,m_ptsec_tail;        RECT    m_rc;        double m_alpha_sec,m_alpha_min,m_alpha_hour;        const double PI;        bool m_bsmooth;             TCHAR m_clktxt[12][15];public:             bool m_bAdjustWindow;        XBigBen(int x,int y,int r,                COLORREF clrh=RGB(224,63,196),                COLORREF clrm=RGB(255,0,0),                COLORREF clrs=RGB(0,255,255),                COLORREF clrbk=RGB(0,0,0))                :PI(3.1415)        {                m_clrHour=clrh;                 m_clrMinute=clrm;                m_clrSecond=clrs;                m_clrBack=clrbk;                m_r=r;                m_pt0.x=x;                m_pt0.y=y;                                   m_rc.left=m_pt0.x-m_r;                m_rc.top=m_pt0.y-m_r;                m_rc.right=m_pt0.x+m_r;                m_rc.bottom=m_pt0.y+m_r;                m_rsec_tail=m_r/4;                m_rsec=m_r*85/100;                m_rmin=m_r*80/100;                m_rhour=m_r*60/100;                m_bsmooth=true;                m_bAdjustWindow=true;                //TCHAR *str[12]={TEXT("XII"),TEXT("I"),TEXT("II"),TEXT("III"),TEXT("IV"),TEXT("V"),TEXT("VI"),TEXT("VII"),TEXT("VIII"),TEXT("IX"),TEXT("X"),TEXT("XI")};                //setclktext(str);        }        void setclktext(TCHAR *ptxt[12])        {                for(int i=0;i<12;i++)                {                        lstrcpy(m_clktxt[i],ptxt[i]);                }        }        void gettime()        {                GetLocalTime(&m_time);                //秒针,分针都是圆的六十等分(360/60),走一秒为n*6度,由于C函数用的参数变弧度,所以n*6再乘以转化率PSECOND/180=n*6*PI/180=n*PI/30=n*3.1415/30===n*360.0/60.0*3.1415/180,由于时钟是以90度计为0秒,不是0度,所以要减去90度(即PI/2)                //时针是圆的十二等分(360/12)===360.0/12*3.1415/180,分针行进过程中,时针缓缓地步进到下一个刻度                m_alpha_sec=(m_time.wSecond+( m_bsmooth ? m_time.wMilliseconds/1000.0 :0.0 ) )*PI/30.0-PI/2;//平滑秒针跳走second+m_time.wMilliseconds/1000.0               m_alpha_sec = (m_time.wSecond + (m_bsmooth ? m_time.wMilliseconds / 1000.0 : 0.0))*PI / 30.0 - PI / 2;//平滑秒针跳走second+m_time.wMilliseconds/1000.0         //分针走一分是圆的60分之一(360.0 / 60.0),这个角度换算成弧度*PI/180.0,由于时钟是以90度计为0秒,不是0度,所以要减去90度(即PI/2),后面加的是平滑走分的参数.秒的60次积累才达到一个弧度.        //m_alpha_min = m_time.wMinute*(360.0 / 60.0*(PI / 180.0)) - PI / 2 + 360.0 / 60.0*(PI / 180.0)*(m_time.wSecond / 60.0);//fixed:到00秒时分针突变          m_alpha_min = (360.0 / 60.0)*(PI / 180.0)* ((m_time.wSecond / 60.0) + m_time.wMinute) - PI / 2; //化简后                m_alpha_hour=m_time.wHour*PI/6.0-PI/2.0+PI/360.0*m_time.wMinute;//分针行进过程中,时针缓缓地步进到下一个刻度,而不像数字表那样瞬间跳变,一定要用浮点数代入计算,否则将被求整而产生错误m_alpha_hour=m_time.wHour*PI/6-PI/2+PI/180*(360/12)*((m_time.wMinute/60));                m_ptsec.x=static_cast<long>(m_rsec*cos(m_alpha_sec)+m_pt0.x);                m_ptsec.y=static_cast<long>(m_rsec*sin(m_alpha_sec)+m_pt0.y);                m_ptsec_tail.x=static_cast<long>(m_rsec_tail*cos(m_alpha_sec+PI)+m_pt0.x);                m_ptsec_tail.y=static_cast<long>(m_rsec_tail*sin(m_alpha_sec+PI)+m_pt0.y);//当拷贝粘贴时错误也一并拷贝                m_ptedge.x=static_cast<long>(m_r*cos(m_alpha_sec)+m_pt0.x);                m_ptedge.y=static_cast<long>(m_r*sin(m_alpha_sec)+m_pt0.y);                m_ptmin.x=static_cast<long>(m_rmin*cos(m_alpha_min)+m_pt0.x);                m_ptmin.y=static_cast<long>(m_rmin*sin(m_alpha_min)+m_pt0.y);                m_pthour.x=static_cast<long>(m_rhour*cos(m_alpha_hour)+m_pt0.x);                m_pthour.y=static_cast<long>(m_rhour*sin(m_alpha_hour)+m_pt0.y);           }        void drawcircle(HDC hdc,POINT pt,int r,COLORREF clr,int width=1)//pt为圆心,半径为r,以clr色彩画圆        {                XPEN hpen(hdc,clr,width);                XBRUSH hbr(hdc,HOLLOW_BRUSH);  //若不设定为(HOLLOW_BRUSH);会自动填充白色画刷而覆盖其他色彩                RECT rc0;                rc0.left=pt.x-r;                rc0.top=pt.y-r;                rc0.right=pt.x+r;                rc0.bottom=pt.y+r;                Ellipse(hdc,rc0.left,rc0.top,rc0.right,rc0.bottom );//指针的中心圆点        }        void show(HWND hwnd,HDC hdc)        {                RECT rcwnd;  //client rect                GetClientRect(hwnd,&rcwnd);                 HDC hmem=CreateCompatibleDC(hdc);//使用缓冲BitBlt方式避免闪烁                 HBITMAP hbmp=CreateCompatibleBitmap(hdc,rcwnd.right-rcwnd.left,rcwnd.bottom-rcwnd.top);//RIGHT-LEFT NO LEFT-RIGHT,一出错全是白的                SelectObject(hmem,hbmp);                XBRUSH brBack(hmem,m_clrBack);                FillRect(hmem,&rcwnd,brBack.get());//背景着色                gettime();//取得时间,并计算各时钟指针的坐标                drawface(hmem);      //表盘刻度 和文字                         drawhour(hmem);  //画时针                drawminute(hmem);//画分针                drawsecond(hmem);  //画秒针                drawcircle(hmem,m_pt0,4,RGB(0,0,255),2);                BitBlt(hdc,0,0,rcwnd.right-rcwnd.left,rcwnd.bottom-rcwnd.top,hmem,0,0,SRCCOPY  );// SRCCOPY刷新//SRCAND重叠                 DeleteObject(hbmp);                DeleteDC(hmem);                int t=6;                HRGN hrgn=  CreateEllipticRgn (m_rc.left-t+3,m_rc.top-t+2,m_rc.right+t,m_rc.bottom+t);                 SetWindowRgn(hwnd,hrgn,TRUE);//把窗口切成圆的        }        void line(HDC hdc,POINT pt1,POINT pt2)        {                MoveToEx(hdc,pt1.x,pt1.y,NULL);                LineTo(hdc,pt2.x,pt2.y);        }               void drawhour(HDC hdc)        {                XPEN hpen(hdc,m_clrHour,4);                line(hdc,m_pt0,m_pthour);        }        void drawminute(HDC hdc)        {                XPEN hpen(hdc,m_clrMinute,3);                line(hdc,m_pt0,m_ptmin);        }        void drawsecond(HDC hdc)        {                              XPEN hpen(hdc,m_clrSecond,2);                SetPixel(hdc,m_ptedge.x,m_ptedge.y,RGB(255,0,0));                line(hdc,m_pt0,m_ptsec);                //hpen.select(RGB(146,250,43),2);//秒针的尾巴色彩                line(hdc,m_pt0,m_ptsec_tail);        }        void drawface(HDC hdc)        {                       for(int i=0;i<60;i++)//绘制分钟,秒钟的刻度                {                        double beta=i*PI/30.0-PI/2.0;                         POINT ptedge;//圆框的点的位置                        ptedge.x=static_cast<long>(m_r*cos(beta)+m_pt0.x);                        ptedge.y=static_cast<long>(m_r*sin(beta)+m_pt0.y);                        POINT ptit;//时刻度的点的位置                        ptit.x=static_cast<long>((m_rsec*1.1)*cos(beta)+m_pt0.x);                        ptit.y=static_cast<long>((m_rsec*1.1)*sin(beta)+m_pt0.y);                        XPEN hpen(hdc,RGB(159,34,241),2);                        line(hdc,ptit,ptedge);                        if(i%5==0)                        {                                XPEN hpen(hdc,RGB(51,140,183),3);//绘制时钟刻度的位置                                ptit.x=static_cast<long>((m_rsec+1.0)*cos(beta)+m_pt0.x);                                ptit.y=static_cast<long>((m_rsec+1.0)*sin(beta)+m_pt0.y);                                POINT ptit_num;//时间的数值的位置                                ptit_num.x=static_cast<long>((m_rsec-15.0)*cos(beta)+m_pt0.x);//数值为微调位置                                ptit_num.y=static_cast<long>((m_rsec-9.0)*sin(beta)+m_pt0.y);                                line(hdc,ptit,ptedge);                                TEXTMETRIC tm;                                LOGFONT lf={0};                                GetTextMetrics(hdc,&tm);                                 lstrcpy(lf.lfFaceName,TEXT("Lucida"));                                lf.lfHeight= tm.tmHeight+FONT_HIGHT;                                lf.lfWidth=tm.tmAveCharWidth+FONT_WIDTH ;                                HFONT hfont=CreateFontIndirect(&lf);                                HGDIOBJ hdcOld=SelectObject(hdc,hfont);                                SIZE sz;                                GetTextExtentPoint32(hdc,m_clktxt[i/5],lstrlen(m_clktxt[i/5]),&sz);                                SetBkMode(hdc,TRANSPARENT);//使文字背景透明                                SetTextColor(hdc,RGB(190,177,27));                                TextOut(hdc,ptit_num.x-sz.cx/2,ptit_num.y-sz.cy/2,m_clktxt[i/5],lstrlen(m_clktxt[i/5]));                                SelectObject(hdc,hdcOld);//还原否则字体会不断变大                                DeleteObject(hfont);                        }                }                              XBRUSH hbr(hdc,HOLLOW_BRUSH);                 drawcircle(hdc,m_pt0,m_r,RGB(191,138,28),3);        }};


// BigBen.cpp //程序名:BigBen  //作者wisepragma  //主页:http://blog.csdn.net/wisepragma  #include "stdafx.h"#include "BigBen.h"#include <cmath>#pragma comment(lib,"user32.lib")#pragma comment(lib,"gdi32.lib")XBigBen BigBen(EDGE_LENGTH/2,EDGE_LENGTH/2,(EDGE_LENGTH-10)/2,COLOR_HOUR,COLOR_MINUTE,COLOR_SECOND, COLOR_BACK );//________________________________________________________________TCHAR szTitle[ ]=TEXT("BigBen");        // 标题栏文本TCHAR szWindowClass[ ]=TEXT("BigCls"); // 主窗口类名ATOM    MyRegisterClass(HINSTANCE hInstance);BOOL    InitInstance(HINSTANCE, int);LRESULT CALLBACKWndProc(HWND, UINT, WPARAM, LPARAM); int APIENTRY _tWinMain(HINSTANCE hInstance,                     HINSTANCE hPrevInstance,                     LPTSTR    lpCmdLine,                     int       nCmdShow){UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine); MSG msg;  MyRegisterClass(hInstance);// 执行应用程序初始化:if (!InitInstance (hInstance, nCmdShow)){return FALSE;}// 主消息循环:while (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);                DispatchMessage(&msg);}return (int) msg.wParam;} ATOM MyRegisterClass(HINSTANCE hInstance){WNDCLASSEX wcex;wcex.cbSize = sizeof(WNDCLASSEX);wcex.style              = CS_HREDRAW | CS_VREDRAW;wcex.lpfnWndProc= WndProc;wcex.cbClsExtra= 0;wcex.cbWndExtra= 0;wcex.hInstance= hInstance;wcex.hIcon= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_QUESTION));wcex.hCursor= LoadCursor(NULL, IDC_ARROW);wcex.hbrBackground= static_cast<HBRUSH>(0);//(WHITE_BRUSH);(COLOR_WINDOW+1);//有色的背景某此情下会造成闪烁wcex.lpszMenuName=NULL;// MAKEINTRESOURCE(IDC_BigBen);wcex.lpszClassName= szWindowClass;wcex.hIconSm= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_QUESTION));return RegisterClassEx(&wcex);}  BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){        HWND hWnd =CreateWindowEx(WS_EX_TOPMOST|WS_EX_TOOLWINDOW,                        szWindowClass,szTitle,WS_POPUPWINDOW,                        CW_USEDEFAULT,CW_USEDEFAULT,EDGE_LENGTH,EDGE_LENGTH,                        NULL,NULL,hInstance,NULL);        if (!hWnd)  return FALSE;        ShowWindow(hWnd, nCmdShow);        UpdateWindow(hWnd);        return TRUE;}LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ PAINTSTRUCT ps;HDC hdc; switch (message){        case WM_LBUTTONDOWN:                RECT rcWnd;                       GetWindowRect(hWnd,&rcWnd);                SendMessage(hWnd,WM_NCLBUTTONDOWN,HTCAPTION,lParam);                GetWindowRect(hWnd,&rcWnd);                  if(rcWnd.top<0) MoveWindow(hWnd,rcWnd.left,0,EDGE_LENGTH,EDGE_LENGTH,TRUE);//WIN7下窗口超出顶端会变形,所以要调整                break;         case WM_KEYDOWN:               if(wParam==VK_ESCAPE)PostQuitMessage(0);                break; case WM_PAINT:                {                          hdc = BeginPaint(hWnd, &ps);                        BigBen.show(hWnd,hdc);          EndPaint(hWnd, &ps);                }break;case WM_DESTROY:PostQuitMessage(0);break;        case WM_CREATE:                BigBen.setclktext(clktxt);                SetTimer(hWnd,0,100,NULL);                if(BigBen.m_bAdjustWindow)                {                        RECT rectDesktop;                        SystemParametersInfo(SPI_GETWORKAREA,0,&rectDesktop,0);                        MoveWindow( hWnd, GetSystemMetrics(SM_CXFULLSCREEN)-EDGE_LENGTH,//微调                                rectDesktop.bottom-EDGE_LENGTH,//rectDesktop.bottom是系统状态栏最高处的纵坐标                                EDGE_LENGTH,                                EDGE_LENGTH,                                TRUE);                        BigBen.m_bAdjustWindow=false;                }                break;        case WM_TIMER:                InvalidateRect(hWnd,NULL,TRUE);                break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;} 

 

最新版本加入这张背景图片IMAGE.BMP

 

//resource.h的内容#define IDI_IMAGE   180
//BigBen.rc的内容//编译方式:RC /v BigBen.rc//显示:Writing BITMAP:180,     lang:0x804,     size 313240.#include "resource.h"IDI_IMAGE               BITMAP                  "image.bmp"
//BigBen.h<pre name="code" class="cpp">//更新版本:1.1//程序名:BigBen  //作者wisepragma //主页:http://blog.csdn.net/wisepragma#pragma once#include "resource.h"#include <cmath>//#define EDGE_LENGTH 600//#define FONT_WIDTH 14//#define FONT_HIGHT 14////#define EDGE_LENGTH 400//#define FONT_WIDTH 11//#define FONT_HIGHT 11#define EDGE_LENGTH 250#define FONT_WIDTH 5#define FONT_HIGHT 5//#define EDGE_LENGTH 150//#define FONT_WIDTH 1//#define FONT_HIGHT 1//时钟的外观设定;#define COLOR_HOUR  (RGB(255,30,155))//2014.3.24 add (RGB(224,63,196))#define COLOR_MINUTE RGB(230,20,228)//(RGB(0,49,255))//(RGB(255,0,0))#define COLOR_SECOND (RGB(0,255,255)) #define COLOR_BACK (RGB(0,0,0))#define COLOR_TEXT RGB(0,17,255)//(0)//RGB(162,120,9)RGB(0,200,128));//字体色彩RGB(190,177,27)RGB(142,36,162)RGB(94,36,126)//TCHAR *clktxt[]={TEXT("天"),TEXT("道"),TEXT("酬"),TEXT("勤"),TEXT("静"),TEXT("以"),TEXT("修"),TEXT("身"),TEXT("检"),TEXT("以"),TEXT("养"),TEXT("德")};TCHAR *clktxt[12]={TEXT("XII"),TEXT("I"),TEXT("II"),TEXT("III"),TEXT("IV"),TEXT("V"),TEXT("VI"),TEXT("VII"),TEXT("VIII"),TEXT("IX"),TEXT("X"),TEXT("XI")};////TCHAR *clktxt[]={TEXT("待"),TEXT("我"),TEXT("君"),TEXT("临"),TEXT("天"),TEXT("下"),TEXT("许"),TEXT("你"),TEXT("四"),TEXT("海"),TEXT("为"),TEXT("家")};//////TCHAR *clktxt[]={TEXT("历"),TEXT("史"),TEXT("尘"),TEXT("封"),TEXT("了"),TEXT("锁"), TEXT("在"),TEXT("岁"),TEXT("月"),TEXT("的"),TEXT("橱"),TEXT("窗")}; //       //  TCHAR *clktxt[]={TEXT("12"),TEXT("1"),TEXT("2"),TEXT("3"),TEXT("4"),TEXT("5"),TEXT("6"),TEXT("7"),TEXT("8"),TEXT("9"),TEXT("10"),TEXT("11")};class XPEN{private:        HPEN m_hpen,m_hpenold;        HDC m_hdc;public:         XPEN(HDC hdc,COLORREF clr,int width=1)        {                                m_hdc=hdc;                m_hpen=CreatePen(PS_SOLID,width,clr);                m_hpenold=static_cast<HPEN>(SelectObject(m_hdc,m_hpen));             }        void select(COLORREF clr,int width=1)        {                SelectObject(m_hdc,m_hpenold);                DeleteObject(m_hpen);                  m_hpen=CreatePen(PS_SOLID,width,clr);                m_hpenold=(HPEN)SelectObject(m_hdc,m_hpen);              }        ~XPEN()        {                SelectObject(m_hdc,m_hpenold);                DeleteObject(m_hpen);              }};class XBRUSH{private:        HBRUSH m_hbrush,m_hbrold;        HDC m_hdc;public:        XBRUSH(HDC hdc,int br)        {                                 m_hdc=hdc;                m_hbrush=static_cast<HBRUSH>(GetStockObject(br));//会自动填充白色画刷而覆盖其他色彩                 m_hbrold=static_cast<HBRUSH>(SelectObject(m_hdc,m_hbrush));        }        XBRUSH(HDC hdc,COLORREF clr)        {                m_hdc=hdc;                m_hbrush=static_cast<HBRUSH>(CreateSolidBrush(clr));//会自动填充白色画刷而覆盖其他色彩                 m_hbrold=static_cast<HBRUSH>(SelectObject(m_hdc,m_hbrush));        }        void select(COLORREF clr)        {                SelectObject(m_hdc,m_hbrold);                DeleteObject(m_hbrush);                  m_hbrush=CreateSolidBrush(clr);m_hbrold = static_cast<HBRUSH>(SelectObject(m_hdc, m_hbrush));        }        HBRUSH get()        {                return m_hbrush;        }        ~XBRUSH()        {                SelectObject(m_hdc,m_hbrold);                DeleteObject(m_hbrush);              }};class XBigBen{private:        COLORREF m_clrHour,m_clrMinute,m_clrSecond,m_clrBack;           SYSTEMTIME  m_time;        unsigned int  m_r,m_rsec_tail,m_rhour,m_rmin,m_rsec;        POINT m_pt0,m_ptedge,m_ptsec,m_ptmin,m_pthour,m_ptsec_tail;        RECT    m_rc;        double m_alpha_sec,m_alpha_min,m_alpha_hour;        const double PI;        bool m_bsmooth;             TCHAR m_clktxt[12][15];public:             bool m_bAdjustWindow;        XBigBen(int x,int y,int r,                COLORREF clrh=RGB(224,63,196),                COLORREF clrm=RGB(255,0,0),                COLORREF clrs=RGB(0,255,255),                COLORREF clrbk=RGB(0,0,0))                :PI(3.1415)        {                m_clrHour=clrh;                 m_clrMinute=clrm;                m_clrSecond=clrs;                m_clrBack=clrbk;                m_r=r;                m_pt0.x=x;                m_pt0.y=y;                                   m_rc.left=m_pt0.x-m_r;                m_rc.top=m_pt0.y-m_r;                m_rc.right=m_pt0.x+m_r;                m_rc.bottom=m_pt0.y+m_r;                m_rsec_tail=m_r/4;                m_rsec=m_r*85/100;                m_rmin=m_r*80/100;                m_rhour=m_r*60/100;                m_bsmooth=true;                m_bAdjustWindow=true;                //TCHAR *str[12]={TEXT("XII"),TEXT("I"),TEXT("II"),TEXT("III"),TEXT("IV"),TEXT("V"),TEXT("VI"),TEXT("VII"),TEXT("VIII"),TEXT("IX"),TEXT("X"),TEXT("XI")};                //setclktext(str);        }        void setclktext(TCHAR *ptxt[12])        {                for(int i=0;i<12;i++)                {                        lstrcpy(m_clktxt[i],ptxt[i]);                }        }        void gettime()        {                GetLocalTime(&m_time);                //秒针,分针都是圆的六十等分(360/60),走一秒为n*6度,由于C函数用的参数变弧度,所以n*6再乘以转化率PSECOND/180=n*6*PI/180=n*PI/30=n*3.1415/30===n*360.0/60.0*3.1415/180,由于时钟是以90度计为0秒,不是0度,所以要减去90度(即PI/2)                //时针是圆的十二等分(360/12)===360.0/12*3.1415/180,分针行进过程中,时针缓缓地步进到下一个刻度m_alpha_sec = (m_time.wSecond + (m_bsmooth ? m_time.wMilliseconds / 1000.0 : 0.0))*PI / 30.0 - PI / 2;//平滑秒针跳走second+m_time.wMilliseconds/1000.0//分针走一分是圆的60分之一(360.0 / 60.0),这个角度换算成弧度*PI/180.0,由于时钟是以90度计为0秒,不是0度,所以要减去90度(即PI/2),后面加的是平滑走分的参数.秒的60次积累才达到一个弧度.//m_alpha_min = m_time.wMinute*(360.0 / 60.0*(PI / 180.0)) - PI / 2 + 360.0 / 60.0*(PI / 180.0)*(m_time.wSecond / 60.0);//fixed:到00秒时分针突变m_alpha_min = (360.0 / 60.0)*(PI / 180.0)* ((m_time.wSecond / 60.0) + m_time.wMinute) - PI / 2; //fixed:到00秒时分针突变m_alpha_hour = m_time.wHour*PI / 6.0 - PI / 2.0 + PI / 360.0*m_time.wMinute;//分针行进过程中,时针缓缓地步进到下一个刻度,而不像数字表那样瞬间跳变,一定要用浮点数代入计算,否则将被求整而产生错误:m_alpha_hour=m_time.wHour*PI/6-PI/2+PI/180*(360/12)*((m_time.wMinute/60));                m_ptsec.x=static_cast<long>(m_rsec*cos(m_alpha_sec)+m_pt0.x);                m_ptsec.y=static_cast<long>(m_rsec*sin(m_alpha_sec)+m_pt0.y);                m_ptsec_tail.x=static_cast<long>(m_rsec_tail*cos(m_alpha_sec+PI)+m_pt0.x);                m_ptsec_tail.y=static_cast<long>(m_rsec_tail*sin(m_alpha_sec+PI)+m_pt0.y);//当拷贝粘贴时错误也一并拷贝                m_ptedge.x=static_cast<long>(m_r*cos(m_alpha_sec)+m_pt0.x);                m_ptedge.y=static_cast<long>(m_r*sin(m_alpha_sec)+m_pt0.y);                m_ptmin.x=static_cast<long>(m_rmin*cos(m_alpha_min)+m_pt0.x);                m_ptmin.y=static_cast<long>(m_rmin*sin(m_alpha_min)+m_pt0.y);                m_pthour.x=static_cast<long>(m_rhour*cos(m_alpha_hour)+m_pt0.x);                m_pthour.y=static_cast<long>(m_rhour*sin(m_alpha_hour)+m_pt0.y);           }        void drawcircle(HDC hdc,POINT pt,int r,COLORREF clr,int width=1)//pt为圆心,半径为r,以clr色彩画圆        {                XPEN hpen(hdc,clr,width);                XBRUSH hbr(hdc,HOLLOW_BRUSH);  //若不设定为(HOLLOW_BRUSH);会自动填充白色画刷而覆盖其他色彩                RECT rc0;                rc0.left=pt.x-r;                rc0.top=pt.y-r;                rc0.right=pt.x+r;                rc0.bottom=pt.y+r;                Ellipse(hdc,rc0.left,rc0.top,rc0.right,rc0.bottom );//指针的中心圆点        }        void show(HWND hwnd,HDC hdc)        {                RECT rcwnd;  //client rect                GetClientRect(hwnd,&rcwnd);                 HDC hmem=CreateCompatibleDC(hdc);//使用缓冲BitBlt方式避免闪烁                 HBITMAP hbmp=CreateCompatibleBitmap(hdc,rcwnd.right-rcwnd.left,rcwnd.bottom-rcwnd.top);//RIGHT-LEFT NO LEFT-RIGHT,一出错全是白的                SelectObject(hmem,hbmp);                XBRUSH brBack(hmem,m_clrBack);                FillRect(hmem,&rcwnd,brBack.get());//背景着色                HANDLE hbitmp=LoadImage(   GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_IMAGE),                        IMAGE_BITMAP ,  EDGE_LENGTH , EDGE_LENGTH ,                        LR_LOADTRANSPARENT                         );                SelectObject(hmem,hbitmp);                gettime();//取得时间,并计算各时钟指针的坐标                drawface(hmem);      //表盘刻度 和文字                         drawhour(hmem);  //画时针                drawminute(hmem);//画分针                drawsecond(hmem);  //画秒针                drawcircle(hmem,m_pt0,4,RGB(0,0,255),2);                BitBlt(hdc,0,0,rcwnd.right-rcwnd.left,rcwnd.bottom-rcwnd.top,hmem,0,0,SRCCOPY  );// SRCCOPY刷新//SRCAND重叠                 DeleteObject(hbitmp);                DeleteObject(hbmp);                DeleteDC(hmem);                int t=6;                HRGN hrgn=  CreateEllipticRgn (m_rc.left-t+4,m_rc.top-t+4,m_rc.right+t-2,m_rc.bottom+t-2);//change2014.3.24                 SetWindowRgn(hwnd,hrgn,TRUE);//把窗口切成圆的        }        void line(HDC hdc,POINT pt1,POINT pt2)        {                MoveToEx(hdc,pt1.x,pt1.y,NULL);                LineTo(hdc,pt2.x,pt2.y);        }               void drawhour(HDC hdc)        {                XPEN hpen(hdc,m_clrHour,4);                line(hdc,m_pt0,m_pthour);        }        void drawminute(HDC hdc)        {                XPEN hpen(hdc,m_clrMinute,3);                line(hdc,m_pt0,m_ptmin);        }        void drawsecond(HDC hdc)        {                              XPEN hpen(hdc,m_clrSecond,2);                SetPixel(hdc,m_ptedge.x,m_ptedge.y,RGB(255,0,0));                line(hdc,m_pt0,m_ptsec);                //hpen.select(RGB(146,250,43),2);//秒针的尾巴色彩                line(hdc,m_pt0,m_ptsec_tail);        }        void drawface(HDC hdc)        {                       for(int i=0;i<60;i++)//绘制分钟,秒钟的刻度                {                        double beta=i*PI/30.0-PI/2.0;                         POINT ptedge;//圆框的点的位置                        ptedge.x=static_cast<long>(m_r*cos(beta)+m_pt0.x);                        ptedge.y=static_cast<long>(m_r*sin(beta)+m_pt0.y);                        POINT ptit;//时刻度的点的位置                        ptit.x=static_cast<long>((m_rsec*1.1)*cos(beta)+m_pt0.x);                        ptit.y=static_cast<long>((m_rsec*1.1)*sin(beta)+m_pt0.y);                        XPEN hpen(hdc,RGB(159,34,241),2);                        line(hdc,ptit,ptedge);                        if(i%5==0)                        {                                XPEN hpen(hdc,RGB(51,140,183),3);//绘制时钟刻度的位置                                ptit.x=static_cast<long>((m_rsec+1.0)*cos(beta)+m_pt0.x);                                ptit.y=static_cast<long>((m_rsec+1.0)*sin(beta)+m_pt0.y);                                POINT ptit_num;//时间的数值的位置                                ptit_num.x=static_cast<long>((m_rsec-10.0)*cos(beta)+m_pt0.x);//数值为微调位置change2014.3.24                                ptit_num.y=static_cast<long>((m_rsec-9.0)*sin(beta)+m_pt0.y);                                line(hdc,ptit,ptedge);                                TEXTMETRIC tm;                                LOGFONT lf={0};                                GetTextMetrics(hdc,&tm);                                 lstrcpy(lf.lfFaceName,TEXT("Lucida"));                                lf.lfHeight= tm.tmHeight+FONT_HIGHT;                                lf.lfWidth=tm.tmAveCharWidth+FONT_WIDTH ;                                HFONT hfont=CreateFontIndirect(&lf);                                HGDIOBJ hdcOld=SelectObject(hdc,hfont);                                SIZE sz;                                GetTextExtentPoint32(hdc,m_clktxt[i/5],lstrlen(m_clktxt[i/5]),&sz);                                SetBkMode(hdc,TRANSPARENT);//使文字背景透明                                SetTextColor(hdc,COLOR_TEXT);//字体色彩RGB(190,177,27)RGB(142,36,162)RGB(94,36,126)                                TextOut(hdc,ptit_num.x-sz.cx/2,ptit_num.y-sz.cy/2,m_clktxt[i/5],lstrlen(m_clktxt[i/5]));                                SelectObject(hdc,hdcOld);//还原否则字体会不断变大                                DeleteObject(hfont);                        }                }                              XBRUSH hbr(hdc,HOLLOW_BRUSH);                 drawcircle(hdc,m_pt0,m_r,RGB(191,138,28),3);        }};



最新版的图




 

0 0
原创粉丝点击