win32数字时钟

来源:互联网 发布:mysql 导出表命令 编辑:程序博客网 时间:2024/04/27 17:57

首先看下程序吧
这里写图片描述
一个数字时钟,如何实现呢?
首先,这样的数字可以分为7个部分
111111
2 3
2 3
444444
5 6
5 6
777777
这样,可以定义一个二维数组,如果对应的位置存在,就令其为1,比如数字3:
#######
#
#
#######
#
#
#######
应该为{1,0,1,1,0,1,1};

//用于画数字时判断各个部分是否画出的二维数组

static BOOL fSevenSegment[10][7] = {//10个数字,每个数字都是由7部分组成        1, 1, 1, 0, 1, 1, 1,      //0           0, 0, 1, 0, 0, 1, 0,      //1        1, 0, 1, 1, 1, 0, 1,      //2        1, 0, 1, 1, 0, 1, 1,      //3        0, 1, 1, 1, 0, 1, 0,      //4        1, 1, 0, 1, 0, 1, 1,      //5        1, 1, 0, 1, 1, 1, 1,      //6        1, 0, 1, 0, 0, 1, 0,      //7        1, 1, 1, 1, 1, 1, 1,      //8        1, 1, 1, 1, 0, 1, 1       //9    };

然后,应该指出7个部分的坐标,先看其中一个:
这里写图片描述
再定义一个数组:

static POINT ptSegment[7][6] = {//组成数字的7个部分的多边形坐标,每个部分6个点         //    /\   这里三个点         //    ||         //    ||         //    \/   下面三个点                                7, 6, 11, 2, 31, 2, 35, 6, 31, 10, 11, 10,   // <---->        6, 7, 10, 11, 10, 31, 6, 35, 2, 31, 2, 11,        36, 7, 40, 11, 40, 31, 36, 35, 32, 31, 32, 11,        7, 36, 11, 32, 31, 32, 35, 36, 31, 40, 11, 40,        6, 37, 10, 41, 10, 61, 6, 65, 2, 61, 2, 41,        36, 37, 40, 41, 40, 61, 36, 65, 32, 61, 32, 41,        7, 66, 11, 62, 31, 62, 35, 66, 31, 70, 11, 70        //剩下的部分坐标就不一一说明了    };

至此,可以试着输出一些数字:

# include<windows.h>LRESULT CALLBACK WndProc(HWND hwnd,    UINT uMsg,    WPARAM wParam,    LPARAM lParam    );void DisplayDigit(HDC hdc, int iNumber){    //segment分割;段;部分;    //===================数字的显示=====================    //      111111    //      2    3    //      2    3    //      444444    //      5    6    //      5    6    //      777777    //================================================    static BOOL fSevenSegment[10][7] = {//10个数字,每个数字都是由7部分组成        1, 1, 1, 0, 1, 1, 1,      //0           0, 0, 1, 0, 0, 1, 0,      //1        1, 0, 1, 1, 1, 0, 1,      //2        1, 0, 1, 1, 0, 1, 1,      //3        0, 1, 1, 1, 0, 1, 0,      //4        1, 1, 0, 1, 0, 1, 1,      //5        1, 1, 0, 1, 1, 1, 1,      //6        1, 0, 1, 0, 0, 1, 0,      //7        1, 1, 1, 1, 1, 1, 1,      //8        1, 1, 1, 1, 0, 1, 1       //9    };    static POINT ptSegment[7][6] = {//组成数字的7个部分的多边形坐标,每个部分6个点                                    //    /\   这里三个点                                    //    ||                                    //    ||                                    //    \/   下面三个点                                 7, 6, 11, 2, 31, 2, 35, 6, 31, 10, 11, 10,   // <---->        6, 7, 10, 11, 10, 31, 6, 35, 2, 31, 2, 11,        36, 7, 40, 11, 40, 31, 36, 35, 32, 31, 32, 11,        7, 36, 11, 32, 31, 32, 35, 36, 31, 40, 11, 40,        6, 37, 10, 41, 10, 61, 6, 65, 2, 61, 2, 41,        36, 37, 40, 41, 40, 61, 36, 65, 32, 61, 32, 41,        7, 66, 11, 62, 31, 62, 35, 66, 31, 70, 11, 70    };    int iSeg;    for (iSeg = 0; iSeg < 7; iSeg++)    {        if (fSevenSegment[iNumber][iSeg])            Polygon(hdc, ptSegment[iSeg], 6); //绘制数字iNumber(一位数的)    }}int WINAPI WinMain(HINSTANCE hInstance,    HINSTANCE hPrevInstance,    LPSTR lpCmdLine,    int iCmdShow    ){    WNDCLASS wndclass;    wndclass.cbClsExtra = 0;    wndclass.cbWndExtra = 0;    wndclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);//这里用NULL表示使用微软提供的图标    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //同上    wndclass.hInstance = hInstance;    wndclass.lpfnWndProc = WndProc;    wndclass.lpszClassName = "类名";    wndclass.lpszMenuName = NULL;    wndclass.style = CS_HREDRAW | CS_VREDRAW;    RegisterClass(&wndclass);//注册窗口类    HWND hwnd;    hwnd = CreateWindow("类名", "窗口名", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,        CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);//在窗口风格用或语句就可以加上滚动条了    ShowWindow(hwnd, SW_SHOW);    UpdateWindow(hwnd);    MSG msg;    while (GetMessage(&msg, NULL, 0, 0))    {        TranslateMessage(&msg);        DispatchMessage(&msg);    }    return 0;}LRESULT CALLBACK WndProc(HWND hwnd,    UINT uMsg,    WPARAM wParam,    LPARAM lParam    ){    int i = 0;    PAINTSTRUCT ps;    HDC hdc;    switch (uMsg)    {    case WM_PAINT:        hdc = BeginPaint(hwnd, &ps);        for (i = 0;i < 10;i++)        {            DisplayDigit(hdc, i);            OffsetWindowOrgEx(hdc, -42, 0, NULL);            //这么理解,默认“窗口“原点(0,0)对应"视口"原点(0,0)(客户区左            //上角),并且向右x递增,向下y递增,默认是WM_TEXT模式,            //将窗口原点左移42个像素,比如原来(x0,y0)对应(x1,y1),左移            //后(x0-42,y0-42)对应(x1,y1)    //这样做就不用改变之前点的坐标了,比较方便        }        EndPaint(hwnd, &ps);        return 0;    case WM_CLOSE:        PostQuitMessage(0);        //DestroyWindow(hwnd);        return 0;    default:        return DefWindowProc(hwnd, uMsg, wParam, lParam);    }    return 0;}

程序运行结果:
这里写图片描述

以下是完整程序:

# include<windows.h># define ID_TIMER 1LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int WINAPI WinMain(HINSTANCE hInstance,    HINSTANCE hPrevInstance,    PSTR lpCmdLine,    int iCmdShow    ){    TCHAR szAppName[] = TEXT("DigClock");    WNDCLASS wndclass;    wndclass.cbClsExtra = 0;    wndclass.cbWndExtra = 0;    wndclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);//这里用NULL表示使用微软提供的图标    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //同上    wndclass.hInstance = hInstance;    wndclass.lpfnWndProc = WndProc;    wndclass.lpszClassName = szAppName;    wndclass.lpszMenuName = NULL;    wndclass.style = CS_HREDRAW | CS_VREDRAW;    if (!RegisterClass(&wndclass))//注册窗口类    {        MessageBox(NULL, "Program requires windows NT!", szAppName, MB_ICONERROR);        return 0;    }    HWND hwnd;    hwnd = CreateWindow(szAppName,  TEXT("Digital Clock"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,        CW_USEDEFAULT, CW_USEDEFAULT, NULL,NULL, hInstance, NULL);//在窗口风格用或语句就可以加上滚动条了    //cw_usedefault表示采用系统默认的值    ShowWindow(hwnd, SW_SHOW);    UpdateWindow(hwnd);    MSG msg;    while (GetMessage(&msg, NULL, 0, 0))    {        TranslateMessage(&msg);        DispatchMessage(&msg);    }    return 0;}//画数字void DisplayDigit(HDC hdc, int iNumber){    //segment分割;段;部分;    //===================数字的显示=====================    //      111111    //      2    3    //      2    3    //      444444    //      5    6    //      5    6    //      777777    //================================================    static BOOL fSevenSegment[10][7] = {//10个数字,每个数字都是由7部分组成        1, 1, 1, 0, 1, 1, 1,      //0           0, 0, 1, 0, 0, 1, 0,      //1        1, 0, 1, 1, 1, 0, 1,      //2        1, 0, 1, 1, 0, 1, 1,      //3        0, 1, 1, 1, 0, 1, 0,      //4        1, 1, 0, 1, 0, 1, 1,      //5        1, 1, 0, 1, 1, 1, 1,      //6        1, 0, 1, 0, 0, 1, 0,      //7        1, 1, 1, 1, 1, 1, 1,      //8        1, 1, 1, 1, 0, 1, 1       //9    };    static POINT ptSegment[7][6] = {//组成数字的7个部分的多边形坐标,每个部分6个点         //    /\   这里三个点         //    ||         //    ||         //    \/   下面三个点                                7, 6, 11, 2, 31, 2, 35, 6, 31, 10, 11, 10,   // <---->        6, 7, 10, 11, 10, 31, 6, 35, 2, 31, 2, 11,        36, 7, 40, 11, 40, 31, 36, 35, 32, 31, 32, 11,        7, 36, 11, 32, 31, 32, 35, 36, 31, 40, 11, 40,        6, 37, 10, 41, 10, 61, 6, 65, 2, 61, 2, 41,        36, 37, 40, 41, 40, 61, 36, 65, 32, 61, 32, 41,        7, 66, 11, 62, 31, 62, 35, 66, 31, 70, 11, 70    };    int iSeg;    for (iSeg = 0; iSeg < 7; iSeg++)    {        if (fSevenSegment[iNumber][iSeg])            Polygon(hdc, ptSegment[iSeg],6); //绘制数字iNumber(一位数的)    }}//bool表示是否去掉前面的0,,比如1,如果为true,就不显示0,否则显示(如01)void DisplayTwoDigits(HDC hdc, int iNumber, BOOL fSuppress){    if (!fSuppress || (iNumber / 10 != 0))        DisplayDigit(hdc, iNumber / 10);    //将窗口原点左移42个像素,比如原来(x0,y0)对应(x1,y1),左移后(x0-42,y0-42)对应(x1,y1)    //这样做就不用改变之前点的坐标了,比较方便    OffsetWindowOrgEx(hdc, -42, 0, NULL);    DisplayDigit(hdc, iNumber % 10);    OffsetWindowOrgEx(hdc, -42, 0, NULL);//绘制数字iNumber(两位数的)}void DisplayColon(HDC hdc)//画冒号{    POINT ptColon[2][4] = {        2, 21, 6, 17, 10, 21, 6, 25,        2, 51, 6, 47, 10, 51, 6, 55    };    Polygon(hdc, ptColon[0], 4);    Polygon(hdc, ptColon[1], 4);    OffsetWindowOrgEx(hdc, -12, 0, NULL);}void DisplayTime(HDC hdc, BOOL f24Hour, BOOL fSuppress){    SYSTEMTIME st;    GetLocalTime(&st);    if (f24Hour)//画时        DisplayTwoDigits(hdc, st.wHour, fSuppress);    else        DisplayTwoDigits(hdc, (st.wHour %= 12) ? st.wHour : 12, fSuppress);    DisplayColon(hdc);//画冒号    DisplayTwoDigits(hdc, st.wMinute, FALSE);//画分    DisplayColon(hdc); //画冒号    DisplayTwoDigits(hdc, st.wSecond, FALSE);//画秒}LRESULT CALLBACK WndProc(HWND hwnd,    UINT uMsg,    WPARAM wParam,    LPARAM lParam    ){    static BOOL f24Hour, fSuppress;    static HBRUSH hBrushRed;    static int cxClient, cyClient;    HDC hdc;    PAINTSTRUCT ps;    TCHAR szBuffer[2];    switch (uMsg)    {    case WM_CREATE:        hBrushRed = CreateSolidBrush(RGB( 255,0, 0));        SetTimer(hwnd, ID_TIMER, 1000, NULL);                     //fall through    case WM_SETTINGCHANGE://如果用户更改了任何系统设置,WM_SETTINGCHA    //NGE消息就会被传给所有的应用程序,可以去"控制面板"        //“区域设置”中实验一下        GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITIME, szBuffer, 2);        //LOCALE_ITIME标识符确定使用的是12小时制还是24小时制,        f24Hour = (szBuffer[0] == '1');        GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITLZERO, szBuffer, 2);        //然后使用LOCALE_ITLZERO标志符(在小时显示中禁止前面显示0)        fSuppress = (szBuffer[0] == '\0');        InvalidateRect(hwnd, NULL, TRUE);        return 0;    case WM_SIZE:        cxClient = LOWORD(lParam);        cyClient = HIWORD(lParam);        return 0;    case WM_TIMER:        InvalidateRect(hwnd, NULL, TRUE);        return 0;    case WM_PAINT:        hdc = BeginPaint(hwnd, &ps);        SetMapMode(hdc, MM_ISOTROPIC);        SetWindowExtEx(hdc, 276, 72, NULL);        SetViewportExtEx(hdc, cxClient, cyClient, NULL);        SetWindowOrgEx(hdc, 138, 36, NULL);        SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL);        SelectObject(hdc, GetStockObject(NULL_PEN));        SelectObject(hdc, hBrushRed);        DisplayTime(hdc, f24Hour, fSuppress);        EndPaint(hwnd, &ps);        return 0;    case WM_CLOSE:        KillTimer(hwnd, ID_TIMER);        DeleteObject(hBrushRed);        PostQuitMessage(0);        //DestroyWindow(hwnd);        return 0;  }        return DefWindowProc(hwnd, uMsg, wParam, lParam);}

上面的程序都是windwos程序设计第五版上面的,不是太好理解,所以写博客记录下来,长时间容易忘…….

0 0
原创粉丝点击