天天看點

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;
}
           

運作結果:

windows程式設計--時鐘

總結和分析:

  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;/