设备环境DC(device context 又称为设备上下文或设备描述表)。它是一个关于如何绘制图形的方法的集合,它既可以绘制各种图形,也可以确定在应用窗体中绘制图形的方式,就是绘图模式和映射模式。
在Win32编程中,设备环境就是HDC来标识。H的意思是Handle句柄的意思。
如何获得HDC?
一:
HDC hdc = ::GetDC(hWnd);
::ReleaseDC(hWnd,hdc);//没有release会因为申请不到hdc而黑屏
二:
1 PAINTSTRUCT ps; 2 hdc = BeginPaint(hWnd, &ps); 3 4 EndPaint(hWnd, &ps);
三:通过调用CreateCompatibleDC函数来创建与目标DC兼容的内存DC。一般用于解决界面的闪烁问题。
代码片段:
HDC hMemDC = ::CreateCompatibleDC(hDest); ::BitBlt(hDest,x,y,w,h,hMemDC,0,0,SRCCOPY); ::DeleteDC(hMemDC);
GDI对象:

在GDI中,用HPEN来表示画笔。H是代表句柄的意思。
在GDI中,画线,画边框(如矩形边框,圆边框,饼边框)都是采用画笔来操作的。
GDI默认的画笔是黑色,宽度为1,样式为实线的画笔

在GDI中,用HBRUSH来表示画刷,H是代表句柄的意思、
在GDI中,填充矩形,填充圆,填充饼等以及刷窗口背景都是经过画刷来操作的。
GDI默认的画刷是白色的。

在GDI中,用HFONT来表示字体。H是代表的句柄。
在GDI中,所有的文本绘制,都是要基于具体的字体对象来绘制。
GDI中默认的字体,是系统的宽字体,比如对话框标题一般就采用这个字体

在GDI中,用HRGN来表示区域。H代表句柄
在窗口中,一个区域可以是椭圆形,多边形,或是更常见的矩形

在GDI中,用HBITMAP来表示位图,H代表句柄。
GDI的绘制从大体上分为图形绘制跟图像绘制。对于线、矩形、圆、饼等的绘制是属于图形绘制。而对于位图的绘制是属于图像绘制。
GDI函数:
HGDIOBJ WINAPI SelectObject(HDC hdc,HGDIOBJ h);//第一个参数是设备DC。第二个参数HGDIOBJ,其实是一个void*。这个函数传入一个新的GDI对象到第一个参数的DC中,并返回该DC的老的相同类型的GDI对象。
GetStockObject();可以通过对象的ID号来获得库存的GDI对象的函数。
库存的对象是不需要销毁的
GDI对象的信息获取:
比如位图HBITMAP对象的结构是BITMAP,画刷是LOGBRUSH。我们现在以获得位图对象信息为例:得到位图的宽度与高度。
BITMAP bm; ::GetObject(hBitmap,sizeof(BITMAP),&bm);
绘制位图的步骤:
·获得目标DC句柄
·创建与目标DC兼容的临时内存DC
·将位图句柄选入到临时内存DC
·使用BitBlt函数将临时内存DC的位图拷贝到目标DC
·将位图句柄选出临时DC
·销毁临时DC
1 HDC hMemdc = ::CreateCompatibleDC(hdc); 2 HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemdc,h_BmpBack); 3 BITMAP bittemp; 4 ::GetObject(h_BmpBack,sizeof(BITMAP),&bittemp); 5 ::BitBlt(hdc,0,0,bittemp.bmWidth,bittemp.bmHeight,hMemdc,200,0,SRCCOPY); 6 :SelectObject(hMemdc,hOldBitmap); 7 ::DeleteDC(hMemdc);
拉伸填充:
1 HDC hMemdc = ::CreateCompatibleDC(hdc); 2 HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemdc,h_BmpBack); 3 BITMAP bittemp; 4 ::GetObject(h_BmpBack,sizeof(BITMAP),&bittemp); 5 6 RECT reClient; 7 ::GetClientRect(hWnd,&reClient); 8 int nWidth = reClient.right - reClient.left; 9 int nHeight = reClient.bottom - reClient.top; 10 11 ::StretchBlt(hdc,0,0,nWidth,nHeight,hMemdc,0,0,bittemp.bmWidth,bittemp.bmHeight,SRCCOPY); 12 ::SelectObject(hMemdc,hOldBitmap); 13 ::DeleteDC(hMemdc);
一个透明背景蓝色字体:
1 HDC hMemdc = ::CreateCompatibleDC(hdc); 2 HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemdc,h_BmpBack); 3 BITMAP bittemp; 4 ::GetObject(h_BmpBack,sizeof(BITMAP),&bittemp); 5 //::BitBlt(hdc,0,0,bittemp.bmWidth,bittemp.bmHeight,hMemdc,200,0,SRCCOPY); 6 7 RECT reClient; 8 ::GetClientRect(hWnd,&reClient); 9 int nWidth = reClient.right - reClient.left; 10 int nHeight = reClient.bottom - reClient.top; 11 12 ::StretchBlt(hdc,0,0,nWidth,nHeight,hMemdc,0,0,bittemp.bmWidth,bittemp.bmHeight,SRCCOPY); 13 14 ::SelectObject(hMemdc,hOldBitmap); 15 ::DeleteDC(hMemdc); 16 17 18 19 //字体 20 LOGFONT MyFont; 21 memset(&MyFont,0,sizeof(LOGFONT)); 22 MyFont.lfCharSet = GB2312_CHARSET; 23 MyFont.lfWidth = 20; 24 MyFont.lfHeight = 40; 25 _tcscpy(MyFont.lfFaceName,_T("宋体")); 26 HFONT hFont = CreateFontIndirect(&MyFont); 27 HFONT hOldFont = (HFONT)::SelectObject(hdc,hFont); 28 COLORREF clrOldText = ::SetTextColor(hdc,RGB(0,0,128)); 29 ::SetBkMode(hdc,TRANSPARENT); 30 31 //标题 32 wstring title = L"欢迎访问XCoderLiu的博客园"; 33 DrawText(hdc,title.c_str(),(int)title.length(),&reClient,DT_CENTER|DT_TOP|DT_SINGLELINE); 34 35 ::SelectObject(hdc,hOldFont); 36 ::SetTextColor(hdc,clrOldText); 37 ::DeleteObject(hFont);
DrawText采用绘制区域和绘制格式来控制绘制的位置,TextOut直接采用坐标控制绘制位置,所以自定义绘制位置时TextOut比较灵活,但是布局式绘制时DrawText比较适合。