Interoperability between GDI and GDI+

Overview

Sometimes it is desirable to mix GDI and GDI+ drawing operations in the same code path. When you write code that allows GDI and GDI+ to interoperate, there are a few things to keep in mind. This article outlines these considerations and provides additional information to help you write this type of code successfully.

More information

While it is possible to mix GDI and GDI+ code, certain rules must be followed. In general, you shouldn't interleave GDI and GDI+ calls on one target object. For example, HDCwrapping an Graphicsobject around is fine, but Graphicsyou shouldn't access it directly from GDI until the object is destroyed HDC.

This article describes four main scenarios for interoperability between GDI and GDI+:

  • Using GDI on screen-backed GDI+ graphics objects
  • Using GDI on GDI+ graphics objects backed by bitmaps
  • Using GDI+ on GDI HDC
  • Using GDI+ on GDI memory HBITMAP

Using GDI on screen-backed GDI+ graphics objects

An example of using GDI on a screen-backed GDI+ Graphics object is to draw a "rubber band" or "focus" rectangle. GDI+ does not currently support raster operations (ROPs), so if R2_XORpen operations are required, GDI must be used directly. In this case, you can use Graphics::GetHDC()to get what GDI output points to HDC. GDI+ output should not be HDCattempted on graphics objects with a lifetime (that is, until called Graphics::ReleaseHDC()).

Using GDI on GDI+ Graphics Objects Supported by Bitmaps

When called for a bitmap-backed Graphicsobject instead of a screen Graphics::GetHDC(), a memory is created HDC, and a new one is created HBITMAPand selected into memory HDC. Instead of using the original bitmap's image to initialize this new in-memory bitmap, it uses a marker mode that allows GDI+ to track changes to the bitmap. Any changes made to the memory bitmap by using GDI code will become apparent in the changes to the sentinel mode. When Graphics::ReleaseHDC()called, these changes are copied back to the original bitmap. Since the memory bitmap is not initialized with the bitmap's image, the one obtained this way HDCshould be considered "write-only" and therefore not suitable for use with ROP, whose use requires the ability to read the target, eg R2_XOR. Also, this approach has a high performance cost, as GDI+ has to copy the changes back to the original bitmap.

HDCUsing GDI+ over GDI

It is convenient to use GDI+ on it by using the Graphics constructor HDCthat takes an argument. HDCThe drawing members of the Graphics class can draw on this way HDC. Once a Graphics object is attached , no GDI operations should be performed on it until HDCthe Graphicsobject is destroyed or goes out of scope . HDCIf you HDCneed GDI output on , you can either HDCdestroy the Graphicsobject before using the original, or use Graphics::GetHDC()get the new one HDC, then interoperate according to the rules described earlier in this article, while in GDI+ purposes.

HBITMAPUsing GDI+ on GDI memory

The GDI+ bitmap constructor that takes an HBITMAP as a parameter does not use the actual source HBITMAP as the backing image for the bitmap. Instead, a copy of the image is created in the constructor and changes are not written back to the original bitmap even during the execution of the destructor. New bitmaps can be thought of as "copy-on-create", so in order for GDI+ to grab HBITMAPmemory from GDI and apply these changes to HBITMAPsomething like:

  1. List content
  2. Create one DIBSection.
  3. will DIBSectionselect into memory HDC.
  4. To draw with GDI+ DIBSection, wrap an Graphicsobject around the HDC.
  5. To draw with GDI DIBSection, destroy the Graphicsobject, then use HDC.
  6. Destroy the graphic object, then clear HDCthe DIBSectionoptions in .

Later, if desired, you can DIBSectionconstruct a bitmap from it and use it as Graphics::DrawImage()the source image in .

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326678335&siteId=291194637