windows编程--时钟

代码:

#include<Windows.h> //底层实现窗口的头文件
#include<tchar.h>
const TCHAR szWindowClass[] = L"第一个窗口";
const TCHAR szWindowTitle[] = L"时钟";
const int IDM_TOPMOST = 101;
const int IDTIMER = 1;

#define KEY_DOWN(vk_code)(GetAsyncKeyState(vk_code)&0x8000)
//6.处理消息(窗口过程)
//CALLBACK  代表__stdcall 指的是WinMain函数参数的传递顺序 从右向左,依次入栈,并且在函数返回前 清空堆栈
LRESULT CALLBACK WindowProc(
    HWND hwnd,  //  消息所属的窗口句柄
    UINT Msg,      //具体的消息名称 WM_XXX 消息名
    WPARAM wParam,  //键盘的附加消息
    LPARAM lParam   //鼠标的附加消息
    )
{
    static HBRUSH         hBrushRed;
    static BOOL bTopMost = FALSE;//是否最前端,默认是最前端
    switch (Msg)
    {
    case WM_CREATE:
    {
      
        HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
        AppendMenu(hSysMenu, MF_SEPARATOR, 0, NULL);
        AppendMenu(hSysMenu, MF_STRING, IDM_TOPMOST, L"保持在其他窗口前端");
        CheckMenuItem(hSysMenu, IDM_TOPMOST, MF_UNCHECKED);

       // HINSTANCE hInst = ((LPCREATESTRUCT)lParam)->hInstance;
        hBrushRed = CreateSolidBrush(RGB(255, 0, 0));
        SetTimer(hwnd, IDTIMER, 1000, NULL);
        return 0;
    }
       
    case WM_TIMER:
    {
        switch (wParam) //判断定时器的ID
        {
        case IDTIMER:
            InvalidateRect(hwnd, NULL, TRUE);
 
        }
        return 0;
    }

    case WM_DESTROY:
    {
        KillTimer(hwnd, IDTIMER);
        PostQuitMessage(0);

        return 0;
    }
    case WM_CONTEXTMENU:
    {
        POINTS p = MAKEPOINTS(lParam);
        HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
        int nID = TrackPopupMenu(hSysMenu, TPM_LEFTALIGN | TPM_RETURNCMD, p.x, p.y, 0, hwnd, NULL);
        if (nID > 0)
        {
            SendMessage(hwnd, WM_SYSCOMMAND, nID, 0);

        }
        return 0;
    }
    case WM_SYSCOMMAND:
    {
        HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
        switch (wParam)
        {
        case IDM_TOPMOST:
        {
            bTopMost = !bTopMost;
            if (bTopMost) {
                CheckMenuItem(hSysMenu, IDM_TOPMOST, MF_CHECKED);
                SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE);

            }
            else
            {
                CheckMenuItem(hSysMenu, IDM_TOPMOST, MF_UNCHECKED);
                SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE);

            }
            break;
        }
        return DefWindowProc(hwnd, Msg, wParam, lParam);

        }

    }
    case WM_NCHITTEST:
    {
        LRESULT nHitTest = DefWindowProc(hwnd, Msg, wParam, lParam);
        if(nHitTest == HTCLIENT && KEY_DOWN(MK_LBUTTON))
            nHitTest = HTCAPTION;
        return nHitTest;
    }
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd,&ps);
        SelectObject(hdc, GetStockObject(NULL_PEN));
        SelectObject(hdc, hBrushRed);
        SYSTEMTIME t;		//
        GetLocalTime(&t);//获取系统时间
        TCHAR str[20];
       //_stprintf(str, L"%d:%d:%d", t.wHour, t.wMinute, t.wSecond);
       swprintf_s(str, L"%d:%d:%d", t.wHour, t.wMinute, t.wSecond);
       RECT r;
       GetClientRect(hwnd, &r);//获取客户区的矩形
       //单行,垂直居中,水平输出字符串
       DrawText(hdc,str,-1,&r,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
       EndPaint(hwnd, &ps);
       return 0;
    }
        
  
    default:
        return DefWindowProc(hwnd, Msg, wParam, lParam);
    }

 
}
//程序的入门函数
/*
    WINAPI: 代表__stdcall 指的是WinMain函数参数的传递顺序 从右向左,依次入栈,并且在函数返回前 清空堆栈
*/
int WINAPI WinMain(
    HINSTANCE hInstance,    //应用程序的实例句柄
    HINSTANCE hPrevInstance,//上一个应用程序句柄,在 win32 环境下,一般为NULL,不起作用了 
    LPSTR lpCmdLine,        //char * argv[] 
    int nCmdShow)           //窗口的显示方式:最大化、最小化、正常
{
    //1.设计窗口
    WNDCLASS wc = {0};
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //设置背景
    wc.hCursor = LoadCursor(NULL, IDC_HAND);//设置光标,第一个参数为NULL表示使用系统提供的光标
    wc.hIcon = LoadIcon(NULL, IDI_ERROR);//图标
    wc.hInstance = hInstance;//应用程序的实例句柄,传入winmain中的形参即可
    wc.lpfnWndProc = WindowProc;//回调函数 窗口过程
    wc.lpszClassName = szWindowClass;//窗口类名称
    wc.lpszMenuName = NULL;//菜单名称
    wc.style = 0;//显示风格, 最大化、最小化、正常
   
    //2.注册窗口
    RegisterClass(&wc);
   
    HWND hwnd = CreateWindow(szWindowClass,
        szWindowTitle,
        WS_POPUP | WS_BORDER | WS_SYSMENU,
        200, 200,
        200, 100,
        NULL, NULL,
        hInstance, NULL);
    if (!hwnd) return FALSE;

    //4.显示和更新
    ShowWindow(hwnd, SW_SHOWNORMAL);
    UpdateWindow(hwnd);
    MSG msg;

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

运行结果:
在这里插入图片描述
总结和分析:

  1. 添加#include<Windows.h>头文件:底层实现窗口的头文件,和 #include<tchar.h>:是一个在TCHAR.h里面,目的是为了简化代码方便国际使用。
  2. 全局区
const TCHAR szWindowClass[] = L"第一个窗口";
const TCHAR szWindowTitle[] = L"时钟";
const int IDM_TOPMOST = 101;保证菜单在其他窗口的前面
const int IDTIMER = 1;///定时器的ID
#define KEY_DOWN(vk_code)(GetAsyncKeyState(vk_code)&0x8000)//判断是否按下的宏

关于KEYDOWN(VK_CODE)

  1. 用于消息处理的回调函数
LRESULT CALLBACK WindowProc(
    HWND hwnd,  //  消息所属的窗口句柄
    UINT Msg,      //具体的消息名称 WM_XXX 消息名
    WPARAM wParam,  //键盘的附加消息
    LPARAM lParam   //鼠标的附加消息
    )
{
    //static HBRUSH         hBrushRed;
    static BOOL bTopMost = FALSE;//是否最前端,默认是最前端
    switch (Msg)
    {
    case WM_CREATE:	//	应用程序创建一个窗口 创建窗口的消息
    {
      
        HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
        AppendMenu(hSysMenu, MF_SEPARATOR, 0, NULL);
        AppendMenu(hSysMenu, MF_STRING, IDM_TOPMOST, L"保持在其他窗口前端");
        CheckMenuItem(hSysMenu, IDM_TOPMOST, MF_UNCHECKED);

       // HINSTANCE hInst = ((LPCREATESTRUCT)lParam)->hInstance;
        hBrushRed = CreateSolidBrush(RGB(255, 0, 0));
        SetTimer(hwnd, IDTIMER, 1000, NULL);
        return 0;
    }
       
    case WM_TIMER:	//定时器的消息
    {
        switch (wParam) //判断定时器的ID
        {
        case IDTIMER:
            InvalidateRect(hwnd, NULL, TRUE);
 
        }
        return 0;
    }

    case WM_DESTROY:	//窗口销毁的VM消息
    {
        KillTimer(hwnd, IDTIMER);
        PostQuitMessage(0);

        return 0;
    }
    case WM_CONTEXTMENU:
    {
        POINTS p = MAKEPOINTS(lParam);
        HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
        int nID = TrackPopupMenu(hSysMenu, TPM_LEFTALIGN | TPM_RETURNCMD, p.x, p.y, 0, hwnd, NULL);
        if (nID > 0)
        {
            SendMessage(hwnd, WM_SYSCOMMAND, nID, 0);

        }
        return 0;
    }
    case WM_SYSCOMMAND:
    {
        HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
        switch (wParam)
        {
        case IDM_TOPMOST:
        {
            bTopMost = !bTopMost;
            if (bTopMost) {
                CheckMenuItem(hSysMenu, IDM_TOPMOST, MF_CHECKED);
                SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE);

            }
            else
            {
                CheckMenuItem(hSysMenu, IDM_TOPMOST, MF_UNCHECKED);
                SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE);

            }
            break;
        }
        return DefWindowProc(hwnd, Msg, wParam, lParam);

        }

    }
    case WM_NCHITTEST:
    {
        LRESULT nHitTest = DefWindowProc(hwnd, Msg, wParam, lParam);
        if(nHitTest == HTCLIENT && KEY_DOWN(MK_LBUTTON))
            nHitTest = HTCAPTION;
        return nHitTest;
    }
    case WM_PAINT:		//	要求一个窗口重画自己 
    {
        PAINTSTRUCT ps;//
        HDC hdc = BeginPaint(hwnd,&ps);
       // SelectObject(hdc, GetStockObject(NULL_PEN));
        //SelectObject(hdc, hBrushRed);
        SYSTEMTIME t;//系统时间变量
        GetLocalTime(&t);//获取系统时间
        TCHAR str[20];
       //_stprintf(str, L"%d:%d:%d", t.wHour, t.wMinute, t.wSecond);
       swprintf_s(str, L"%d:%d:%d", t.wHour, t.wMinute, t.wSecond);
       RECT r;
       GetClientRect(hwnd, &r);//获取客户区的矩形
       //单行,垂直居中,水平输出字符串
       DrawText(hdc,str,-1,&r,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
       EndPaint(hwnd, &ps);
       return 0;
    }
        
  
    default:
        return DefWindowProc(hwnd, Msg, wParam, lParam);
    }

 
}

/typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME;
/

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值