win32数字时钟

首先看下程序吧
这里写图片描述
一个数字时钟,如何实现呢?
首先,这样的数字可以分为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 1

LRESULT 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程序设计第五版上面的,不是太好理解,所以写博客记录下来,长时间容易忘…….

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值