GDI绘图入门实例——数字时钟

来源:互联网 发布:php curl异步抓取 编辑:程序博客网 时间:2024/06/04 00:43

    在C++界面编程中,经常会用到GDIGraphics Device Interface的缩写,含义是图形设备接口),我在VS2013上,以实现动态数字为例,介绍它的基本使用:

1)下载GDIplus工具包,推荐连接:http://download.csdn.net/detail/yja000/9868700;

2)新建对话框工程,将GDIplus工具包中文件全部复制到工程目录下;

3)在StdAfx.h文件中添加GDIplus连接代码:

#include "../Includes\\GdiPlus.h"

using namespace Gdiplus;

#pragma comment(lib, "../Lib\\GdiPlus.lib")

如果是VS低版本或者是VC++平台,还需要添加以下代码:

#define UNICODE

#ifndef ULONG_PTR

#define ULONG_PTR unsigned long*

#endif

4)在类行为文件XX.cpp的InitInstance()中添加如下4条代码(注意【】标识的添加位置):

GdiplusStartupInput gdiplusStartupInput;

ULONG_PTR gdiplusToken;

GdiplusStartup(&gdiplusToken,&gdiplusStartupInput, NULL);

【C**Dlg dlg;】

【…】

GdiplusShutdown(gdiplusToken);

【return FALSE;】

5) 在XXDlg.h文件中声明变量和函数:

Image *m_pImageBackground, *m_pImageNum;

BOOL ImageFromIDResource(UINT nID, LPCTSTR sTR, Image *&pImg);//获取图片信息函数

void DrawBackground(HDC hDC);//绘制背景
void DrawTime(HDC hDC);//绘制时钟 

6)在XXDlg.cpp文件中添加ImageFromIDResource函数代码:

BOOL Cgraph_testDlg::ImageFromIDResource(UINT nID, LPCTSTR sTR, Image *&pImg)
{
HINSTANCE hInst = AfxGetResourceHandle();
HRSRC hRsrc = ::FindResource(hInst, MAKEINTRESOURCE(nID), sTR); // type  
if (!hRsrc)
return FALSE;

// load resource into memory  
DWORD len = SizeofResource(hInst, hRsrc);
BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);
if (!lpRsrc)
return FALSE;

// Allocate global memory on which to create stream  
HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);
BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
memcpy(pmem, lpRsrc, len);
IStream* pstm;
CreateStreamOnHGlobal(m_hMem, FALSE, &pstm);

// load from stream  
pImg = Gdiplus::Image::FromStream(pstm);

// free/release stuff  
GlobalUnlock(m_hMem);
pstm->Release();
FreeResource(lpRsrc);

return TRUE;
}

7)添加PNG背景图和数字编码图,在XXDlg.cpp文件的OnInitDialog()函数中添加代码:

ImageFromIDResource(IDB_PNG1, _T("PNG"), m_pImageBackground);
ImageFromIDResource(IDB_PNG2, _T("PNG"), m_pImageNum);
SetTimer(1, 1000, NULL);

8)在XXDlg.cpp文件中添加DrawBackground(HDC hDC)函数及代码:

void Cgraph_testDlg::DrawTime(HDC hDC)
{
Graphics graph(hDC);

SYSTEMTIME SystemTime;   // address of system time structure
GetLocalTime(&SystemTime);

int nx = 30;
//H,从m_pImageClock中剪切指定rect中的像素draw到指定位置
graph.DrawImage(m_pImageNum, nx + 0, 0, 14 * (SystemTime.wHour / 10), 0, 14, 23, UnitPixel);
graph.DrawImage(m_pImageNum, nx + 20, 0, 14 * (SystemTime.wHour % 10), 0, 14, 23, UnitPixel);
//:
graph.DrawImage(m_pImageNum, nx + 20 * 2, 0, 140, 0, 14, 23, UnitPixel); 
//M
graph.DrawImage(m_pImageNum, nx + 20 * 3, 0, 14 * (SystemTime.wMinute / 10), 0, 14, 23, UnitPixel); 
graph.DrawImage(m_pImageNum, nx + 20 * 4, 0, 14 * (SystemTime.wMinute % 10), 0, 14, 23, UnitPixel); 
//:
graph.DrawImage(m_pImageNum, nx + 20 * 5, 0, 140, 0, 14, 23, UnitPixel); 
//S
graph.DrawImage(m_pImageNum, nx + 20 * 6, 0, 14 * (SystemTime.wSecond / 10), 0, 14, 23, UnitPixel); 
graph.DrawImage(m_pImageNum, nx + 20 * 7, 0, 14 * (SystemTime.wSecond % 10), 0, 14, 23, UnitPixel); 

graph.ReleaseHDC(hDC);
}


9)在XXDlg.cpp文件中添加DrawBackground(HDC hDC)函数及代码:

void Cgraph_testDlg::DrawBackground(HDC hDC)
{
CRect rcClient;
GetClientRect(&rcClient);

Graphics graph(hDC); 

Point points[] = { Point(0, 0),
Point(rcClient.Width(), 0),
Point(0, rcClient.Height()),
};
graph.DrawImage(m_pImageBackground, points, 3);

graph.ReleaseHDC(hDC);
}

10)在XXDlg.cpp文件中添加MyPaint()函数及代码:

void Cgraph_testDlg::MyPaint()
{
CPaintDC dc(this);

CRect rcClient;
GetClientRect(&rcClient);

CDC dcMem;
CBitmap bmpMem;
dcMem.CreateCompatibleDC(&dc);
if (bmpMem.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height()))
{
CBitmap* pOldBmp = dcMem.SelectObject(&bmpMem);

DrawBackground(dcMem.m_hDC);
DrawTime(dcMem.m_hDC);

dc.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &dcMem, 0, 0, SRCCOPY);
dcMem.SelectObject(pOldBmp);
bmpMem.DeleteObject();
}
dcMem.DeleteDC();
}

11)在XXDlg.cpp文件的OnPaint()函数else分支中添加代码:

MyPaint(); //绘图

12)在XXDlg.cpp文件的OnInitDialog()函数中添加代码:

ImageFromIDResource(IDB_PNG1, _T("PNG"), m_pImageBackground);//装载背景图
ImageFromIDResource(IDB_PNG2, _T("PNG"), m_pImageNum);//装载数字编码图
SetTimer(1, 1000, NULL);

13)在对话框工程中添加定时器响应函数及代码:

void Cgraph_testDlg::OnTimer(UINT_PTR nIDEvent)
{
//UpdateClockDisplay(255);
UpdateWindow();
Invalidate();

CDialogEx::OnTimer(nIDEvent);
}

14)最后在退出时释放资源:

void Cgraph_testDlg::OnDestroy()
{
delete m_pImageBackground;
delete m_pImageNum;
CDialogEx::OnDestroy();
}

保存后运行程序,对话框中就显示背景图,并且刷新当前显示时间,效果如下:


原创粉丝点击