理解设备上下文

9
作为MFC的新手,我经常看到设备环境(Device Contexts, DCs)。我模糊地理解它与绘图有关,但具体细节在我找到的任何地方都没有很好地解释清楚。创建“兼容的设备环境”是什么意思,为什么这很重要?SelectObject是什么,我必须如何先使DC兼容?
2个回答

22

设备上下文是绘图发生的位置,因此如果您有两个不同的DC,则在两个不同的位置进行绘图。就像一个文件句柄。

设备上下文可以是屏幕上的房地产,也可以是仅驻留在内存中的位图,可能还有其他位置,这些只是我目前能想到的两个。

兼容的上下文是具有相同基础像素组织的上下文,其中指的是每像素比特数,每像素字节数,颜色组织等。内存位图设备上下文可以具有任何组织,但是屏幕上下文将与图形卡上的缓冲区相关联(最终),这将根据模式等具有非常特定的像素组织。

具有兼容上下文意味着在它们之间传输图像数据是有效的,因为几乎不需要转换数据。另一方面,如果您拥有一个256色调色板、8位位图,并尝试将其复制到每个像素具有8位RGBA的屏幕上,那么每个像素都需要大量修改,因此复制不兼容的位图速度非常慢。根据Win32 SDK文档,至少BitBlt()和StretchBlt()“将源颜色格式转换为与目标格式匹配”,因此可以这样做。

请调查CreateCompatibleDC()和CreateCompatibleBitmap()作为创建与已经存在的上下文兼容的绘图上下文的起点。

SelectObject()控制设备上下文中当前处于活动状态的资源。上下文具有当前笔、画刷、字体和位图。这些使得其他GDI调用更简单,因为它们允许您指定较少的参数。例如,在使用TextOut()时无需指定字体,但是如果要更改字体,则可以使用SelectObject()。如果将句柄传递给字体,SelectObject()的返回值是有效的字体的句柄,并且后续操作使用新字体。对于其他类型的资源,如笔刷等,行为相同。


谢谢!那么接下来有几个问题:你能使用不兼容的设备上下文(DC),并且仍然拥有一个可运行的程序(尽管速度较慢)吗?而SelectObject在设备上下文兼容性的概念中起到了什么作用? - Smashery
这对我理解一些我之前不太懂的概念非常有帮助。非常感谢你。 - Yoon5oo

3

(虽然这是一个旧问题,但在谷歌搜索时会显示...)

对于初学者来说,我担心所选答案可能有些误导。
请记住,MFC封装了Win32 API,因此我们需要从Win32级别来看待问题,以更好地理解发生了什么。

要理解为什么存在设备上下文,我们应该了解GDI(图形设备接口)。

那么,为什么存在GDI?——为了实现设备无关性。为了实现这一点,Microsoft制作了图形对象(刷子、笔等),每个对象都包装并抽象了所有设备依赖性问题。

现在我们不必关心不同的设备,这就是GDI的全部意义所在

因此,我们需要在某些数据结构中保存图形对象(刷子、笔、位图等),这就是设备上下文

那么SelectObject函数是什么?
从字面上看,它使DC能够“选择”图形对象。也就是说,我们使用SelectObject将存储在DC中的图形对象句柄更改为我们想要使用的另一个图形对象句柄。

那么什么是兼容设备上下文
兼容设备上下文(=内存设备上下文)使用内存,而不是设备。
来自MSDN(强调我自己的):

为了使应用程序能够将输出放入内存而不是发送到实际设备,请使用特殊的位图操作设备上下文称为内存设备上下文。内存DC使系统将一部分内存视为虚拟设备。它是内存中的位数组,应用程序可以暂时使用它来存储在正常绘图表面上创建的位图的颜色数据。由于位图与设备兼容,因此有时也将内存DC称为兼容设备上下文

内存DC为特定设备存储位图图像。应用程序可以通过调用CreateCompatibleDC函数来创建内存DC。

例如,可以使用兼容DC来减少闪烁,因为我们可以将位图保存在内存中,并在图像更改时仅显示一次,而不是每次都显示。

遵循MSDN文档对新手(包括我)会很有帮助。
从MFC的角度看设备上下文。
从Win32角度看设备上下文,以及以下部分


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接