Windows form. Net Framework Drawing Technology,. net drawing
When writing a typical Windows form program,Drawing forms and controls, Effect and other operations do not need to be taken into consideration. Why? Because. NetFramework, developers can drag a series of controls to the form, write some simple code associated with the event, and then press F5 In the IDE, a complete Form program is born! All controls draw their own, and the size and scaling of the form or control can be adjusted freely. It is often used here, and the control effect should be noted. For games, custom chart controls, and Screen Saver Programming, the programmer needs to write additional code to respond to the Paint event.
This article targets those Windows forms developers and helps them use simple plotting techniques during application preparation. First, we will discuss some basic plotting concepts. Who is responsible for drawing? How does a Windows form program know when to draw? Where exactly are the drawing codes placed? Next, we will introduce the dual Buffer technology for Image Rendering. You will see how it works and how to use a method to achieve the alternation between the cache and the actually displayed image. Finally, we will discuss "smart invalid areas". Actually, we just re-paint or clear invalid parts of the application form to speed up the display and response of the program. We hope that these concepts and technologies will guide readers through this article and help them develop Windows Forms programs more quickly and effectively.
Windows Forms use the GDI + Image Engine. All the drawing code in this article involves using the managed. Net Framework to manipulate and use the Windows GDI + Image Engine.
Although this article is used for basic form drawing operations, it also provides fast, effective techniques and methods that help improve program performance. Therefore, before reading this article, we recommend that you have a basic understanding of the. Net Framework, including Windows form event processing, simple GDI + objects such as Line, Pen, and Brush. Familiar with Visual Basic. Net or C # programming language.
Concept
Windows applications are drawn by themselves. When a form is "not clean", that is, the size of the form is changed, or some of the forms are overwritten by other programs, or restored from the minimized state, the program will receive the information to be drawn. In Windows, this "not clean" status is called "invalid (Invalidated)". We understand that re-painting is required, when the Windows form program needs to redraw the form, it obtains the drawn information from the Windows message queue. This information is encapsulated by the. Net Framework and then transmitted to the PaintBackground and painting events of the form. In the above events, you can properly write the code specifically for drawing.
A simple drawing example is as follows:
The following is a reference clip: Using System; Using System. Drawing; Using System. Windows. Forms; Public class BasicX: Form { Public BasicX () { InitializeComponent (); } Private void BasicX_Paint (object sender, PaintEventArgs e) { Graphics g = e. Graphics; Pen p = new Pen (Color. Red ); Int width = ClientRectangle. Width; Int height = ClientRectangle. Height; G. DrawLine (p, 0, 0, width, height ); G. DrawLine (p, 0, height, width, 0 ); P. Dispose (); } Private void InitializeComponent () { This. SetStyle (ControlStyles. ResizeRedraw, true ); This. ClientSize = new System. Drawing. Size (300,300 ); This. Text = "BasicX "; This. Paint + = new PaintEventHandler (this. BasicX_Paint ); } [System. STAThreadAttribute ()] Public static void Main () { Application. Run (new BasicX ()); } } |
The above code is divided into two basic steps to create a sample program. First, the InitializeComponent method contains some attribute settings and the processing process of adding a form Paint event. Note that the style of the control is also set in the method. Setting the style of the control is also an effective way to customize Windows Forms and control behaviors. For example: the "ResizeRedraw" attribute of the control indicates that the form must be completely re-painted when the size of the form changes. That is to say, the customer area of the entire form must always be re-painted. The "customer region" of a form refers to all the form regions except the title bar and border. You can perform an interesting experiment to cancel the property of the control and then run the program. We can clearly see why this property is often set, because the invalid area after the form size is adjusted is not repainted at all.
Well, we need to pay attention to the BasicX_Paint method. As mentioned earlier, the Paint event is activated when the program needs to be repainted, the program form uses the Paint event to respond to the system message to be repainted. The BasicX_Paint method call requires an object sender and a PaintEventArgs type variable, the PaintEventArgs class instance or variable e encapsulates two important data. The first is the Graphics object of the form, this object indicates the surface of a form that can be drawn, also known as a canvas, used to draw lines, text, and images. The second data is ClipRectangle. This Rectangle object indicates an invalid rectangular range on the form, that is, the area where the form needs to be repainted. Remember, after the ResizeRedDraw of the form is set, the size of the ClipRectangle is equal to the size of the entire customer area of the form, or the part of the cut area covered by other program forms. We will describe the usefulness of some cut areas in more detail in the intelligent re-painting chapter.
Double buffer plot Technology
The dual-buffer technology allows the program to draw more quickly and smoothly, effectively reducing the image flickering during painting. The basic principle of this technology is to first draw an image to a canvas in the memory. Once all the painting operations are completed, push the canvas in the memory to the form or control surface to display it. After this operation, the program can make the user feel faster and more beautiful.
The example program provided below can clarify the concept and implementation method of dual buffer. This example has complete functions and can be used in practical applications. Later in this chapter, we will also mention that this technology should work with some property settings of controls to achieve better results.
Run the SpiderWeb sample program to learn the benefits of the dual-buffer plot technology. After the program starts and runs, adjust the window size. You will find that the efficiency of using this drawing algorithm is not high, and a large amount of flashes appear during the resizing process.
Not having dual Buffer technologySpiderWebSample program
Looking at the source code of the program, you will find that after the program Paint event is activated, the line is drawn by calling the LineDrawRoutine method. The LineDrawRoutine method has two parameters. The first is that the Graphics object is used to draw lines, and the second is the Pen object of the drawing tool used to draw lines. The code is quite simple, a loop statement, LINEFREQ constant, etc. The program is underlined from the lower left of the form surface to the upper right. Please note that the program uses floating point numbers to calculate the drawing position on the form. The advantage of this is that when the size of the form changes, the location data will be more accurate.
The following is a reference clip: Private void LineDrawRoutine (Graphics g, Pen p) { Float width = ClientRectangle. Width; Float height = ClientRectangle. Height; Float xDelta = width/LINEFREQ; Float yDelta = height/LINEFREQ; For (int I = 0; I <LINEFREQ; I ++) { G. DrawLine (p, 0, height-(yDelta * I), xDelta * I, 0 ); } } |
Write a simple code for responding to the Paint event SpiderWeb_Paint. As mentioned earlier, the Graphics object is the drawing surface of the form extracted from the PaintEventArgs object of the Paint event parameter. This Graphics object is passed together with the newly created Pen object to the LineDrawRoutine method to draw a line like a spider. The resources occupied by the Graphics object and the Pen object are released after the Graphics object and the Pen object are used, then the entire painting operation is complete.
The following is a reference clip: Private void SpiderWeb_Paint (object sender, PaintEventArgs e) { Graphics g = e. Graphics; Pen redPen = new Pen (Color. Red ); LineDrawRoutine (g, redPen ); RedPen. Dispose (); G. Dispose (); } |
So what changes can be made to implement a simple dual Buffer technology for the SpiderWeb program above? In fact, the principle is quite simple, that is, the painting operation that should be painted on the form surface should be converted to the bitmap in the memory first, and LineDrawRoutine will execute the same spider network Painting Operation to the canvas hidden in the memory, call Graphics after drawing. the DrawImage method pushes the hidden content on the canvas to the surface of the form for display. Finally, a high-performance drawing form program is completed with some minor changes.
Compare the differences between the following dual-buffer plot events and the simple plot events described above:
The following is a reference clip: Private void SpiderWeb_DblBuff_Paint (object sender, PaintEventArgs e) { Graphics g = e. Graphics; Pen bluePen = new Pen (Color. Blue ); Bitmap localBitmap = new Bitmap (ClientRectangle. Width, ClientRectangle. Height ); Graphics bitmapGraphics = Graphics. FromImage (localBitmap ); LineDrawRoutine (bitmapGraphics, bluePen ); // Pushes bitmap processed in memory to the foreground and displays G. DrawImage (localBitmap, 0, 0 ); BitmapGraphics. Dispose (); BluePen. Dispose (); LocalBitmap. Dispose (); G. Dispose (); } |
The above Sample Code creates a memory bitmap object, which is equal to the size of the form's customer region (that is, the drawing surface) by calling Graphics. fromImage transfers the reference of the bitmap in the memory to the Graphics object. That is to say, all subsequent operations on the Graphics object are actually performed on the bitmap in the memory, this operation is equivalent to copying the pointer of a bitmap object to a Graphics object in C ++. The two objects use the same memory address. The Graphics object represents a canvas at the back of the screen, which plays a crucial role in the dual Buffer technology. All line drawing operations are targeted at bitmap objects in the memory. Next, call the DrawImage method to copy the bitmap to the form, the lines of the spider web are immediately displayed on the drawing surface of the form without blinking.
This series of operations is not particularly effective after completion, because we first premise that the style of the control is also a way to define the behavior of the Windows form program, to better implement dual buffer, you must set the Opaque attribute of the Control. This attribute indicates that the form is not responsible for drawing its own in the background. In other words, if this attribute is set, you must add the relevant code for the clear and redraw operations. SpiderWeb programs with dual-buffer versions use the above settings to perform well when re-painting is required. The form surface is cleared with its own background color, which reduces the appearance of flashes.
The following is a reference clip: Public SpiderWeb_DblBuff () { SetStyle (ControlStyles. ResizeRedraw | ControlStyles. Opaque, true ); } Private void SpiderWeb_DblBuff_Paint (object sender, PaintEventArgs e) { Bitmap localBitmap = new Bitmap (ClientRectangle. Width, ClientRectangle. Height ); Graphics bitmapGraphics = Graphics. FromImage (localBitmap ); BitmapGraphics. Clear (BackColor ); LineDrawRoutine (bitmapGraphics, bluePen ); } |
What are the results? Image Rendering is much smoother. From the memory, we pushed the spider's lines to the front end to show that there was no blinking at all, but we paused a little while, first trim the bitmap in the memory and then display it, you can add a line of code to make the line look flat.
The following is a reference clip: BitmapGraphics. SmoothingMode = SmoothingMode. AntiAlias; |
After assigning the bitmap object in the memory to Graphics, we place this line of code. Every line we draw on the canvas uses anti-aliasing to make the uneven lines more flat.
SpiderWeb_DblBuff sample programs that have dual Buffer technology and use the AntiAliasing attribute
After a simple dual-buffer application is completed, there are two issues that need to be clarified to the reader. Some controls in. Net, such as Button, PictureBox, Label, and PropertyGrid, have made good use of this technology! By default, these controls automatically enable the dual Buffer technology. You can set the "DoubleBuffer" attribute to implement the dual Buffer technology. Therefore, if you use PictureBox to draw spider web, it will be more efficient and make the program easier.
The dual-buffer technology we discuss here is neither completely optimized, but has no negative impact. Dual Buffer technology is an important way to reduce the flash of Windows Forms during painting, but it does consume a lot of memory because it will use double memory space: the image displayed by the application and the image in memory at the rear of the screen. Each time a Paint event is activated, bitmap objects are dynamically created, which consumes a lot of memory. The control with the dual Buffer technology performs better after the DoubleBuffer attribute is used.
The DIB (device-independent Bitmap) object of GDI + is used to implement memory buffering outside the image. controls with a dual buffer mechanism can make good use of this bitmap object. DIB is the underlying Win32 object for efficient screen painting. Similarly, it is worth noting that the first version of GDI + is only related to hardware acceleration and some simple functions can be used directly. Due to such restrictions, screen rendering methods, such as anti-sawtooth and translucent, are executed quite slowly. Although the dual buffer mechanism consumes some memory, its use undoubtedly enhances the execution performance of the program.
Intelligent re-painting, you need to consider before drawing
"Smart reuse" means that programmers should understand that only the invalid areas in the program should be repainted, repainting the invalid Regions corresponding to the Regions object can improve the rendering performance. By using the Regions object, you can exclude or draw only some areas of the control and form to achieve better performance. Let's take a look at the BasicClip sample program. This program uses the ClipRectangle object stored in the PaintEventArgs object, which we mentioned earlier, the Paint event is activated whenever the program size changes. The BasicClip example program fills the cut rectangular area with red and blue colors. After adjusting the size of the form several times with different speeds, you will find that the drawn rectangular area is actually an invalid area of the form (including the area greater than the size of the original form and the area smaller). The example program's Paint Event code is as follows:
The following is a reference clip: Private void BasicClip_Paint (object sender, PaintEventArgs e) { Graphics g = e. Graphics; If (currentBrush. Color = Color. Red) CurrentBrush. Color = Color. Blue; Else CurrentBrush. Color = Color. Red; G. FillRectangle (currentBrush, e. ClipRectangle ); G. Dispose (); } |
The sole purpose of this example is to demonstrate how to draw images only for some areas.
The color rectangle area in the BasicClip example program is the invalid area at the bottom and right of the form.
Regions is an object used to define Windows forms or control areas. Regions obtained after the form size is adjusted is the smallest area of the window weight painting. When the program needs to draw only the special areas of interest, so that drawing a smaller area will make the program run faster.
To better demonstrate Regions usage, see the TextCliping sample program. This program reloads the OnPaintBackground and OnPaint methods, and directly reloads these methods to ensure that the Code is called before other painting operations, and the rendering of custom controls is more effective. For clarity, the sample program provides a Setup method that defines a global Graphics object.
The following is a reference clip: Private void Setup () { GraphicsPath textPath = new GraphicsPath (); TextPath. AddString (displayString, FontFamily. GenericSerif, 0, 75, new Point (10, 50), new StringFormat ()); TextRegion = new Region (textPath ); BackgroundBrush = new TextureBrush (new Bitmap ("CoffeeBeanSmall.jpg "), WrapMode. Tile ); ForegroundBrush = new SolidBrush (Color. Red ); } |
The Setup method above first defines an empty GraphicsPath object variable textPath. The next line of the string "Windows Forms" is added to this path and a Region is created around this outline. In this way, a Region that is drawn on the surface of the form in the string contour area is created. Finally, the Setup method creates a form with the material brush as the background and the solid color brush as the foreground.
The following is a reference clip: Protected override void OnPaintBackground (PaintEventArgs e) { Base. OnPaintBackground (e ); Graphics bgGraphics = e. Graphics; BgGraphics. SetClip (textRegion, CombineMode. Exclude ); BgGraphics. FillRectangle (backgroundBrush, e. ClipRectangle ); BgGraphics. Dispose (); } |
The OnPaintBackground method defined above calls the base class method immediately, which ensures that all the code drawn at the underlying layer can be executed. Next, obtain the Graphics object from PaintEventArgs, and define the cut area of the Graphics object as the textRegion object. By specifying the CombineMode. Exclude parameter, it is clear that the textRegion area is not drawn no matter where the Graphics object is drawn or how it is drawn.
The following is a reference clip: Protected override void OnPaint (PaintEventArgs e) { Base. OnPaint (e ); Graphics fgGraphics = e. Graphics; FgGraphics. FillRegion (foregroundBrush, textRegion ); FgGraphics. Dispose (); } |
Finally, the OnPaint event is responsible for accurately drawing strings. You can easily call the FillRegion method of Graphics. Use the specified foreground brushes foregroundBrush and textRegion, and only the area is drawn. As a result, the Windows form program does "think" about how to draw before running it.
The TextClipping example program uses the Windows Forms string defined by Region. This allows the program to avoid an area during painting.
You can use the appropriate combination of area and smart re-painting to write the drawing code that runs fast and does not cause flashes, and save memory consumption compared to the use of dual-buffer painting separately.
Conclusion
If your program is determined to plot, several techniques can be used to enhance the rendering performance. Make sure that setting control properties and appropriate Paint event processing are the beginning of robust programming. After balancing the advantages and disadvantages, you can use the dual Buffer technology to produce a very "visual protection" result. Finally, it is helpful to think about which customer regions or Region needs to be drawn before actually drawing.
It is hoped that this article will help readers better understand the. net Framework rendering technology and its application.
Use c ++/CLI and Net Framework class library to develop a Windows form application with certain technical content
Oh, this requirement is interesting!
It is actually the DLL compiled by calling CLI with. NET.
In fact,. NET is very simple. It is nothing more than using DllImport to get the DLL and call the next entry function.
The key is the DLL on the CLI. You need to call the win api display window. It may also involve some of the basics of MFC.
C # What is the difference between the "public control" in the toolbar and "All windows Forms "?
All windows Forms display all controls and components.
Public controls are only a small part
If you cannot find the public control, it is generally in all windows Forms.
One is a large set and the other is a small subset.