GDI和GDI +之间的互操作性

概要

有时候希望在相同的代码路径中混合使用GDI和GDI +绘图操作。当您编写允许GDI和GDI +互操作的代码时,请记住一些注意事项。本文概述了这些注意事项,并提供了其他信息来帮助您成功编写此类代码。

更多信息

虽然可以将GDI和GDI+代码混合使用,但是必须遵守一定的规则。通常,您不应该将GDI和GDI +调用交错在一个目标对象上。例如,围绕HDC包装一个Graphics对象是可以的,但是在Graphics对象被销毁之前,您不应该直接从GDI访问HDC

本文介绍了GDI和GDI +之间互操作性的四个主要场景:

  • 在由屏幕支持的GDI +图形对象上使用GDI
  • 在由位图支持的GDI +图形对象上使用GDI
  • 在GDI HDC上使用GDI +
  • 在GDI内存HBITMAP上使用GDI +

在由屏幕支持的GDI+图形对象上使用GDI

在屏幕支持的GDI+ Graphics对象上使用GDI的一个例子就是绘制一个“橡皮筋”或“焦点”矩形。GDI+目前不支持光栅操作(ROPs),因此如果需要R2_XOR笔操作,则必须直接使用GDI。在这种情况下,您可以使用Graphics::GetHDC()来获取GDI输出指向的HDC。GDI +输出不应该在HDC生命周期的图形对象上进行尝试(也就是直到调用Graphics::ReleaseHDC())。

在位图所支持的GDI+图形对象上使用GDI

当为位图支持的Graphics对象而不是屏幕调用Graphics::GetHDC()时,会创建一个内存HDC,并创建一个新的HBITMAP并将其选入内存HDC中。这个新的内存位图不是使用原始位图的图像进行初始化,而是使用一个标记模式,它允许GDI +跟踪对位图的更改。通过使用GDI代码对内存位图所做的任何更改,都会在对哨兵模式的更改中变得明显。当Graphics::ReleaseHDC()被调用时,这些更改被复制回原始位图。由于内存位图未用位图的图像进行初始化,因此以这种方式获得的HDC应被视为“只写”,因此不适合与ROP一起使用,其使用需要能够读取目标,如R2_XOR。此外,这种方法的性能成本也很高,因为GDI +必须将更改复制回原始位图。

在GDI HDC上使用GDI+

通过使用以HDC为参数的Graphics构造函数,可以方便地在HDC上使用GDI +。Graphics类的绘图成员可以用这种方式在HDC上绘图。一旦Graphics对象被附加到HDC,在Graphics对象被销毁或超出范围之前,不应该在HDC上执行GDI操作。如果在HDC上需要GDI输出,则可以在使用原始HDC之前销毁Graphics对象,或者使用Graphics::GetHDC()获取新的HDC,然后按照本文前面所述的规则进行互操作,同时在GDI +目的。

在GDI内存HBITMAP上使用GDI+

将HBITMAP作为参数的GDI +位图构造函数不使用实际的源HBITMAP作为位图的后备图像。而是在构造函数中创建图像副本,即使在执行析构函数期间,也不会将更改写回原始位图。新的位图可以被认为是“在创建时复制”,因此为了让GDI +从GDI中获取HBITMAP内存,并将这些更改应用于HBITMAP,需要使用类似下面的方法:

  1. 列表内容
  2. 创建一个DIBSection
  3. DIBSection选择到内存HDC中。
  4. 要使用GDI +绘制DIBSection,请围绕HDC包装一个Graphics对象。
  5. 要使用GDI绘制DIBSection,请销毁Graphics对象,然后使用HDC
  6. 销毁图形对象,然后清除HDC中的DIBSection选项。

稍后,如果需要,可以从DIBSection构造一个位图,并将其用作Graphics::DrawImage()中的源图像。

猜你喜欢

转载自blog.csdn.net/caoshiying/article/details/78936230