Graphic device interface (GDI) It's a runnable program , It accepts Windows Drawing request for application ( Manifested as GDI Function call ), And pass them to the corresponding device driver , Finish hardware specific output , Like printer output and screen output .GDI be responsible for Windows All graphics output of , Contains the output pixels on the screen 、 Output hard copies and drawings on the printer Windows The user interface . That is to say Windows Graphics programming for .

One 、GDI Architecture

1、  GDI32.DLL Derived function

GDI Hundreds of them Windows Functions that can be called in a program . Most of these functions are derived from Win32 Subsystem DLL GDI32.DLL The . Form management module UER32.DLL It's using GDI Large users of functions , It USES GDI Function to draw the menu 、 Icon 、 Scroll bar 、 The title bar and the frame of each form . There are some drawing functions from USER32.DLL export , For applications . only Windows2000 GDI32.DLL It's exported 543 Entry points . And DevStudio Together with dumpbin Tool is a simple tool , Can list the functions exported by the module . Here's what happened by dumpbin gdi32.dll /export Part of the production :

 Detailed view :

2、  GDI The function classification

GDI There are so many functions of , So we need a way to Win32 GDI API Function classification of , To understand GDI Structure ,MSDN The library will GDI API Divide into 17 Fields , A clear description of GDI The function of .

(1) Bitmap : Process creation 、 Draw device related bitmaps (DDB)、 Device independent bitmap (DIB)、DIB paragraph 、 A function of pixels and region filling .

(2) A brush : Process creation 、 changes GDI Functions that paint objects .

(3) Tailoring : Functions that handle device context paintable areas .

(4) Color : Palette Management .

(5) Coordinates and transformations : Dealing with mapping patterns 、 Function of equipment coordinate mapping logic and general transformation matrix .

(6) Device context : Create device context , Inquire about 、 Set its properties , And selection GDI Object function .

(7) Fill shapes : A function of drawing a closed area and its circumference .

(8) Fonts and text : Install and enumerate fonts in the system , And use them to draw text strings .

(9) Straight lines and curves : Draw a straight line 、 Functions of elliptic curves and Bezier curves .

(10) Metafile : Handle Windows The function of generating and playing back the format metafile or enhanced metafile .

(11) Multiple display monitors : Functions that agree to use multiple display monitors in a system . These functions are actually derived from uer32.dll Derived .

(12) Drawing and drawing : Functions responsible for drawing message management and drawing area of the form . Some of these functions are actually derived from uer32.dll Derived .

(13) route : Responsible for grouping a series of lines and curves into paths GDI object , And use it to draw functions .

(14) paint brush : Functions that handle line drawing properties .

(15) Printing and printing pools : Responsible for GDI The drawing command is sent to the hard copy device ( Such as line printer and plotter ) And manage these tasks smoothly . The print pool function is created by Win32 Print pool provides , Contains several systems that provide DLL And selling self defined modules .

(16) rectangular :user32.dll Processing provided RECT Function of structure .

(17) Area : Responsible for using the area GDI Object description describes the function of a point set , And operate the point set .

Other undocumented functions . Somewhat GDI Function in DDK Description in , Some are not documented yet, but the system DLL Functions used , Other functions are not practical . Here is a rough classification of these functions :

User mode printer driver .



Other systems DLL Support .

Other undocumented functions .

3、  GDI Object handle

32 Bit GDI The handle is created by 8 An unknown high position 、1 Bit heap object tag 、7 Bit object type information and high 4 Is it 0 Of 16 Bit index . With the help of 7 Bit object type information , Be able to determine the device context 、 Area 、 Bitmap 、 palette 、 typeface 、 A brush 、 Enhanced metafile 、 Brushes and extended brushes .

4、GDI object type

GDI Object table

typedef struct


void * pKernel;

unsigned short nProcess;

unsigned short nCount;

unsigned short nUpper;

unsigned short nType;

void * pUser;


(1) pKernel Point to page pool : It works for everyone GDI object ,pKernel Never empty , And the value is always unique . So it seems that for every GDI Object has a corresponding data structure , This data structure can only be accessed from kernel mode code , Not even from GDI32.DLL Direct access . For objects in different processes , from pKernel There is no obvious distinction between the values of .pKernel The starting address of the object is 0xE1000000, basis 《Inside Windows NT》, The starting address is 0xE1000000 This area is usually called “ Page pool ” The memory heap of a pageable system .

(2)nCount It's a partial selection counter : stay Windows 2000 Next ,nCount It's always zero , That is to say, it is not used . But in Windows NT 4.0 in , some GDI The object uses it . In order to understand nCount The meaning of , We try to select and deselect object handles into one or more device contexts , Observe whether the selection and cancellation can be based on nCount Value change and success .

(3)nProcess bring GDI Handle bound to process : Suppose the program wants to use the GDI Object handle ,Win32 API Calls usually fail .GdiTableCell Medium nProcess Fields are the reason behind this phenomenon . For inventory (stock) object , Such as GetStockObject(BLACK_PEN),nProcess Set to zero . For others created by user processes GDI object ,nProcess Is the process identifier of the creation process .

With this field ,GDI It would be very easy Check whether the current process identifier and GDI Object's nProcess The fields are consistent , The goal is to force the rule that object handles cannot be accessed in another process .

According to Microsoft documents , When the process terminates , All created by the process GDI Object will be released . Suppose you want to know how this is achieved , We have a clue now .GDI Just search GDI Object table and delete the object with the specified process identifier .

(4)nUpper: Check the handle again : We found that GDI Object table entry nUpper The fields are 4 byte GDI A full copy of the upper two bytes of an object handle —— Yes GDI Object handle error checking is a low-cost redundancy check .

(5)nType: Internal object types :nType The lower bytes of are usually the same as HGDIOBJ Is in the 7 Bit type information is also , The high byte is usually zero .

(6)pUser Point to the user mode data structure .

GDI List of object types :

5、GDI Functions are roughly classified

Device context functions ( Such as GetDC、CreateDC、DeleteDC)、 Line drawing function ( Such as LineTo、Polyline、Arc)、 Fill in the drawing function ( Such as Ellipse、FillRect、Pie)、 Drawing properties function ( Such as SetBkColor、SetBkMode、SetTextColor)、 Text 、 Font functions ( Such as TextOut、GetFontData)、 Bitmap function ( Such as SetPixel、BitBlt、StretchBlt)、 Coordinate functions ( Such as DPtoLP、LPtoDP、ScreenToClient、ClientToScreen)、 Mapping function ( Such as SetMapMode、SetWindowExtEx、SetViewportExtEx)、 Metafile functions ( Such as PlayMetaFile、SetWinMetaFileBits)、 Region functions ( Such as FillRgn、FrameRgn、InvertRgn)、 Path function ( Such as BeginPath、EndPath、StrokeAndFillPath)、 Crop function ( Such as SelectClipRgn、SelectClipPath) etc. .

Two 、 Three types of graphic output
Applications can use GDI Create three types of graphic output : Vector output 、 Bitmap graphics output and text output .

Vector graphics output
Vector graphics output refers to the creation of lines and filled graphics , Include a point 、 A straight line 、 curve 、 polygon 、 Drawing of sectors and rectangles .
Bitmap output
The output of bitmap refers to the operation of bitmap function on the data stored in the form of bitmap , It contains the output of various bitmaps and icons .
On the screen, it is shown as the operation on the pixels of several rows and columns , On the printer, it is the output of several rows and columns .
The advantage of bitmap graphics output is very fast , It is a copy operation directly from memory to video memory . The disadvantage is that it requires extra memory space .
Text output
And DOS The output is different in character mode ,Windows It's output graphically .
such , When outputting text , The output position of the text must be calculated in logical coordinates , Rather than image DOS Output text in text behavior unit . This is more than DOS The text output is a little more difficult under .
Outputting text graphically brings great flexibility to text output . Users can call all kinds of GDI function , Create a variety of text output effects , Including bold 、 Italics 、 Set colors, etc .
Windows There is also a TrueType( Photo typeface ).TrueType The font describes the outline of the narrative font with a set of line and curve commands and some parameters .Windows We can adjust the length of the line and the shape of the curve through the parameters , So as to realize the free scaling of the font .

3、 ... and 、 Equipment description table (DC)

stay Windows Environment , The output of each program must be limited to its own form .

GDI Use a simple mechanism to make sure that all programs drawing in the form follow this rule . Such a mechanism is called device description table (DC); When Windows The program is on the screen 、 When drawing on a printer or other device , It doesn't output pixels directly to the device , Instead, the diagram is drawn to the logical meaning represented by the device description table " The display plane " Up . The equipment description table is deeply embedded in Windows A data structure in , It includes GDI All the required description fields about the display plane , Including connected physical devices and various status information .

Gets the device context associated with the form , The application cannot be used CreateDC Create a device context associated with a form , But WIN32 API Provides several functions to get the device context associated with the form , contain :

HDC GetWindowDC(HWND hWnd)


HDC GetDCEx(HWND hWnd,HRGN hrgnClip,DWORD flags)


Use GetDCEx Can replace other functions . such as ,GetDCEx(hWnd,NULL,DCX_WIND|DCX_NORESETATTRS) Can easily replace GetWindowDC(hWnd), and GetDCEx(hWnd,NULL,DCX_NORESETATTRS) Can replace GetDC(hWnd).

The device context class contains CDC And its derived classes CClientDC、CPaintDC、CWindowDC、CMetaFileDC.

CDC、CclientDC、CpaintDC、CwindowDC、CmetaFileDC Meaning and difference
CDC Is the base class of the device context class , In addition to the general form display , It is also used for desktop based full screen rendering and non screen display printer output .CDC Class encapsulates all graphics output functions , Contains vectors 、 Bitmap and text output .
CClientDC( Client area device context ) Output for client area , It encapsulates... In the constructor GetDC(), Encapsulated in the destructor ReleaseDC() function . Generally in response to a non form redraw message ( Such as drawing text when keyboard input 、 Mouse drawing ) It's used in drawing .
CClientDC dc(this);//this Generally point to this form or the current active view
CPaintDC In response to a form redraw message (WM_PAINT) The output of drawing when .CPaintDC Call in constructor BeginPaint() Get device context , Call in destructor EndPaint() Release the device context .EndPaint() In addition to releasing the device context , It's also responsible for clearing... From the message queue WM_PAINT news . therefore , When dealing with redrawing a form , You have to use CPaintDC, otherwise WM_PAINT The message could not be cleared from the message queue , Will cause constant redrawing of the form .CPaintDC It can only be used in WM_PAINT Message processing .
CWindowDC For form client area and non client area ( Contains the form border 、 The title bar 、 control button etc. ) The draw . Unless you want to draw your own borders and button( As some CD Play programs, etc ), Otherwise, you don't use it .
CMetaFileDC It is specially used for drawing metafiles . Metafiles record a set of GDI command , To be able to get through this group GDI Command to rebuild graphics output . Use CMetaFileDC when , All graphics output commands will be automatically recorded to a and CMetaFileDC Related metafiles .

BeginPaint and GetDC The difference

Why? WINDOWS To put forward the concept of invalid area ? This is to speed up . because BeginPaint and EndPaint The device descriptors used will only be drawn in the current invalid area , The painting in the effective area will be filtered by itself , Everybody knows ,WIN GDI My painting speed is relatively slow , So if you can save one pixel, you can save one , Don't be stingy , This can effectively accelerate the speed of painting .
       so BeginPaint、EndPaint It's a comparison “ passive ” Of , Redraw only when the form is new or destroyed .
and GetDC For active rendering , Just where you point , Where it goes . It's drawn without inference , The invalid area has nothing to do with it . The dialog is not covered, not destroyed , It's very healthy , The system doesn't ask it to redraw , But in some cases, developers need to redraw it : For example, a window that changes its appearance regularly , It's time to WM_TIMER Processing code with GetDC. This time BeginPaint、EndPaint Words , Because the invalid area is empty , All painting operations will be filtered out .

because WM_PAINT The priority of the message is very low , such , Because the form object cannot be received in time WM_PAINT Messages affect the user's visual perception of screen objects . To make up for that , Programs can consider using functions UpdateWindows(), It exists in the message queue of the application WM_PAINT In case of news , Force Windows Send it to the form object immediately WM_PAINT news .

// because WM_PAINT It's a very low priority ( Even after the virtual keystroke message , see 《windows Programming core 》 Form message chapter ), It just changes the... In the message structure QS_PAINT sign . So , Let's say we use functions UpdateWindows(), Will directly send One WM_PAINT news , That will call the form handler directly , Than ordinary WM_PAINT Message processing is very fast .

               MessageBox(hwnd,"mouse clicked","message",0);
               HDC hdc;
              TextOut(hdc,0,50," Program ape house ",strlen(" Program ape house "));
case WM_PAINT:
           HDC hDC;
           PAINTSTRUCT ps;// See the difference ?

PAINTSTRUCT ps; This structure is to fill in the coordinates of invalid areas and so on , such BeginPaint You can just draw invalid areas , Improved efficiency .

BeginPaint It can make invalid area effective ,GetDC Don't change the region properties , Invalid or invalid , What works is still effective .
BeginPaint stay WM_PAINT The message uses ,GetDC Can be used in all messages , Usually right and wrong WM_PAINT news .

Four 、 Graphic objects

The graphic object class contains CGdiObject、 paint brush 、 brush 、 typeface 、 Bitmap 、 palette 、 Area, etc .
CGdiObject Is the base class of graphic object class , But this class cannot be used directly by applications .
To use GDI object , You must use its derived class : paint brush 、 brush 、 typeface 、 Bitmap 、 Areas and so on .
Pay attention to two points when using graphic objects :
a. Same as others MFC object ,GDI Object creation is also divided into two steps : First step , Is to define a GDI Examples of drawing object classes ; The second step is to call the creation method of the object to actually create the object .
b. Create objects : Use this object , First call CDC::SelectObject() Select it into the device context , At the same time, save the original settings to a GDI Object pointers, for example pOldObject in . After use , Reuse SelectObject(pOldObject) Restore the original settings .

1、GDI Brushes and CPen class

Windows Draw lines and curves with the brush currently selected in the device description table , And use Rectangle,Ellipse As well as other graphics generating functions draw graphics inlay border . The default brush draws a solid black line that is pixel wide .

Suppose you want to change the way you draw lines , You need to create a GDI paint brush , And by the CDC::SelectOjbect Choose it as the device description table ,MFC Utility class CPen Express GDI paint brush .

How to create a brush

The easiest way to create a brush is to construct a CPen Object and pass the parameters used to define the brush to the object

CPen pen(PS_SOLID,1,RGB(255,0,0));

Another way to create a brush is to construct An uninitialized CPen Object and call CPen::CreatePen:

CPen pen;


The third way to create a brush is to construct an uninitialized CPen object , towards LOGPEN The structure is filled with parameters that describe the characteristics of the brush , And then call CPen::CreatePenIndirect Generating brushes .

CPen pen;


lp.lognStyle = PS_SOLID;// style

lp.lopnWidth.x = 1;// Width

lp.lopnColor = RGB(255,0,0);// Color


As can be seen from the above definition of brush , There are three characteristics to define a brush : style , Width and color . For a description of the brush style, see MSDN.

There are about seven styles of lines , For example, the following :

PS_DASH        Specify a brush to draw the dotted line

PS_DASHDOT    Specify a brush that alternates dotted lines and dots

PS_DASHDOTDOT   Specify a brush that alternates between a dotted line and two points

PS_DOT        Specify a fulcrum line brush

PS_INSIDEFRAME    Specify a brush with a defined shape , The thickness of the line does not extend beyond the boundary of the shape

PS_NULL        Specify an empty brush

PS_SOLID    Create a solid line brush

2、GDI Brushes and CBrush class

By default , be Rectangle,Ellipse And other things CDC Function draws a closed graph filled with white pixels . By creating a GDI Brush and select it into the device description table before drawing , It can change the fill color of graphics .

MFC Of CBrush Class encapsulation GDI A brush .

There are three basic types of brushes : monochrome 、 With shadows and patterns .

Monochrome brush filled monochrome .

The shadow line brush uses a predefined cross line pattern to fill the pattern .

A pattern brush fills a pattern with a bitmap .

Creating a monochrome brush is similar to creating a brush , As you can see below :

CBrush brush(RGB(255,0,0));


CBrush brush;


Create a brush with shaded lines

CBrush brush(HS_DIAGCROSS,RGB(255,0,0));// Shadow index ,COLORREF value


CBrush brush;


HS_DIAGCROSS Is one of six shadow line styles available , For other styles, see MSDN

Be careful :

When filling with a shadow brush , Unless with CDC::SetBkColor Change the current background color of the device description table , Or use CDC::SetBkMode Put the background mode OPAQUE Change to TRANSPARENT, No background padding , otherwise Windows With the default background color ( white ) Fill in the space between the shadow lines .

3、 Fonts vs CFont

Encapsulates the GDI Font object , Users can build a GDI typeface , And use CFont To access it . The font contains the words (FontFamily) 、 style 、 There are three main attributes of size ; Font refers to Song typeface 、 Blackbody, etc ; Style refers to the thickness of the font 、 Whether it is tilted, etc ;FontStyleStrikeout It refers to the strike line style ; Able to use GDI Medium Font class , Construct a font object directly , Such as :Font font(&fontFamily, 12, FontStyleRegular, UnitPoint); In order to keep up with the original GDI Font compatibility ,Font There's a second form of constructor for :Font(HDC hdc, const LOGFONTW *logfont);hdc Is a device environment handle to a form ,logfont It's pointing LOGFONT( Logical Fonts ) Pointer to data structure .

After the logical font is selected to the device context , You can use the following functions to query the details of the physical font it maps , And the measurement information of the current physical font instance .

int GetTextFace(HDC hDC,int nCount,LPSTR lpFaceName);

DWORD GetFontLanguageInfo(HDC hDC);

int GetTextCharSet(HDC hDC);

int GetTextCharSetInfo(HDC hDC,LPFONTSIGNATURES lpSig,DWORD dwFlags);



4、 Bitmap

Encapsulates the GDI Bitmap , It provides member functions to load and manipulate bitmaps .GDI Supports three bitmap types : Device independent bitmap 、 Device related bitmap 、DIB paragraph .

GDI Drawing bitmap processing function

BitBlt            Transfer a bit block composed of pixels in a rectangle from the source device environment to the target device environment

CreateBitmap        Use width 、 Debug and color format to create bitmaps

CreateBitmapIndirect    ditto , It's just that the parameters are different

CreateCompatibleBitmap    Create a bitmap compatible with the device associated with the determined device environment

CreateDIBitmap        Create a device independent bitmap from a device independent bitmap , Set the bit of the bitmap at the same time

CreateDIBSection    Create device independent bitmaps that applications can write directly to , Returns a pointer to where the bitmap is stored

ExtFloodFill        Fill an area of the display plane with the current brush

GetBitmapDimensionEx    Get the size of a bitmap

GetDIBColorTable    Get current DIB A range of colors in the bitmap color table RGB Color value

GetDIBits        Get the bits of the bitmap and copy them into a buffer using a specific format

GetPixel        Gets the... Of the pixel at the current coordinate position RGB Color value

GetStretchBltMode    Get the current scaling mode

LoadBitmap        Load a specific bitmap resource from a template or runnable file

MaskBlt            Merge the color data of the source and destination bitmaps using specific mask and raster operations

PatBlt            Draws a given rectangle using the brush currently selected into the device environment

PlgBlt            The bit block composed of pixel color data in a parallelogram is transferred from the source device environment to the target device environment

SetBitmapDimensionEx    Specify a predetermined size for the bitmap

SetDIBColorTable    Set up current DIB A range of colors in the bitmap color table RGB Color value

SetDIBits        Use the color data from a specific device independent bitmap to set the pixels of the bitmap

SetDIBitsToDevice    Use the color data from a specific device independent bitmap to set the pixels of a specific rectangle in the device associated with the target environment

SetPixel        Set a certain color to the pixels at a specific coordinate position

SetPixelV         To set a color value similar to the color determined for a pixel at a specific coordinate position

SetStretchBltMode    Set bitmap scaling mode in the determined device environment

StretchBlt        Copy the bitmap from the source rectangle to the destination rectangle , And stretch or shrink the bitmap when necessary

StretchDIBits        hold DIB The pixel color data of the rectangular area in the bitmap is copied to the determined target rectangle

5、 palette

encapsulation GDI palette , It holds the color information available to the system , Is the interface between the application and the context of the color output device .

The logical palette associated with a device context can use GetCurrentObject(hDC,OBJ_PAL) Function to get . For a new device context , Its default palette is made up of GetStockObject(DEFAULT_PALETTE) Function returns the inventory default palette .

6、 The output text

GetTextMetrics(); Returns the size of the currently used font , Used for font size calculation .

SetTextColor(int nColor); Set the foreground .

SetBkColor(int nColor); Set background color .

TextOut: Text output .

TabbedTextOut: like TextOut Display the text as well , Be able to use the tab key Tab.

ExtTextOut: Displays the text in the specified rectangle . This function can be used to delete the text beyond the rectangle , Fill the rectangle with the text background , Adjust character spacing .

DrawText: Display the text in the specified rectangle , Be able to use the tab key Tab. Adjust the left alignment of the text when formatting the rectangle 、 Right aligned or centered ; It can also be broken in a word to fit rectangular boundaries .

GDI+ Text output in has only one function :DrawString
DrawString(const WCHAR *string, INT length, const Font *font, const Rect &layoutRect, const StringFormat *stringFormat, const Brush *brush);
DrawString(const WCHAR *string, INT length, const Font *font, const PointF &origin, const Brush *brush);
DrawString(const WCHAR *string, INT length, const Font *font, const PointF &origin, const StringFormat *stringFormat, const Brush *brush);
brush Used to specify a brush , This brush can be SolidBrush and HatchBrush, It can also be TextureBrush( Texture brush ), Even gradient brushes . StringFormat Class to control these format properties , The format properties of text usually contain alignment 、 Character spacing and text adjustment, etc .

7、 Draw a dot

SetPixel: Draw a dot in the specified color at the specified coordinates .

8、 Draw line

MoveToEx Move the starting point of the line to the specified coordinates ,LineTo Draw a straight line from the beginning to the end . The linetype used is specified by the current brush .

9、 Draw an arc

Arc(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4);

10、 Closed graphics

rectangular :Rectangle

Rounded rectangle :RoundRect

The ellipse :Ellipse

Pie chart :Pie

Closed polygons :Polygon

11、 Other drawing functions

FillRect: Fill the rectangle with the specified color without drawing a border .

FloodFill: With a given color , Use the currently selected brush to fill the area where the bottom of the display is surrounded by a border , Such as the filling of polygon area .

ExtFloodFill: With a given color , Use the current brush to fill the area where the surface is surrounded by a border , Users can selectively fill an area composed of specified colors .

InvertRect: In a rectangular area, the reflection has color .

12、 Metafile

For recording and playback GDI Function call . First, through CMetaFileDC:Create To create new objects , Suppose there is a file name , Then save it to a file , If not, it's built in memory . After completion , use Close() close .
To be able to call PlayMetaFile() Put metafiles back and forth . It's enough CopyMetaFile() Save the file to disk . When the metafile ends , use DeleteMetaFile() Remove... From memory .
There are also enhanced metafiles .
CMetaFileDC    dc;
BOOL bCreate=dc.CeeateEnblanced(pDC,”metaest,wmf/0”,0,vectosd/0 this is l/0/0”);
if(!bCreated) return;
( Detailed drawing content ……)
// Close file , And returns the file handle
HENHMETAFILE    hemf=dc.CloseEnhanced();
// Play the file
// When files are no longer needed

13、 Print

Print correlation functions

int StartDoc(HDC hDC,CONST DOCINFO *lpdi);// tell GDI Start a new print job

int StartPage(HDC hDC);// Print task new page starts

int EndPage(HDC hDC);// The printing task ends on one page

int EndDoc(HDC hDC);// end StartDoc Start the print task

HDC ResetDC(HDC hDC,const DEVMODE *lpInitData);// Change the printing device context setting information

int AbortDoc(HDC hDC);// It is used to end the printing task abnormally

int SetAbortProc(HDC hdc,ABORTPROC lpAbortProc);// Set the callback routine ,GDI Periodically use it to check or discard printing tasks

14、 Device description table property change / Set function

When using CDC When the output function is drawing on the screen , Some features of the output are not specified in the function call process ( Use the system default property drawing ), But we can get or get new set properties through the device description table itself .

MFC Provides functions to get and set these properties , We can use these functions to easily change the default properties when drawing .

such as :

CDC::SetTextColor// Set text color

CDC::GetTextColor// Get the text color

CDC::SetBkColor// Set the background color

CDC::SetBkMode// Set background mode

CDC::SetMapMode// Set the mapping mode

CDC::CDC::SetROP2// Set drawing mode

CDC::MoveTo// The current position

CDCL::SelectObject// The current brush , The current brush , The current font

( Suppose you want to ignore the background color , You can set the background to "Transparent",dc.SetBkMode(TRANSPARENT);)

SelectObject function

Most commonly used to define device description table properties CDC The function is SelectObject.

such as :

CPen pen(PS_SOLID,2,RGB(0,192,0));

CPen* pOldPen = dc->SelectObject(&pen);// Put the new CDC Object is selected into the device description table , Keep the old at the same time CDC object



Drawing mode and SetROP2

GDI When outputting pixels to a logical plane , It doesn't just output pixel colors . contrary , It can combine the color of the output pixel with that of the target pixel through a series of Boolean operations . The logical relationship used in it is determined by the current drawing mode of the device description table . Use CDC::SetROP2(Set Raster Operation To) You can change the drawing mode . The default drawing mode is R2_COPYPEN, It will copy pixels to the display plane .

Mapping mode

Default mapping mode

Fixed scale mapping mode

Programmable mapping patterns

In short , The mapping schema is an attribute of the device description table , It is used to determine the conversion mode from logical coordinate value to equipment coordinate value .

The default mapping mode

The default mapping mode makes MM_TEXT, It makes... In pixels .X Axial left is positive ,Y Axis down is positive . The default coordinate origin is in the upper left corner .

Fixed scale mapping mode


Their default coordinate origin is in the upper left corner . The difference is that the physical size of each logical unit is different .

The logical units used are respectively 0.1 mm ,0.01 mm ,0.01 Inch ,0.001 Inch ,1/1440 Inch (0.0007 Inch ).

Variable scale mapping mode ( Programmable mapping patterns )

For variable scale mapping mode, users can customize the size represented by a logical unit , It can be of any size .

It can also make the size change with the environment . Yes MM_ISOTROPIC,MM_ANISOTROPIC These two mapping patterns .

The size of its logical unit is equal to the ratio of the scope of the view to the scope of the form .

The difference between the two is that the former requires X Axis and Y The unit of measurement of the axis must be the same , The latter has no such limitation .

Programmable mapping patterns

MM_ISOTROPIC and MM_ANISOTROPIC It is up to the user to decide how to convert the logical coordinate value to the device coordinate value ,

That is, it is up to the user to decide how many equipment units a logical unit is equal to (cm,mm,m etc. ), Rather than by Windows decision .

So it's called the programmable mapping pattern ;

MM_ISOTROPIC and MM_ANISOTROPIC Mapping mode is most often used to adjust the output size of the drawing according to the window size .

MM_ISOTROPIC and MM_ANISOTROPIC Differences in mapping patterns

In the former X Direction and Y Directions have the same scaling factor , The latter two directions can be scaled individually ;

Examples :

CRect rect;



dc.SetWindowExt(500,500);// Set the scope of the form , Increase the logical size of the form to 500 Company ×500 Company

dc.SetViewportExt(rect.Width(),rect.Height());// Set the range of the view


notes : The size of the form is calculated in logical units , The size of the viewport is measured in device units or pixels .

In particular

MM_TEXT Is the default mapping mode , Its origin is in the upper left corner of the form ,X The positive direction of the axis is right ,Y The positive direction of the axis is down ,

And a logical unit corresponds to a pixel in device coordinates

Other mapping patterns have the same origin , just Y The axis will flip so that the positive direction is up , And the logical units are scaled to the actual distance size , Not the number of pixels .

It should be noted that , Use metric mapping mode ( Non default mapping mode ) when , To make the output visible ,Y The coordinates have to be negative .

such as :

dc.Rectangle(0,0,200,100);// Drawing in default mode

dc.SetMapMode(MM_LOENGLISH);// Change the mapping pattern

dc.Rectangle(0,0,200,-100);// mapping

Transmit to CDC The output function is the logical coordinate value .

The device coordinate value refers to the corresponding pixel position in the form .

GDI Summary of mapping patterns

GDI Summary of coordinate transformation

Pay attention to problems in programming :

1、  Device context 5 A large area : Clipping area 、 Metaregions , System area ,API Area ,RAO Area . For a function BeginPaint、GetDC perhaps CreateDC In the context of the returned device , The value of its clipping area is NULL, The value of the clipping area is NULL, That means there is no clipping area . No clipping area means that all the graphics in the system area atmosphere will be displayed , Instead of not showing .

2、  Inventory objects (StcokObject) It's pre created by the operating system , And shared for all processes executed in the system . After the application has used the inventory object , There's no need to delete their handles . But calling functions DeleteObject It's very safe to handle inventory object handles , Function as DeleteObject When you don't do anything , It will return TRUE value .

3、  SetDIBitsToDevice Function and StretchDIBits Functions are all display DIB image , The difference is SetDIBitsToDevice Functions require very little memory ;SetDIBitsToDevice Don't handle stretching , You need to write your own stretching algorithm ;StretchDIBits Can pass SetStretchBltMode/GetStretchBltMode To control the stretch mode of each device context .

4、 stay DIB and DDB Copy bitmaps between ,GDI function :SetDIBits/GetDIBits;

Access the original DDB Pixel array :LONG GetBitmapBits(HBITMAP hBmp,LONG cbBuffer,LPVOID lpvBits); How do I know what size of buffer to allocate ? Set the size to 0 And the buffer pointer is NULL Under the circumstances ,GetBitmapBits Function returns the required buffer size .

LONG SetBitmapBits(HBITMAP hBmp,LONG cBytes,LPVOID lpBits);

DDB Show ,GDI function :BitBlt,StretchBlt

5、SetTextColor、SetBkColor Function to set the new color , After use , You need to set the old color back ( adopt SetTextColor、SetBkColor). This operation is similar to SelectObject be similar .

typeface :CreateFont、CreateFontIndirect and CreateFontIndirectEx establish GDI Logical font object , Return the handle to the caller . adopt GDI Object handle , You can use GetObject Get the... That defines the logical font LOGFONT or ENUMLOGFONTEX structure . And others GDI object , When you don't need a logical font object , application DeleteObject Delete the .

6、GDI Memory leak problem

To write GDI Exception occurred after executing the program many times , In addition to the well-known memory leaks ,gdi Resource leakage is also a very direct cause . The prevention of gdi Resource leakage measures .

1)Create Coming out gdi object , Be sure to use DeleteObject To release , The release order is first Create After the release of , after Create Release first .
there Create It starts with it gdi function , example ,CreateDIBitmap,CreateFont wait , At the end of the day DeleteObject To release .

2)Create Coming out dc Use DeleteDC To release ,Get You need to use ReleaseDC Release .

3) Make sure to release DC When DC Each of gdi Objects are not created by you ; Make sure that gdi Objects are not released by anything dc Select use .
If we want to use gdi Function drawing , The right steps should be, for example, the following :
a. Create a memory compatible dc(CreateCompatibleDC)
b. Create a memory compatible bitmap(CreateCompatibleBitmap)
c. Association created memory compatible dc and bitmap(SelectObject)
d. mapping
e.BitBlt To the end dc On
f. Disconnect memory compatibility dc and bitmap relation (SelectObject)
g. Destroy memory compatibility bitmap
h. Destroy memory compatibility dc
because SelectObject In the selection of a new gdi Object will return an original gdi object ( If it works ), So it's necessary to take steps c Save the return value when you save it , Steps in f It is used as an entry parameter . also , step g And steps h In fact, the order can be arbitrary , Because the two of them are not related at the moment , But for structural clarity , I suggest following " First Create After the release of , after Create Release first " The principle of .
About the steps f, It could be controversial , Because even if you omit this step , step g And steps h It still seems to be able to return a successful value . But it may not actually work , At least boundschecker I'll report a mistake , The error message is basically , Releasing dc There are also non default gdi object , Releasing gdi I said this when I was talking to someone gdi The object is also represented by a dc In the use of . therefore , I suggest keeping the steps f.

4) About 98 Next use CreateCompatibleBitmap
according to msdn That's what I'm saying , created size No more than 16m. Is that the case ? no ~! From the results of my own tests (win98se-sc), This value is in the 2044*2043 and 2044*2044 Between , However , Later in another 98 This value on the system doesn't work either , Later, I just gave the upper limit to 2000*2000. Very lucky , So far, there is no problem , But I can't guarantee that the number is right . Another point , If one of the width or height exceeds 32768, Even if the other value is 1, It also fails to create , Those who are interested can do a test by themselves . Suppose you want to make sure that this function is in 98 I'll always be successful , Try the following code :
float factor = 10.f;
while(!bitmap.CreateCompatibleBitmap(&dc ,nWidth*factor ,nHeight*factor))
   factor -= 0.01f; 
This at least ensures that the width and height are proportional

5) About using... On a printer BitBlt
Sometimes in memory compatibility dc There's a picture in it , But in the use of BitBlt When you are young, you fail . This is the time , First confirm that the created memory is compatible dc and bitmap Is it using a printer dc, Assuming the confirmation is correct , Or run BitBlt Failure , that 80% Maybe it's memory compatible bitmap It's too big , Please try again in the following way :
Create another memory compatible dc2 Compatible with a smaller memory biimap2, Probably 1000*1000 Well , This is how I use it , And then put dc It's divided into pieces (1000*1000), Put each piece BitBlt To dc2 above , Again from dc2 Inside BitBlt To print dc On . Some people may have such doubts : Then why not just put dc The contents of it are divided into several times BitBlt To the printer ? Is there a difference ? The answer is yes , hypothesis dc Inside bitmap Too big , Even if you want to BitBlt One 10*10 All of these areas will fail on the printer .


InvalidateRect Makes the specified area of the form invalid ,Invalidate Make all areas of the form invalid ,Validate Make all areas of the form valid . Suppose the form has an invalid region , be Windows Hair WM_PAINT, Parameter to specify the maximum rectangle of the invalid area , The program responds to this message , use BeginPaint Make the invalid area the clipping area , The following painting activities will not go beyond this cutting area , It's up to EndPaint Make invalid area valid , At this time WM_PAINT Be cleared of .MFC Provides... For form classes WM_PAINT Message handling .MFC Provides... For form classes WM_PAINT Message handling functions for OnPaint,OnPaint Responsible for redrawing the form . There are some exceptions to the view class , In the view class OnPaint Called in the function OnDraw function , The actual redrawing is done by OnDraw Come on, over . Parameters bErase by TRUE when , The background in the redraw area will be erased , otherwise , The background will remain the same .

UpdateWindow( ) The function of is to redraw the form immediately . call Invalidate After waiting for the function, the form will not be redrawn immediately , This is because WM_PAINT The priority of the message is very low , It needs to wait for other messages in the message queue to be sent before it can be processed . call UpdateWindow Function can make WM_PAINT Is sent directly to the target form , This causes the form to be redrawn immediately .UpdateWindow Just send... To the form WM_PAINT news , Infer before sending GetUpdateRect(hWnd,NULL,TRUE) See if there's a customer area to draw , Suppose there is no , Then don't send WM_PAINT.

Invalidate Add one to the message queue WM_PAINT news , The invalid area is the whole customer area .

UpdateWindow Send one directly WM_PAINT news , The scope of its invalid area is in the message queue WM_PAINT news ( There's only one at most ) Invalid area of .

The effect is very obvious , When calling Invalidate after , The screen doesn't have to be updated immediately , because WM_PAINT The message doesn't have to be at the head of the queue , And call UpdateWindow Can make WM_PAINT The message immediately runs , Bypassing the message queue .

8、 Double buffer drawing

The main thing is to establish memory compatibility DC And memory compatible bitmaps , For example, the following :

HDC hDC = ::GetDC(m_hWnd);

hFrceDC = CreateCompatibleDC(hDC); // Memory compatible DC

hFrceBmp = CreateCompatibleBitmap(hDC, WinWidth, WinHeight); // Memory compatible bitmaps

SelectObject(hFrceDC, hFrceBmp); // Check in memory compatibility DC

::ReleaseDC(m_hWnd, hDC);

In the future, all GDI operation , example LineTo etc. , It's all about hFrceDC, When it comes to refreshing :

void CST_CurveCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)


BitBlt(pdc->m_hDC, rcInvalid.left,, rcInvalid.Width(), rcInvalid.Height(), hFrceDC, rcInvalid.left,, SRCCOPY);



That's why double buffering is GDI The most important skill in programming . So no matter how complicated your drawing is , The screen won't blink any more , The complexity of drawing just takes up CPU Just a little more .

9、 Refresh the background question

Whether to refresh the background is very important , Some novices use the above double buffering on the dialog , Then tell me , Or flashing ! That's because of the background , Because of the use of BitBlt Drawing things , stay windows It seems , It's not a form , It's not like a button, because button It's a form , therefore windows In the background , It will be subtracted from the refresh area button The area occupied , So back to the point , On the dialog BitBlt When , Suppose the bitmap display occupies the entire client area of the dialog , It's simple. It's just , Direct response WM_ERASEBKGND news , Then return TRUE:

BOOL CXXX::OnEraseBkgnd(CDC* pDC)


return TRUE;


hypothesis BitBlt It's not going to take up the entire customer base , So I'm very sorry , It's a bit of a problem , You're going to generate a new one BitBlt The area of the display area , Then on DC function SelectClipRgn function , Please be there. MSDN Search inside “Region Functions”, You can use most of the functions in it , It's mainly about creating areas , Operation area ( For example, ask for AND, seek OR, seek DIFF etc. ).

10、GDI The number of function calls is very important , After refreshing the background with double buffering and elimination , The flickering problem can be regarded as conquered , We'll talk about reducing CPU The question of utilization .GDI Operation is wasteful CPU Resources , For example, the call of frequency GDI function , It's bound to waste CPU resources , This is especially the character printing operation , So GDI Provide PolyTextOut function , Call it once , Can output arbitrary number of characters , Each one sets its output position independently , Let me give you an example of the use of this function , For example, you are drawing a scale value on a coordinate , So the best function is just . Similar to this function is PolylineTo、Polyline、PolyPolyline、Polygon、PolyPolygon Such as function .

11、 Regional refresh technology , It is to divide customers into several regions ( It's usually a rectangle , Fast ), Detailed how to divide , There is no definite number of points , Theoretically , Places that may need to be refreshed separately , It's divided into one area , Whenever this area needs to be refreshed , Just paint this area , and BitBlt Go to the screen . In detail , There should be a refresh function for each area ( Or a switch One of the statements case term ), This function runs GDI operation , When this area needs to be refreshed , Call this function to draw something new into a memory compatible file DC On , And then let the rectangle fail , that windows At the right time , call OnDraw( Or similar functions ), stay OnDraw Inside , Direct use BitBlt For invalid areas ( It's the rectangular area mentioned above ) Just map it .

12、 call CreateCompatibleBitmap establish DDB Bitmap . This function creates a bitmap using the paging memory of the system kernel , This is a rare resource .CreateDIBSection The advantages of , It uses virtual memory to create bitmaps . In this way, the number of instances to execute the program is limited to pagefile And disk space . It's just CreateDIBSection Than CreateCompatibleBitmap It's hard to call some .

References :《Windows Graphic programming 》

GDI More articles on programming summary

  1. GDI+ Programming summary

    GDI+(Graphics Device Interface Plus Graphics device interface plus ) yes Windows XP and Windows Server 2003 Subsystem of the operating system , It's also .NET An important part of the framework , negative ...

  2. GDI+ Programming instructions and summary

    Original address : GDI+(Graphics Device Interface Plus Graphics device interface plus ) ...

  3. Linux Multithreading programming summary

     Linux Multithreading programming summary Some time ago, due to the problem of starting a topic, I have been delayed in doing Linux Progress , I've forgotten what I learned before , Very upset to say , Now take a moment to make a small section of what you have learned before . The content of this article is mainly summarized in <Linux Program ...

  4. GDI Programming

    Graphic device interface (GDI) It's an executable program , It accepts Windows Drawing requests for applications ( Manifested as GDI Function call ), And pass them to the corresponding device driver , Complete hardware specific output , Like printer output and screen output .GDI be responsible for Wind ...

  5. Windows Store Gesture programming summary

    Windows Store Gesture programming summary Recently completed a Windows Store The gesture operation page above . Here I summarize my experience and experience , I hope to share and discuss with you . First , We should correct a mistake , stay Windo ...

  6. MFC Control GDI Programming

    MFC Control GDI Programming 1. Learning content 1. Understand the common GDI Function drawing . 2. Use a common brush . 2. Commonly used GDI Function drawing The top is our usual GDI Function .  Draw line   rectangular .  And the circle   wait . 2.1  Line code ...

  7. [2019BUAA Soft assistant ] Pair programming - Summary

    [2019BUAA Soft assistant ] Pair programming - Summary One . Scoring rules Blog Blog is 50 points in total Serial number requirement The score is 1 At the beginning of the article Github Project address 1 2 Before starting to implement the program , In the following PSP The form records that you expect to be in ...

  8. C# GDI+ Analysis of programming startAngle and sweepAngle

    With DrawArc For example , It has a constructor in the form of public void DrawArc(Pen pen, Rectangle rect, float startAngle, float sweepA ...

  9. An article makes you understand completely WinForm GDI Programming fundamentals

    One  GDI Programming principle GDI(Graphics Device Interface, Graphic device interface ), Mainly responsible for Windows Information exchange between the system and the drawing program , Deal with all Windows The graphic output of the program . GDI Common use of ...

Random recommendation

  1. Dapper Study - Dapper The basic usage of ( Two ) - stored procedure / function

    The last one seems to have introduced less user-defined functions and stored procedures , Because these two functions can also be implemented in the way of query , This one will be supplemented by One . Create and call custom functions (mysql Of ) Delimiter $$ drop function ...

  2. Riot - Than Facebook React Lighter weight UI library

    Riot It's a similar Facebook React User interface library for , Only 3.5KB, Very light weight . Support IE8+ Custom tags for browsers , fictitious DOM, Grammatical simplicity .Riot It provides the front-end developers with the ability to get rid of React and P ...

  3. SharePoint 2013 To configure HTTPS(SSL)

    1. Open... On the server IIS, Find the server certificate , Here's the picture : 2. Enter the server certificate , Click on the operation on the right “ Create a self-signed certificate ”, Here's the picture : 3. Specify a friendly name for the certificate , Storage selects individuals , Here's the picture : 4. After I hit ok , Server certificate page , ...

  4. Get the device 、APP Some information

    Get some information about the device : UIDevice *device = [UIDevice currentDevice]; @property(nonatomic,readonly,strong) NSStrin ...

  5. obtain json A simple way to format strings

    Sometimes you need to find some Json Format string , You can open any web page to enter debugging mode , And then look network Related access information , I can get it . such as : While taking notes , After clicking save , There will be requests , And then there's a corresponding corresponding , ren ...

  6. Dubbo Source analysis series --- Extension point loading

    Extension point configuration : Appointment : In the extension class jar In bag , Place the extension point profile :META-INF/dubbo/ The interface is fully qualified , The content is : Configuration name = Extension implementation class fully qualified name , Multiple implementation classes are separated by line breaks .( Excerpt from dubbo file ) Example : ...

  7. 【 Development technology 】json

    json(JavaScript Object Notation) JavaScript Object symbol is a structured and lightweight data transmission format , Many occasions replace XML File format JSON Format check :http://www.b ...

  8. destruct Problems with operating files in destructors

    These days, we need to add a function of recording operation logs to the background , But the project has been developed, it is impossible to change the previous code , So what's the quickest way ? Project used ThinkPHP3.23 , To facilitate access control , The structure of background controller is : Ordinary controller ex ...

  9. Detailed explanation - Make the root file system , And use yaffs,jffs,nfs Mount system (2)

    1. install mkyaffsimage, mkyaffs2image command ( Used to make yaffs file system ) The first order is for Flash Small page 512B, The second is for Flash Big page 2KB Download the compressed file first  yaffs_so ...

  10. c++ In depth discussion of copy function and memory allocation

    stay c++ When we explore some behaviors of a class , The copy function, that is, the copy constructor, is used in the following scenarios : Object as an argument to a function , It's passed to a function in the form of value passing . Object as the return value of the function , Returns from a function as a value Use one object to start another ...