Bitmap位图应用1 ------ Win32的数字时钟

学习编程离不开实战演练——用所掌握的技术来实现相应的功能,今天来玩一玩Win32的位图Bitmap,写一个数字时钟

 

我们先来看看这个数字时钟的需求:

(1)可以用ASCII码的数字,但是不太美观,因此需要做一个位图,完美模拟电子表的数字(我亲自做了一个,待会儿上传)

(2)如何将位图贴到我们的程序中

a)先将位图加载到内存中

我们先来看看msdn:

HBITMAP LoadBitmap(
  HINSTANCE hInstance,  // handle to application instance
  LPCTSTR lpBitmapName  // name of bitmap resource
);

因此不难知道使用方法,用法我没必要多少,我只想提一点:

我们的位图是保存在硬盘(ROM)中的,程序是在内存(RAM)中的,因此首先需将位图加载到内存中,我们的程序才能直接使用。LoadBitmap函数就是其这样一个作用

类似的函数还有:LoadIcon、LoadCursor等等

b)将位图贴到我们的程序中

这个需要用到很常用的、也是很有用的函数:

BOOL BitBlt(
  HDC hdcDest, // handle to destination DC
  int nXDest,  // x-coord of destination upper-left corner
  int nYDest,  // y-coord of destination upper-left corner
  int nWidth,  // width of destination rectangle
  int nHeight, // height of destination rectangle
  HDC hdcSrc,  // handle to source DC
  int nXSrc,   // x-coordinate of source upper-left corner
  int nYSrc,   // y-coordinate of source upper-left corner
  DWORD dwRop  // raster operation code
);

这个函数有一个很强大的功能:

我们可以按照自己的需要截取位图的一部分,这就意味着有时我们的程序只需要那么几张、或是仅仅一张位图,就能达到使用更多张位图的效果

它的具体用法可以参见给出的完整代码

(3)获取系统时间

这个就没什么多说的了,直接使用以下函数就ok:

[cpp]  view plain copy print ?
  1. GetLocalTime(LPSYSTEMTIME)//传递一个SYSTEMTIME类型的指针  就是系统时间  


(4)时间的处理

我就仅仅介绍我的做法:

[cpp]  view plain copy print ?
  1. int x, y, cxBitmap, cyBitmap;  
[cpp]  view plain copy print ?
  1. //x、y表示位图贴在窗口客户区的坐标,cxBitmap、cyBitmap表示位图的长宽。为了方便起见,以上四个全是全局变量  

 

时间处理代码:

[cpp]  view plain copy print ?
  1. VOID DrawTime(HDC hdc, WORD time, BOOL isSecond)  
  2. {  
  3.     HDC     hdcMem;  
  4.     int     decade, uint;//十位和个位  
  5.   
  6.     hdcMem = CreateCompatibleDC(hdc);   //兼容DC  
  7.     SelectObject(hdcMem, hBitmap);      //选中位图  
  8.   
  9.     //判断当前时间是否小于10 ,如果小于10 , 就要用0来填十位  
  10.     if(time < 10)  
  11.     {  
  12.         decade  = 0;  
  13.         uint    = time;  
  14.     }  
  15.     else  
  16.     {  
  17.         decade  = time / 10;  
  18.         uint    = time % 10;  
  19.     }  
  20.       
  21.     //绘制十位  
  22.     x += cxBitmap;  
  23.     BitBlt(hdc, x, y, cxBitmap, cyBitmap / 12, hdcMem, 0, (11 - decade) * (cyBitmap / 12), SRCCOPY);  
  24.       
  25.     //绘制个位  
  26.     x += cxBitmap;  
  27.     BitBlt(hdc, x, y, cxBitmap, cyBitmap / 12, hdcMem, 0, (11 - uint) * (cyBitmap / 12), SRCCOPY);  
  28.       
  29.     //如果不是秒 , 那么个位后面加一个冒号  
  30.     if(!isSecond)  
  31.     {  
  32.         x += cxBitmap;  
  33.         BitBlt(hdc, x, y, cxBitmap, cyBitmap / 12, hdcMem, 0, cyBitmap / 12, SRCCOPY);  
  34.     }  
  35.   
  36.     DeleteDC(hdcMem);  
  37. }  

 

(5)设定一个时间计时器,每隔一秒调用一次(这个不是本次的重点,以后会讲到的,其实很简单^_^)

 

 

下面直接上完整的源代码:(有注释)

[cpp]  view plain copy print ?
  1. //数字时钟  
  2. #include<windows.h>  
  3. #include"resource.h"  
  4.   
  5. //重新定义窗口风格(不可改变大小)  
  6. #define WS_NORESIZEWINDOW   (WS_OVERLAPPED     | \  
  7.                              WS_CAPTION        | \  
  8.                              WS_SYSMENU        | \  
  9.                              WS_MINIMIZEBOX)  
  10. //设定计时器ID  
  11. #define ID_TIMER    1  
  12.   
  13. HBITMAP hBitmap;  
  14. int     x, y, cxBitmap, cyBitmap;  
  15.   
  16. LRESULT CALLBACK WndProc(HWNDUINTWPARAMLPARAM);  
  17.   
  18. int WINAPI WinMain(HINSTANCE hInstance,  
  19.                    HINSTANCE hPrevInstance,  
  20.                    PSTR szCmdLine,  
  21.                    int iCmdShow)  
  22. {  
  23.     static  TCHAR   szAppName[] = TEXT("NumClock");  
  24.     HWND            hwnd;  
  25.     MSG             msg;  
  26.     WNDCLASS        wndclass;  
  27.       
  28.     wndclass.style          = CS_HREDRAW | CS_VREDRAW;  
  29.     wndclass.lpfnWndProc    = WndProc;  
  30.     wndclass.cbClsExtra     = 0;  
  31.     wndclass.cbWndExtra     = 0;  
  32.     wndclass.hInstance      = hInstance;  
  33.     wndclass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);  
  34.     wndclass.hCursor        = LoadCursor(NULL, IDC_ARROW);  
  35.     wndclass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);  
  36.     wndclass.lpszMenuName   = NULL;  
  37.     wndclass.lpszClassName  = szAppName;  
  38.       
  39.     if(!RegisterClass(&wndclass))  
  40.     {  
  41.         MessageBox(NULL, TEXT("This program requires Windows NT!"),  
  42.             szAppName, MB_ICONERROR);  
  43.         return 0;  
  44.     }  
  45.       
  46.     hwnd = CreateWindow(szAppName,  
  47.                         TEXT("NumClock Demo"),  
  48.                         WS_NORESIZEWINDOW,  
  49.                         (1366 - 200) / 2,  
  50.                         (768 - 150) / 2,  
  51.                         200,  
  52.                         150,  
  53.                         NULL,  
  54.                         NULL,  
  55.                         hInstance,  
  56.                         NULL);  
  57.   
  58.     ShowWindow(hwnd, iCmdShow);  
  59.     UpdateWindow(hwnd);  
  60.   
  61.     while(GetMessage(&msg, NULL, 0, 0))  
  62.     {  
  63.         TranslateMessage(&msg);  
  64.         DispatchMessage(&msg);  
  65.     }  
  66.       
  67.     return msg.wParam;  
  68. }  
  69.   
  70. VOID DrawTime(HDC hdc, WORD time, BOOL isSecond)  
  71. {  
  72.     HDC     hdcMem;  
  73.     int     decade, uint;//十位和个位  
  74.   
  75.     hdcMem = CreateCompatibleDC(hdc);   //兼容DC  
  76.     SelectObject(hdcMem, hBitmap);      //选中位图  
  77.   
  78.     //判断当前时间是否小于10 ,如果小于10 , 就要用0来填十位  
  79.     if(time < 10)  
  80.     {  
  81.         decade  = 0;  
  82.         uint    = time;  
  83.     }  
  84.     else  
  85.     {  
  86.         decade  = time / 10;  
  87.         uint    = time % 10;  
  88.     }  
  89.       
  90.     //绘制十位  
  91.     x += cxBitmap;  
  92.     BitBlt(hdc, x, y, cxBitmap, cyBitmap / 12, hdcMem, 0, (11 - decade) * (cyBitmap / 12), SRCCOPY);  
  93.       
  94.     //绘制个位  
  95.     x += cxBitmap;  
  96.     BitBlt(hdc, x, y, cxBitmap, cyBitmap / 12, hdcMem, 0, (11 - uint) * (cyBitmap / 12), SRCCOPY);  
  97.       
  98.     //如果不是秒 , 那么个位后面加一个冒号  
  99.     if(!isSecond)  
  100.     {  
  101.         x += cxBitmap;  
  102.         BitBlt(hdc, x, y, cxBitmap, cyBitmap / 12, hdcMem, 0, cyBitmap / 12, SRCCOPY);  
  103.     }  
  104.   
  105.     DeleteDC(hdcMem);  
  106. }  
  107.   
  108. //计时器回调函数  
  109. VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)  
  110. {  
  111.     HDC     hdc;  
  112.     SYSTEMTIME st;  
  113.   
  114.     GetLocalTime(&st);//获取本地系统时间  
  115.   
  116.     hdc = GetDC(hwnd);  
  117.   
  118.     x = 33;  
  119.     y = 51;  
  120.       
  121.     DrawTime(hdc, st.wHour, FALSE);     //绘制小时数字  
  122.     DrawTime(hdc, st.wMinute, FALSE);   //绘制分钟数字  
  123.     DrawTime(hdc, st.wSecond, TRUE);    //绘制秒钟数字  
  124.       
  125.     ReleaseDC(hwnd, hdc);  
  126. }  
  127.   
  128. //窗口回调函数  
  129. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
  130. {     
  131.     switch(message)  
  132.     {  
  133.     //初始化参数  
  134.     case WM_CREATE:  
  135.         {  
  136.             HINSTANCE   hInstance;  
  137.             BITMAP      bitmap;  
  138.   
  139.             hInstance = ((LPCREATESTRUCT)lParam)->hInstance;//获取窗口的实例句柄  
  140.             hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP1));  
  141.             GetObject(hBitmap, sizeof(BITMAP), &bitmap);  
  142.   
  143.             cxBitmap = bitmap.bmWidth;  
  144.             cyBitmap = bitmap.bmHeight;  
  145.   
  146.             SetTimer(hwnd, ID_TIMER, 1000, TimerProc);//计时器开始  
  147.         }  
  148.         return 0 ;  
  149.   
  150.     case WM_DESTROY:  
  151.         PostQuitMessage(0);  
  152.         return 0;  
  153.     }  
  154.   
  155.     return DefWindowProc(hwnd, message, wParam, lParam);  
  156. }  


 


 

 

好了到此为止,数字时钟算是完成了,下面来看看运行效果:

<Win32_2>Bitmap位图应用1 ------ Win32的数字时钟_第1张图片

 

怎么样,是不是和电子表的显示很相似呢?呵呵……

download

你可能感兴趣的:(Bitmap位图应用1 ------ Win32的数字时钟)