Introduction
Graphic Display plays an important role in the development of industrial control systems. Compared with many dedicated configuration software, they have powerful graphics systems that can be configured with very beautiful systems. Today, many industrial graphics Development kits have to be paid, and many beautiful controls, such as instruments, can only look at the figure and sigh. A friend of mine made a monitoring system for a pumping station a few days ago. Due to the lack of related controls, he studied the programming methods of these controls and used some programming materials on the network for reference, completed some controls that can be used for industrial control system development.
Body
In the previous two articles, I have used examples to explain how to use dual-buffer technology to compile a disc meter. For details, see
Industrial Control Software graphical interface-Controls (Circular instrument controls) http://www.vchelp.net/itbookreview/view_paper.asp? Paper_id = 1671
Industrial Control Software graphical interface-Controls (Circular instrument controls two) http://www.vchelp.net/itbookreview/view_paper.asp? Paper_id = 1672
The writing principle of the actual instrument can be roughly the same. The difference is that different methods are used to compile the background or pointer or display real-time values. In industrial control programs, if a variety of simulation instruments are used to simulate the scene, the man-machine interface will be more friendly. On the basis of the above, we will continue to compile a new type of instrument and apply it to the field of industrial control.
We still follow the writing steps to create a class that integrates cstatic. Then start wm_paint and other messages. Then, the background, pointer, and real-time value of the instrument are displayed in the middle of onpaint. We use the overlay method for background writing, pointer and text display. The Method of Drawing overlay or text overlay is actually very simple. As described in the previous article, we use the same area or offset area to draw the same content. Different colors are used for drawing, because of the order of drawing, we can produce visual three-dimensional superposition effect, see the specific implementation of industrial control software graphical interface-control implementation (Circular instrument control two) http://www.vchelp.net/itbookreview/view_paper.asp? Paper_id = 1672
The core code is as follows:
Draw a gauge background
// Draw the gauge background
Void cpanelmeter: drawmeterbackground (CDC * PDC, crect & rect)
{
Cbrush m_brushback, pbackbrush, * poldbrush;
PDC-> setbkcolor (m_backcolor );
M_brushback.createsolidbrush (m_backcolor );
Poldbrush = (cbrush *) PDC-> SelectObject (& m_brushback );
PDC-> fillrect (rect, & m_brushback); // draw the background
PDC-> rectangle (rect); // draw a border
PDC-> SelectObject (poldbrush );
M_brushback.deleteobject ();
Int yhalf = rect. Bottom-8;
Float fa = (float) rect. Width ()/2;
Float Fb = (float) rect. Height ()-8;
Cfont fscalefont;
Fscalefont. createfont (10, 12,
0,
0,
Fw_normal,
False,
False,
False,
Default_charset,
Out_default_precis,
Clip_default_precis,
Default_quality,
Default_pitch | ff_dontcare,
"Arial ");
If (m_dvalidvaluemin> = 0)
{
Cbrush brshgreen;
Cbrush brshred;
Brshgreen. createsolidbrush (RGB (0,192, 0 ));
Brshred. createsolidbrush (RGB (230,100,100 ));
Float fstartangle = (float) (m_dvalidvaluemin-m_dminvalue)/(float) (m_dmaxvalue-m_dminvalue) * 3.14f;
Float fendangle = (float) (m_dvalidvaluemax-m_dminvalue)/(float) (m_dmaxvalue-m_dminvalue) * 3.14f;
PDC-> moveTo (rect. Left, yhalf );
PDC-> lineto (rect. Left + 20, yhalf );
PDC-> moveTo (rect. Right-1, yhalf );
PDC-> lineto (rect. Right-22, yhalf );
PDC-> moveTo (rect. Left, yhalf );
For (float f = 0; F <= 3.14; F + = 0.01f)
{
PDC-> lineto (rect. width ()/2-(INT) (FA * Cos (F) + rect. left, yhalf-(INT) (FB * sin (F) + rect. top );
}
PDC-> moveTo (rect. Left + 20, yhalf );
For (F = 0; F <= 3.14; F + = 0.01f)
{
PDC-> lineto (rect. width ()/2-(INT) (Fa-20) * Cos (F) + rect. left, yhalf-(INT) (FB-20) * sin (F) + rect. top );
}
Cbrush * poldbrush = PDC-> SelectObject (& brshred );
PDC-> floodfill (rect. Left + 10, yhalf-10, RGB (0, 0, 0 ));
Fstartangle * = 100;
Fstartangle = (float) (INT) fstartangle)/100;
Fendangle * = 100;
Fendangle = (float) (INT) fendangle)/100;
PDC-> moveTo (rect. width ()/2-(INT) (FA * Cos (fstartangle) + rect. left, yhalf-(INT) (FB * sin (fstartangle) + rect. top );
PDC-> lineto (rect. width ()/2-(INT) (Fa-20) * Cos (fstartangle) + rect. left, yhalf-(INT) (FB-20) * sin (fstartangle) + rect. top );
PDC-> moveTo (rect. width ()/2-(INT) (FA * Cos (fendangle) + rect. left, yhalf-(INT) (FB * sin (fendangle) + rect. top );
PDC-> lineto (rect. width ()/2-(INT) (Fa-20) * Cos (fendangle) + rect. left, yhalf-(INT) (FB-20) * sin (fendangle) + rect. top );
PDC-> SelectObject (brshgreen );
If (fstartangle> 0 & fendangle & lt; 3.14)
{
PDC-> floodfill (rect. width ()/2-(INT) (Fa-5) * Cos (fstartangle + fendangle)/2) + rect. left, yhalf-(INT) (FB-5) * sin (fstartangle + fendangle)/2) + rect. top, RGB (0, 0 ));
}
PDC-> SelectObject (poldbrush );
}
Cpen pen;
Pen. createpen (ps_solid, 3, RGB (255,255,255 ));
Cpen * poldpen = PDC-> SelectObject (& pen );
Cfont * poldfont = PDC-> SelectObject (& fscalefont );
PDC-> setbkmode (transparent );
Fa-= 10;
FB-= 10;
PDC-> moveTo (rect. Left + 10, yhalf );
For (float f = 0; F <= 3.14; F + = 0.01f)
{
PDC-> lineto (rect. width ()/2-(INT) (FA * Cos (F) + rect. left, yhalf-(INT) (FB * sin (F) + rect. top );
}
Float fbigstep = 3.14f/(float) (m_dmaxvalue-m_dminvalue)/(float) m_dinterval)/4;
Int ndiv = 0;
Int nscale = (INT) m_dminvalue;
For (F = 0; F <= 3.15; F + = fbigstep)
{
PDC-> moveTo (rect. width ()/2-(INT) (FA * Cos (F) + rect. left, yhalf-(INT) (FB * sin (F) + rect. top );
If (ndiv = 0)
{
PDC-> lineto (rect. width ()/2-(INT) (Fa-15) * Cos (F) + rect. left, yhalf-(INT) (FB-15) * sin (F) + rect. top );
Cstring STR;
Str. Format ("% d", nscale );
Nscale + = (INT) m_dinterval;
Csize size = PDC-> getoutputtextextent (STR );
PDC-> settextcolor (RGB (0, 0, 0 ));
PDC-> textout (rect. width ()/2-(INT) (Fa-33) * Cos (F) + rect. left-size. CX/2 + 1, yhalf-(INT) (FB-33) * sin (F) + rect. top-size. cy/2 + 1, STR );
PDC-> settextcolor (RGB (255,255,255 ));
PDC-> textout (rect. width ()/2-(INT) (Fa-33) * Cos (F) + rect. left-size. CX/2, yhalf-(INT) (FB-33) * sin (F) + rect. top-size. cy/2, STR );
Ndiv ++;
}
Else
{
PDC-> lineto (rect. width ()/2-(INT) (Fa-10) * Cos (F) + rect. left, yhalf-(INT) (FB-10) * sin (F) + rect. top );
Ndiv ++;
If (ndiv = 4)
{
Ndiv = 0;
}
}
}
PDC-> SelectObject (poldfont );
Fscalefont. deleteobject ();
Cpoint m_ptmetercenter;
M_ptmetercenter.x = rect. Left + rect. Width ()/2;
M_ptmetercenter.y = rect. bottom;
Int nradiusframe = rect. Height ();
Cfont punitfont;
Logfont lf;
Lf. lfescapement = 0;
Lf. lfitalic = NULL;
Lf. lfunderline = NULL;
Lf. lfstrikeout = NULL;
Lf. lfcharset = default_charset;
Lf. lfheight = nradiusframe/4;
Strcpy (LF. lffacename, "");
Punitfont. createfontindirect (& lf );
Poldfont = (cfont *) PDC-> SelectObject (& punitfont );
PDC-> setbkmode (transparent );
PDC-> settextcolor (RGB (0, 0, 0 ));
Crect rectunits (INT (m_ptmetercenter.x-nradiusframe * 0.30f + 2 ),
INT (m_ptmetercenter.y-nradiusframe * 0.70f + 2 ),
INT (m_ptmetercenter.x + nradiusframe * 0.30f + 2 ),
INT (m_ptmetercenter.y-nradiusframe * 0.20f + 2 ));
PDC-> drawtext (m_strunits, & rectunits, dt_center | dt_singleline | dt_vcenter );
PDC-> settextcolor (RGB (255,255,255 ));
Rectunits. setrect (INT (m_ptmetercenter.x-nradiusframe * 0.30f ),
INT (m_ptmetercenter.y-nradiusframe * 0.70f ),
INT (m_ptmetercenter.x + nradiusframe * 0.30f ),
INT (m_ptmetercenter.y-nradiusframe * 0.20f ));
PDC-> drawtext (m_strunits, rectunits, dt_center | dt_singleline | dt_vcenter );
PDC-> SelectObject (poldpen );
PDC-> SelectObject (poldfont );
Punitfont. deleteobject ();
}
Draw the instrument pointer and use the processing technology to overlay the three-dimensional effect
Void cpanelmeter: drawneedle (CDC * PDC, crect & rect)
{
If (m_dcurrentvalue> m_dmaxvalue)
{
M_dcurrentvalue = m_dmaxvalue;
}
Else if (m_dcurrentvalue <m_dminvalue)
{
M_dcurrentvalue = m_dminvalue;
}
Double dangle = (m_dcurrentvalue-m_dminvalue)/(m_dmaxvalue-m_dminvalue) * 3.14f;
Float fa = (float) rect. Width ()/2;
Float Fb = (float) rect. Height ()-8;
Cbrush brshwhite;
Cbrush brshshadow;
Brshwhite. createsolidbrush (RGB (255,255,255 ));
Brshshadow. createsolidbrush (RGB (0, 0, 0 ));
Cbrush * poldbrush = PDC-> SelectObject (& brshshadow );
PDC-> ellipse (rect. width ()/2-9 + rect. left, rect. height ()-20 + rect. top, rect. width ()/2 + 11 + rect. left, rect. height () + rect. top );
PDC-> SelectObject (& brshwhite );
PDC-> ellipse (rect. width ()/2-10 + rect. left, rect. height ()-21 + rect. top, rect. width ()/2 + 10 + rect. left, rect. height ()-1 + rect. top );
PDC-> SelectObject (poldbrush );
Cpen penthick;
Cpen penthin;
Cpen penshadow;
Penthick. createpen (ps_solid, 5, RGB (255,100, 50 ));
Penthin. createpen (ps_solid, 1, RGB (255,255,255 ));
Penshadow. createpen (ps_solid, 5, RGB (0, 0, 0 ));
Cpen * poldpen = PDC-> SelectObject (& penshadow );
PDC-> moveTo (rect. width ()/2-(INT) (Fa-8) * Cos (dangle) + rect. left + 1, rect. height ()-11-(INT) (FB-8) * sin (dangle) + rect. top + 1 );
PDC-> lineto (rect. Width ()/2 + rect. Left + 1, rect. Height ()-11 + rect. Top + 1 );
PDC-> SelectObject (& penthick );
PDC-> moveTo (rect. width ()/2-(INT) (Fa-8) * Cos (dangle) + rect. left, rect. height ()-11-(INT) (FB-8) * sin (dangle) + rect. top );
PDC-> lineto (rect. Width ()/2 + rect. Left, rect. Height ()-11 + rect. Top );
PDC-> SelectObject (& penthin );
PDC-> moveTo (rect. width ()/2-(INT) (Fa-8) * Cos (dangle) + rect. left, rect. height ()-11-(INT) (FB-8) * sin (dangle) + rect. top );
PDC-> lineto (rect. Width ()/2 + rect. Left, rect. Height ()-11 + rect. Top );
PDC-> SelectObject (poldpen );
}
Draw real-time values, also using the superposition Technology
Void cpanelmeter: drawvalue (CDC * PDC, crect & rect)
{
Char strcurrentvalue [10];
Memset (strcurrentvalue, 0, sizeof (strcurrentvalue ));
Sprintf (strcurrentvalue, "%. 2f", m_dcurrentvalue );
Cpoint m_ptmetercenter;
M_ptmetercenter.x = rect. Left + rect. Width ()/2;
M_ptmetercenter.y = rect. bottom;
Int nradiusframe = rect. Height ();
Cfont punitfont, * poldfont;
Logfont lf;
Lf. lfescapement = 0;
Lf. lfitalic = NULL;
Lf. lfunderline = NULL;
Lf. lfstrikeout = NULL;
Lf. lfcharset = default_charset;
Lf. lfheight = nradiusframe/6;
Strcpy (LF. lffacename, "Arial ");
Punitfont. createfontindirect (& lf );
Poldfont = (cfont *) PDC-> SelectObject (& punitfont );
PDC-> setbkmode (transparent );
PDC-> settextcolor (RGB (0, 0, 0 ));
Crect rectunits (INT (m_ptmetercenter.x-nradiusframe * 0.30f + 2 ),
INT (m_ptmetercenter.y-nradiusframe * 0.40f + 2 ),
INT (m_ptmetercenter.x + nradiusframe * 0.30f + 2 ),
INT (m_ptmetercenter.y-nradiusframe * 0.10f + 2 ));
PDC-> drawtext (strcurrentvalue, & rectunits, dt_center | dt_singleline | dt_vcenter );
PDC-> settextcolor (RGB (255,255,255 ));
Rectunits. setrect (INT (m_ptmetercenter.x-nradiusframe * 0.30f ),
INT (m_ptmetercenter.y-nradiusframe * 0.40f ),
INT (m_ptmetercenter.x + nradiusframe * 0.30f ),
INT (m_ptmetercenter.y-nradiusframe * 0.10f ));
PDC-> drawtext (strcurrentvalue, rectunits, dt_center | dt_singleline | dt_vcenter );
PDC-> SelectObject (poldfont );
Punitfont. deleteobject ();
}
Now, the basic drawing is complete. We add some interfaces to change program parameters in the program.