转自 https://blog.csdn.net/sunnyorange/article/details/6590793
首先明白DC的含义,Windows不允许程序员直接访问硬件,它对屏幕的操作是通过环境设备,也就是DC来完成的。DC就是设备上下文的意思,设备上下文就是当前的这个窗体的一些属性,譬如说他使用的画刷,画笔等等。也就是说,它并不是将像素直接输出到设备上,而是将图绘制到由设备描述表表示的逻辑意义上的"显示平面"上去。屏幕上的每一个窗口都对应一个DC,可以把DC想象成一个视频缓冲区,对这这个缓冲区的操作,会表现在这个缓冲区对应的屏幕窗口上。
设备描述表(DC)是Windows中的一种数据结构,它包含GDI需要的所有关于显示界面情况的描述字段,包括相连的物理设备和各种各样的状态信息。在Windows画图之前,Windows程序从GDI获取设备描述表句柄(HDC),并在每次调用完GDI输出函数后将句柄返回给GDI。
函数原型:
HDC GetDC(HWND hWnd);
hWnd:设备上下文环境被检索的窗口的句柄,如果该值为NULL,GetDC则检索整个屏幕的设备上下文环境。
在使用普通设备上下文环境绘图之后,必须调用ReleaseDc函数释放该设备上下文环境,典型和特有设备上下文环境不需要释放,设备上下文环境的个数仅受有效内存的限制。
在窗口的DC之外,可以建立自己的DC,就是说它不对应窗口,这个方法就是CreateCompatibleDC,这个DC就是一个内存缓冲区,通过这个DC你可以把和它兼容的窗口DC保存到这个DC中,就是说你可以通过它在不同的DC之间拷贝数据。例如:你先在这个DC中建立好数据,然后在拷贝到窗口的DC就是完成了这个窗口的刷新。
- hDeskTop = GetDesktopWindow();
-
- hDeskTopDC = GetDC(hDeskTop);//桌面窗口DC
-
- hMemDC = CreateCompatibleDC(hDeskTopDC);//这建立的就是与桌面窗口兼容的DC。
CreatCompatibleDC()创建了一个和当前屏幕的DC兼容的内存DC,在绘制位图的时候,你必须要在内存中建立这样的一个和当前设备的环境兼容的DC,也就是用这个函数建立,这样你才能把位图加载到这块内存里,然后在利用BitBlt函数将位图从内存复制到屏幕DC上,位图才能显示出来。或者说内存DC就相当于有了一个带有画面的“桌布”,你可以在这个DC上绘图,然后再把位图用原来的位图替换下来,就形成了一个新的位图。
HDC CreateCompatibleDC(HDC hdc);
假如你要对屏幕进行比较多的GDI函数操作,如果每一步操作都直接对屏幕DC进行操作,那出现的大多数可能性都是屏幕的闪烁。一个很好的解决方法就是使用内存DC,将这些操作全部先在内存DC上操作,然后依次性在屏幕上进行操作。
例如:如果你单单使用BitBlt在屏幕上拷贝一个图,那可以直接使用屏幕的DC。但是如果你要先设置背景(fillrect)然后再BilBlt的话,这就涉及到两个屏幕DC的操作,这样的话屏幕很容易闪烁。
内存设备上下文环境是仅在内存中存在的设备上下文环境,当内存设备上下文环境被创建时,它的显示界面是标准的一个单色像素宽和一个单色像素高。在一个应用程序可以使用内存设备上下文环境进行绘图操作之前,它必须选择一个高和宽都正确的位图到设备上下文环境中,这可以通过使用CreateCompatibleBitmap函数指定高、宽和色彩组合以满足函数调用的需要。
- CDC m_memDC;
-
- //内存设备环境与屏幕设备环境关联(兼容)
- m_memDC.CreateCompatibleDC(pWindowDC);
- //内存位图与与屏幕关联(兼容),大小为游戏窗口的尺寸
- m_memBmp.CreateCompatibleBitmap(pWindowDC,m_nWidth,m_nHeight);
- //内存设备环境与内存位图关联,以便通过m_memDC在内存位图上作画
- m_memDC.SelectObject(&m_memBmp);