了解设备上下文
作为 MFC 的相对新手,我经常看到设备上下文 (DC)。我隐约明白这与绘画有关,但我能找到的任何地方都没有很好地解释具体细节。创建“兼容的设备上下文”意味着什么,为什么它很重要? SelectObject 的作用是什么?我必须首先如何使 DC 兼容?
As a relative newcomer to MFC, I see Device Contexts (DCs) a lot. I vaguely understand that it's something to do with drawing, but the specifics are not very well explained anywhere that I can find. What does creating a "compatible Device Context" mean, and why is it important? What does SelectObject do, and how must I make a DC compatible first?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
设备上下文只是进行绘制的地方,因此如果您有两个不同的 DC,则您将在两个不同的位置进行绘制。有点像文件句柄。
设备上下文可以指屏幕上的实际空间,也可以指驻留在内存中的位图,也可能是其他地方,这些只是我目前能想到的两个。
兼容上下文是具有相同底层像素组织的上下文,这意味着每个像素的位数、每个像素的字节数、颜色组织等等。内存位图设备上下文可以具有您想要的任何组织,但您的屏幕上下文将(最终)与显卡上的缓冲区相关,这将(取决于模式等)具有非常特定的像素组织。
具有兼容的上下文意味着在它们之间传输图像数据的效率很高,因为几乎不需要或不需要数据转换。在另一个极端,如果您有 256 色调色板、8 位图,并且尝试将其传输到每个像素具有 8 位 RGBA 的屏幕,则每个最后一个像素在复制时都需要大量调整,因此复制不兼容位图要慢得多。根据Win32 SDK文档,至少BitBlt()和StretchBlt()“转换源颜色格式以匹配目标格式”,所以可以做到。
研究 CreateCompatibleDC() 和 CreateCompatibleBitmap() 作为如何创建与现有绘图上下文兼容的绘图上下文的起点。
SelectObject() 控制设备上下文中当前处于活动状态的资源。上下文具有当前笔、画笔、字体和位图。这些允许您指定更少的参数,从而使许多其他 GDI 调用变得更简单。例如,使用 TextOut() 时不必指定字体,但如果您想更改字体,则需要使用 SelectObject()。如果向 SelectObject() 提供字体句柄,则返回value 是有效字体的句柄,后续操作将使用新字体。其他类型的资源(钢笔、画笔等)的行为是相同的。
A Device Context is just a place that drawing occurs, so if you have two different DC's, you're drawing in two different places. Kind of like a file handle.
Device Contexts can refer to real-estate on screen, or to bitmaps that just reside in memory, and probably other places, too, those are just the two I can think of at the moment.
Compatible contexts are ones that have the same underlying pixel organization, by which is meant number of bits per pixel, bytes per pixel, color organization and so forth. Memory bitmap device contexts can have any organization you want, but your screen contexts are going to be related (eventually) to buffers on your graphics card, which will (depending on mode, etc) have a very specific pixel organization.
Having compatible contexts means its efficient to transfer image data between them, because little or no translation of the data is required. At the other extreme, if you have a 256 color palette, 8 bit map and you try to blit it to a screen that has 8 bits each of RGBA per pixel, every last pixel will require significant massaging as it is copied and so copying incompatible bitmaps is very much slower. According to the Win32 SDK documentation, at least BitBlt() and StretchBlt() "convert the source color format to match the destination format", so it can be done.
Investigate CreateCompatibleDC() and CreateCompatibleBitmap() as starting points for how to create drawing contexts that are compatible with already existing ones.
SelectObject() controls which resources are currently active within the device context. A context has a current pen, brush, font, and bitmap. These make a lot of the other GDI calls simpler by allowing you to specifiy fewer parameters. For instance, you don't have to specify the font when you use TextOut(), but if you want to change the font, that's where SelectObject() comes in. If you feed SelectObject() a handle to a font, the return value is a handle to the font that was in effect, and subsequent operations use the new font. Behavior is the same for the other kinds of resources, pens, brushes, etc.
(老问题,但在谷歌搜索时会显示...)
我担心,对于初学者来说,所选的答案可能会有点误导。
请记住,MFC 包装了 Win32 API,因此我们需要从 Win32 层面来看,才能更好地理解发生了什么。
要了解为什么存在设备上下文,我们应该了解GDI(图形设备接口)。
那么,为什么会有GDI呢? - 为了设备独立性。为了实现这一目标,微软创建了图形对象(画笔、笔……),每个图形对象都包装并抽象了所有设备依赖性问题。
现在我们不必关心不同的设备,这就是 GDI 的全部意义。
因此,我们需要将图形对象(画笔、笔、位图……)保存在某种数据结构中,这就是设备上下文。
那么什么是SelectObject函数?
从字面上看,它使 DC 能够“选择”图形对象。即,我们使用SelectObject将DC中存储的图形对象句柄更改为我们想要使用的另一个图形对象句柄。
那么什么是兼容设备上下文?
兼容设备上下文(=内存设备上下文)使用内存,而不是设备。
来自 MSDN (强调我的):
例如,可以使用兼容的 DC(内存 DC)来减少“闪烁”(一次又一次地部分绘制)并加快绘制速度,因为我们可以在内存中的位图上绘制所有内容并在显示器上显示一次 /em>,每次显示器刷新(例如 60Hz)时不显示。这种方法称为“双缓冲”。
遵循 MSDN 文档会对新手(包括我)有所帮助。
设备上下文,从 MFC 角度来看。
从 Win32 的角度来看设备上下文,以及 < a href="https://learn.microsoft.com/en-us/windows/win32/gdi/about-device-contexts" rel="nofollow noreferrer">以下部分。
(Old question but this is shown when googling...)
I'm afraid that, for beginners, the selected answer can be a bit misleading.
Please keep in mind that MFC wraps the Win32 API, so we need to see from the Win32 level, to better understand what's going on.
To understand why there is Device Context, we should understand GDI(Graphics Device Interface).
Then, why GDI exist? - For device independence. To achieve this, Microsoft made Graphic Objects (Brush, Pen, ...), each of which wraps and abstracts all the device dependency issues.
Now we don't have to care about different devices, and that's the whole point of GDI.
So we need to hold Graphic Objects(Brush, Pen, Bitmap,...) in some data structure, and that's the Device Context.
Then what is a SelectObject function?
Literally, it enables DC to "select" a Graphic Object. I.e, we use SelectObject to change a graphic object handle stored in the DC to another graphic object handle that we want to use.
Then what is a compatible device context?
compatible device context(=memory device context) uses memory, rather than devices.
From MSDN (emphasis mine):
Compatible DC (memory DC) can be used, for example, to reduce "flickering"(draw partially again and again) and draw faster because we can draw everything on the bitmap in the memory and show it on the monitor once, not showing every time the monitor refreshes(eg 60Hz). This method is called "double buffering".
Following MSDN docs would be helpful to newbies (including me).
Device Contexts, from the MFC viewpoint.
Device Contexts, from the Win32 viewpoint, and this following section.