First, CPen Brush class
1. Brush Style:
1) All the line functions are drawn using the brush specified by the CPen class, and the default is a solid line of 1 pixels wide and black;
2) to make the defined brush take effect (that is, you can draw a line) you must first create a CPen brush object, and then select it into the device environment DC China can take effect, but if nothing is set can also be directly with the DC line, because the DC initialization when there is a default brush, is the above 1 pixels wide, black solid line;
3) The style of the brush is determined by three characteristics, i.e. style, width, and color:
I. Style (int npenstyle): There are some main styles, such as solid line, dash, dotted line, dot dash, transparent, this feature is specified by macro Ps_, that is, the pen style abbreviation, mainly has these several commonly used
Ps_solid: Solid Line
Ps_dot: Dot Line
Ps_dash: Dash
Ps_dashdot: Dot Dash
Ps_dashdotdot: A dash of two dots
Ps_null: Transparent Line
Ps_insideframe: Along the border
. Note: the borders within the border are the whole border lines of the body are close to the inner edge of the border, rather than the Ps_insideframe line in the border inside and outside the width of the same, for example, draw a circle, diameter of 5 pixels, the style of the Circle line is 2 pixels wide line, the Edge Each side of the line is 1 pixels wide border lines, so the total outside diameter of 12 pixels, but if it is the style of the inner edge, the outside of the line is not border lines of pixels, and the inside has a 2-pixel width of the border line, so the outer diameter is still 10 pixels;
II. Width (int nwidth): The width is given by logical units, and the logical units depend on the current mapping mode, where Ps_solid, Ps_null, ps_insideframe can specify any logical width, but the rest (Ps_dash, Ps_dot, Ps_d Ashdot, Ps_dashdotdot) must specify 1 units wide, and if any other value is specified, it will be automatically corrected to 1 logical width in the background.
. Note: If you specify a width of 0, any style will be corrected to 1 by default;
III. Color (COLORREF crcolor): defined by the RGB macro, three components are red, green, blue, respectively;
2. Create, modify, and select brushes:
1) You can use the CPen constructor:
I. Parameterless constructor: CPen (), same as the default brush for DC initialization, solid line, 1 pixels wide, black;
Ii. parametric constructors: CPen (int npenstyle, int nwidth, COLORREF crcolor);
2) Modify Brush: If you want to modify the style of the brush, you can use the CPen member function CreatePen or createpenindirect to regenerate a new brush
I. Createpen:bool CreatePen (int npenstyle, int nwidth, COLORREF crcolor), you can see that the parameter and the argument constructor are identical, except that the return value is BOOL, which returns true if the creation is successful;
II. Createpenindirect: This method requires creating a "logical brush" and then using the logical brush to create the actual brush. The so-called logical brush and the actual brush is different in that, once the real brush is created will create a brush in memory resources, the resource is directly related to the underlying GDI, the capacity is larger, and the logical brush contains only the Brush style field Structure, there are only the parameters of the brush (just a few int), so if you need to use a variety of different styles of brushes in the program (a very large number), you should create a variety of different styles of logical brushes, but only create an actual brush, you can use different logic to draw Pen to redefine the actual brush, saving memory resources and improving program efficiency.
A. Logical brush structure Body:
typedef struct TAGLOGPEN {
int lopnstyle;
Point lopnwidth;//where lopnwidth only domain X represents the width of the brush and the Y field is not used, be aware.
colorref lopncolor;
} Logpen, *plogpen
// B. Createpenindirect:bool createpenindirect (Lplogpen lplogpen);
C. Creating the actual brush with a logical brush:
CPen pen;
Logpen lopn;
Lopn.lopnstyle = Ps_dot;
lopn.lopnwidth.x = 1;
Lopn.lopncolor = RGB (255, 0, 0);
Pen. Createpenindirect (&LOPN);
3) The main difference between creating a brush with a constructor and a Create series function: The constructor throws a cresourceexception (that is, a memory critical lack exception) in the case of a creation failure, and the Create series returns False when the creation fails, so the latter is more robust So
It is recommended to use the parameterless constructor to create a default brush with little memory before creating the actual brush with the Create series function.
4) Select the brush:
I. To make the brush effective, you must first select the created CPen object into the DC device environment;
II. Use SelectObject to select the drawing object into the environment device DC: cpen* SelectObject (cpen* ppen), which returns the handle of the old brush before updating;
Iii. MFC will selectobject overloaded several versions, there are CBrush and other types of drawing objects, here is just a brush;
Iv. cpen* Poldpen = DC. SelectObject (Pnewpen); Second, CBrush painting brush class
1. The use of paint brushes and the creation of different styles of brushes:
1) The brush is used to fill the inner area of the closed graph, such as ellipse, rectangle, etc.
2) Painting brush three styles:
I. Monochrome: Fill monochrome, create only the color parameters can be given;
II. Hatching: Hatch is filled with hatching, you need to specify the color of the shadow line and the background color of the line, background mode;
III. Bitmap padding: Use bitmaps (customizable) to populate enclosed areas;
3) Create a monochrome brush:
I. Using overloaded single-parameter constructors: CBrush (COLORREF crcolor);
II. Use the simple and straightforward "create monochrome brush" member function: BOOL cbrush::createsolidbrush (Colorref crcolor); This approach suggests creating an empty brush, which is created with the parameterless constructor, and Then use this function to create a monochrome brush;
4) Create a shaded line brush:
I. Using the overloaded two-parameter constructor: CBrush (int nIndex, COLORREF crcolor), where the first parameter specifies the style of the hatch line, and the second parameter specifies the color of the hatch line;
II. Use the simple and straightforward "create shaded line Brush" member function: BOOL cbrush::createhatchbrush (int nIndex, COLORREF crcolor), the parameter meaning is the same as the former;
III. But as I said earlier, you also need to specify the background color and background mode:
. Note : The so-called "background" in GDI:
A. Background color: Determines the fill color of these places: the background color behind the text character, the dot line, and the color of the dotted gap, and the color of the area between the shadow lines of the shadow brush;
B. Background mode: Only two modes, one is transparent, the other is opaque, if it is transparent, then the background color will not work, its color will be the same as the entire client area background color, if it is opaque, you need to specify the background color;
C. Background color and background mode is not subordinate to text, brush, brush, but a separate GDI object, set the background color using DC SetBkColor, set the background using DC SetBkMode;
D. Setbkcolor:colorref SetBkColor (COLORREF crcolor); Returns the background color before the update;
E. setbkmode:int setbkmode (int nbkmode); There are two modes of nbkmode, one is opaque, that is, non-transparent, the second is transparent, that is, transparent;
Iv. nindex Specifies the style of the hatch line:
Hs_bdiagonal: Diagonal Type
Hs_fdiagonal: Main diagonal type
Hs_horizontal: Horizontal Line Style
Hs_vertical: Vertical Line
Hs_cross: Horizontal Vertical crossover type
Hs_diagcross: Oblique Cross Type
. Where Hs_ is the abbreviation of hatch style;
2. Create the actual brush using the logic brush:
1) as in the previous logic brush, mainly used to create a variety of different styles of brush (a lot of) to save memory resources;
2) Logical brush structure definition:
typedef struct TAGLOGBRUSH {
UINT lbstyle;
COLORREF Lbcolor;
LONG lbhatch;
} Logpen, *lplogpen;
A. Where lbstyle is the finger brush style, that is, monochrome or shadow line, with the beginning of the bs_, namely the brush style abbreviation, mainly has these kinds:
Bs_solid: Monochrome
Bs_hatched: Shadow Linetype
Bs_hollow/bs_null: Both equivalent, are transparent, equivalent to SetBkMode (TRANSPARENT), but set to Bs_hollow than direct SetBkMode more Well, because the former is only a brush, and the latter is global, it also affects other GDI objects.
B. lbcolor represents the color of a monochrome and, if it is a shadow line, specifies the color of the hatching;
C. Lbhatch is the Hs_-style of the hatched line, if the Lbstyle is specified as monochrome or transparent, then this parameter will be ignored, this parameter is only valid in the Shadow line style;
3. Create and select the complete process demo for the brush:
With the brush selected and the brushes selected, only SelectObject is overloaded: cbrush* SelectObject (cbrush* pbrush);
CBrush Brush;
Brush. Createhatchbrush (Hs_diagcross, RGB (255, 0, 0));
cbrush* Broldbrush = DC. SelectObject (&brush);
COLORREF Croldcolor = DC. SetBkColor (RGB (0, 0, 255));
int noldbkmode = DC. SetBkMode (OPAQUE);
4. Draw the origin of the brush:
1) Problem background: Fill the inside of the rectangle with the shadow line will encounter a problem, that is, sometimes the shadow line from the top left corner, sometimes not, it seems like nothing, but sometimes do some animation effect when there is a big problem, that is, the rectangle is moving, but the position of the inner Shadow Line remains motionless, which brings bad effect , so you need to let the inner Shadow line move along with the rectangle, and it is best to have a hatched line just out of the upper-left corner of the rectangle;
2) In fact, the brush fill pattern on the screen is in an 8x8 pixel block, can be seen as the original screen is covered with such a small piece, and the screen appears a rectangle needs such a shadow fill, so that only the rectangle inside the pattern, the outside of the rectangle is not displayed, and the 8x 8 The upper left corner of the small square, is the default just to shoot a shadow line of the brush origin, if the brush origin just can coincide with the upper left corner of the rectangle, then there is just a shadow line from the upper left corner of the rectangle shot out, which is what we want, but if not artificially set, the brush origin is always in the upper left corner of the 8x8 pixel block;
3) Set the location of the paint brush Origin:
I. Call First: BOOL cgdiobject::unrealizeobject ();
A. The return value indicates the success or not of the call;
B. The function is to reset the brush and color palette, where the brush is our concern here, after calling this function, it means that the brush's origin can be moved;
C.cbrush such as GDI object types are directly or indirectly inherited from CGdiObject, so you can use this function with confidence;
II. Then use: CPoint cdc::setbrushorg (int x, int y);
A. Also accepts CPoint and point type parameters, the return value is the position of the brush origin before the update;
III. Select the brush that modifies the origin into the device description table to use it normally; 4) Example:
Suppose a start works in logical coordinates
CPoint point (x1, y1);//The logical coordinate DC in the upper-left corner of the rectangle
. LPTODP (&point); Get equipment coordinates, note: The brush origin is set according to the device coordinates
point.x%= 8;//Get the upper left corner of the rectangle in the 8x8 pixel block coordinates
POINT.Y%= 8;
Brush. Urealizeobject ();
dc. Setbrushorg (point); Sets the brush origin and the upper-left corner of the rectangle to coincide with the
DC. Selectobjet (&brush); The DC can be used normally when the device description table is selected
. Rectangle (x1, y1, x2, y2);