Tpaintbox is a graphical control that inherits from Tgraphiccontrol, and only chats a few functions and properties, mainly the canvas and the paint function, all here:
Tpaintbox = Class (Tgraphiccontrol) private fonpaint:tnotifyevent; protected procedure Paint; override; Public Constructor Create (aowner:tcomponent); override; Property Canvas; End
Summary: Such a simple class has also been made a control, and placed in the system column, the visible control, although simple, but it should be very useful, that is no other function, it provides a key canvas properties and a paint function, Its main purpose is to provide a painting function, the programmer can take it to draw anything can, in the functional design can be said to be very simple and clear (off-topic, but also can be based on this painting function, made of multi-functional control, such as to make and tlabel the same function, etc., because it is too simple, Almost identical to a tgraphiccontrol).
As for its constructor, there is almost nothing to do but add a csreplicatable style. So the main is to look at its paint; functions, the code is as follows:
Procedure Tpaintbox.paint;begin Canvas.font: = Font; Canvas.Brush.Color: = Color; If csdesigning in Componentstate then with the Canvas do begin Pen.style: = Psdash; Brush.style: = bsclear; Rectangle (0, 0, Width, Height); End; If Assigned (fonpaint) then fonpaint (self); end;
It can be found that it only does three things:
1. Get ready to work, set the canvas's font and paint brush colors
2. Draw a dashed box in the design period to let the programmer know its size
3. Invoking Programmer Events
Looks like this tpaintbox. If you don't add programmer events, it's not going to do anything yourself, so do the experiment, put a PaintBox1 on the empty form, add a piece of code:
Procedure Tform1.paintbox1paint (sender:tobject); var t:trect;begin t.top:=0; t.left:=0; t.right:=100; t.bottom:=100; PaintBox1.Canvas.FillRect (t); Fills the color of the area with the color of the brush end;
Run, no effect. The reason is that its default color is Clbtnface, which is exactly the same as the color of Form1, so the operation doesn't look like an effect.
At this time, through the IDE to change the color of the Form1 to Clappworkspace, and then run or do not see the effect, the screen is gray, because the IDE through the code in the VCL aware of the Form1 color changes, the whole process is as follows:
The first step, Form1 as a tcontrol, is called when the color is set: Procedure Tcontrol.setcolor (value:tcolor); begin if Fcolor <> Value then Begi N Fcolor: = Value; Simply set the class member data (not the Class property, which executes the related function) Fparentcolor: = False; Perform (cm_colorchanged, 0, 0); Form1 One-stage entry for color change end;end;//The second step, execute three cmcolorchanged functions procedure tcustomform.cmcolorchanged (Var message:tmessage) in succession; Begin inherited; If Fcanvas <> nil then FCanvas.Brush.Color: = Color; End;procedure twincontrol.cmcolorchanged (var message:tmessage); Begin inherited; This invalidates the display of your Own (FORM1), and once the new drawing message arrives, the Fbrush.color can be redrawn based on the new content: = Fcolor; Then set the class member data paint brush color notifycontrols (cm_parentcolorchanged); Notifies all child controls, Form1 as their parent control, that their color has changed end;procedure tcontrol.cmcolorchanged (var message:tmessage); Begin Invalidate; virtual function, so it depends on who called this function. In this case, the current control is Form1, so the twincontrol.invalidate is called, and the process is no longer expanded. end;//The third step, the Form1 own display content after the failure, but also to continue to notify all child controls: procedure Twincontrol.notifycontrols (Msg:word); var message:tmessage; Begin message.msg: = MSG; Message.wparam: = 0; MessagE.lparam: = 0; Message.result: = 0; Broadcast (message); End;procedure Twincontrol.broadcast (Var message); var i:integer;begin for I: = 0 to ControlCount-1 Do begin controls[i]. WindowProc (Tmessage (Message)); Notifies the child controls and invokes their related message functions, if any, if any, if tmessage (message). Result <> 0 Then Exit; end;end;//Fourth Step, the result PaintBox1 as a child control, also really received this message, and make the corresponding: procedure tcontrol.cmparentcolorchanged (Var message:tmessage); Same as SetColor but doesn ' t set Parentbackground to False procedure Setparentcolor (Value:tcolor); Begin if Fcolor <> value then BEGIN fcolor: = value; Change your color to the color of the parent control fparentcolor: = False; Good because the VCL library is non-thread-safe, so that a fake, temporarily no longer accept the new color change message, but once the color changes are complete, will be changed back immediately. Perform (cm_colorchanged, 0, 0); Send a message call function, make own color change on the spot effective end; End;begin//Note that there is no change in the result value of the message during this message processing, so the message for loop in the broadcast function continues to execute if Fparentcolor then//default state is so begin if Mes Sage.wparam <> 0 Then Setparentcolor (tcolor (Message.lparam)) Else Setparentcolor (fparent.fColor); Call the child function, set the parent control's color to its own color, note that the class function with the same name is not called fparentcolor: = True; Before the execution of the message to make the color effective, immediately change back to end;end;//fifth, the last sentence before the PaintBox1 execution perform (cm_colorchanged, 0, 0); equivalent to execution: procedure Tcontrol.cmcolorchanged (var message:tmessage); Begin Invalidate; The InvalidateControl function is called to invalidate its display, end;//sixth step is not expanded here, wm_paint the code of the programmer is executed indirectly through the Paintbox1.paint function after the message comes.
Summary: Once the Form1 color is changed in the IDE, the IDE will first invalidate the Form1 display. The Form1.FBrush.Color is then set to a new value, and the last message notifies the child control, and all the graphics child controls respond by default (if its parentcolor is set to true), because the VCL frame is set in the message broadcast and there is a cm in the Tcontrol _parentcolorchanged the corresponding message function, all the image child controls and the win control are inherited, so the whole process is inevitable. Once the child control responds, set its own color, i.e. paintbox1.fcolor: = Value, and then send the message to invalidate itself. This results in a change in the color of the parent control and a change in the color of the child controls. If you manually write code to change the parent control color, it is the same execution process.
But through the IDE to change the color of the Form1 to Clappworkspace, it will invoke the entire process, so that the PaintBox1 color automatically changed to Form1 consistent with the clappworkspace, but also in the IDE on the spot to take effect, So running the program still does not see the effect.
So manually change the color of the PaintBox1 to another color?
Procedure Tform1.button4click (sender:tobject); begin Paintbox1.canvas.brush.color:=clgreen; Paintbox1.invalidate; End
Pay attention to the invalidate; statement, even if the previous sentence set canvas paint brush color function, want to be effective on the spot, you have to add this sentence, otherwise you have to minimize the Form1 and then maximize to make it fail once, to see the corresponding effect, not trouble. Unfortunately, even with this sentence, it is still not possible. There is no way, inexplicable surprise under the only careful study of its paint source code, and then found Canvas.Brush.Color: = Color, that is, PaintBox1 using the control property color overrides its canvas brush color, It seems that the problem is here. Then change the test statement to:
Procedure Tform1.button4click (sender:tobject); begin Paintbox1.color:=clred;end;
This time even do not have to write invalidate statement can have effect, the reason and set Form1.color on the spot has the effect of the reason is consistent, the whole process can refer to here:
Http://www.cnblogs.com/findumars/p/4117783.html
Also note that The three colors of Paintbox1.color and PaintBox1.Brush.Color and PaintBox1.Canvas.Brush.Color are essentially three, with Paintbox1.color having the highest precedence, and also by the SET function corresponding to the class property directly Work. The relationship between them is only an opportunity to interact with each other, it also has to be done by the creator of the VCL handwriting code to work, the relationship can refer to the above post.
Tpaintbox's Past Life