51CTO技术论坛_中国领先的IT技术社区's Archiver

caoguoyang 发表于 2007-8-20 09:30

编写一个可用于工控数字量节点显示的LED类

在工业控制程序开发过程中很多选用VC作为开发平台,在与PLC等外围设备通讯过程中间一般都会涉及到与他们这些外围设 备的模拟量通讯和数字量通讯,采集当前节点状态.在进行上位机软件开发过程中可以用很多方法来表示这些采集的点的状态,比如1,0等.如果我们采用一个能 够动态改变颜色的LED来显示数字量节点,用一种数字钟来显示模拟量的话程序在人性化接口方面将会比较好.下面的程序简单的介绍一种用继承cstatic 类的方法来实现一个LED控件来动态显示外围设备采集到的数字量信号. ~_,Ki X`2A9y?d
正文
V zkt h%q"Z 数字量节点信号无非就是我们利用串口或者别的通讯端口与外部设备通讯,通过通讯协议解析成为的0或者1的信号,更多的状态就是一种无状态.在通常的工业控 制程序中,我们一般喜欢用红色来表示有状态,即1,绿色为无状态,即0,黄色为无效状态,我们这里可以定义为2.那么,如果考虑到程序的控件的扩展性,我 们可以定义多个背景颜色.这个控件里面我们定义4种颜色,RED, GREEN, YELLOW, BLUE,如果需要更多我们可以灵活定义.
`3af,T `+mDND C3m typedef enum tagItemCOLOR{RED, GREEN, BLUE, YELLOW};)Q"X4R,{9j@+T'Ux#E
1Y['hX!k7hkQ|q kw
同时我们定义一下控件的背景显示模式,一般的LED我们显示为圆圈,但是有些控件的LED为方形,我们也考虑进行定义.0~xnGE ^yW
#define ID_SHAPE_ROUND    3001hu]3Gr UJ#?
#define ID_SHAPE_SQUARE    3002
K(H5X&`h$L|p5xo*G &uJ(B5p]
首先继承一个新类命名为CStateLedCtrl继承CStatic,映射消息WM_PAINT,我们将在这里进行背景的绘制就可以简单的实现了.
H F'A#alI f0Z void CStateLedCtrl::OnPaint()
#VWk%T3L;@nBR)I {7R4B b!{D6u:x;`
    CPaintDC dc(this); // device context for paintingP]l$R6nK1@+f L
    UgQU2_2a
    // TODO: Add your message handler code here;M)Q(G+iq
    i3m.a'P`km^(U
    // Do not call CStatic::OnPaint() for painting messages
oz,qR@oT tBM     // Get the Device Context LTGG-n?
   
?n%g Yp#^%x:c+oz     // Get the rectangle of the window where we are going to draw
?-l0U-w$X&b     CRect rcClient; nc U.C0vLss?%_T n
    GetClientRect(&rcClient);;Uo%h G6VI gU

tE9YUwz     // If the pen has been selected already, then we have to delete it
8z)YqE/?8ZS     // so that it doesnt throw an assertionF:hx;En'D eV\K#_

+``jL];US     if(m_PenBright.m_hObject!=NULL)
iT%E.CL)ls`         m_PenBright.DeleteObject(); Sp!XU4Y;`Yw&M0f6X

L5mP;] O0K1O yt@     if(m_BrushBright.m_hObject!=NULL)3q e)Od)RQ#J [X'd
        m_BrushBright.DeleteObject();Og"p X6u;lgR
{V'Ms]JsH rZ u
    if(m_PenDark.m_hObject!=NULL)
lP;r` k         m_PenDark.DeleteObject();+z7}(`7q*kT su

(e w'iEgj9f.j     if(m_BrushDark.m_hObject!=NULL)
ENr f7f         m_BrushDark.DeleteObject();   
Ke*xioX i}`
$bL;X9Md     if(m_itemColor == RED)
nH+^ I'iHg"}P     {K.ic!T1L:p!r[x[l
        // I'm creating a light shade of red here for displaying the bright
:l2~)\/OJ         // LED. You can change the values to any colour that you want
d\ zdQ(K1IG8\2n _         m_PenBright.CreatePen(0, 1, RGB(250,0,0));R._'z9yW6A
        m_BrushBright.CreateSolidBrush(RGB(250,0,0));
2B*^6_u1@ 8J,H4[ Y d,k2k`
        // Here i'm creating a dark shade of red. You can play with the values to,C$UP,ysj8B
        // see the effect on the LED control8MX)pb[` T
5DG)y-J!nS
        m_PenDark.CreatePen(0, 1, RGB(125,0,0));
DbV*j3NI1D9K]         m_BrushDark.CreateSolidBrush(RGB(0,255,0));1GC ^v3SMr
    }
z~ YPG5M     else if(m_itemColor == GREEN)MB*@yYC+a&c(iy~
    {
(J2O)a b3z?         // If the user has selected GREEN as the color of the LED D.?jO;Bg(L wS7v

0K$D/|+| E         m_PenBright.CreatePen(0, 1, RGB(0,250,0));q~ PuM&By^"N
        m_BrushBright.CreateSolidBrush(RGB(0,250,0));n#u3E {b
Cx:B$C*U$u-w7PQ1M
        m_PenDark.CreatePen(0, 1, RGB(0,125,0));
5H+GP*x.Xt(H2OO         m_BrushDark.CreateSolidBrush(RGB(255,0,0));
@ LG'SDm,BQ#c8|6A     }
.z0]V O*s Y N     else if(m_itemColor == YELLOW)Uu2e4A9J.m-|5H
    {$RI(A K&uj1y
        // If the user has selected YELLOW as the color of the LED
| GT+Z4@ t@%O*^!uY9I
        m_PenBright.CreatePen(0,1,RGB(255,255 ,0));a(s&W+wR#U&Du
        m_BrushBright.CreateSolidBrush(RGB(255,255,0));X2Bge t.kW D Z1u
H;Qq'k^#P*UQ FF
        m_PenDark.CreatePen(0,1,RGB(150,150,0));
xE yp[ @6v         m_BrushDark.CreateSolidBrush(RGB(150,150,0));
6[#\!OH5o0YF,x4U     }
bEt`Qi)g)U#t     elseR'd.Qd/u4| r FR1zXw
    {
8e)Q$fi1P         // If the user has selected BLUE as the color of the LEDB@1E#JNh3I
N]nYaM|-k B
        m_PenBright.CreatePen(0,1,RGB(0,0,250)); c chgagX
        m_BrushBright.CreateSolidBrush(RGB(0,0,250));
jJ5PL A/[tO3u
[![K2kA@qk         m_PenDark.CreatePen(0,1,RGB(0,0,150));"NdO'G*|'D
        m_BrushDark.CreateSolidBrush(RGB(0,0,150));#I:nH%fB*nwa7l#jm
    }m)IT` ^/M~*{@&E
     
e?ai1F     dc.SelectObject(&m_PenBright);`c)iqr*WvG
    dc.SelectObject(&m_BrushBright);
i(H/W;rk/]     "Q _ x9m(O
    m_BrushCurrent.m_hObject = m_BrushBright.m_hObject; )G)@Y/~ _$a6F Db
_#jM+~.^
    // If the round shape has been selected for the control
.ARQ{FrRA&v     if(m_nShape==ID_SHAPE_ROUND) I\ Kgkh1i.w@
    {LC:Td:_q~
        // Draw the actual colour of the LEDh6H&q z v
        dc.Ellipse(rcClient);Z4P @3NMg,}9K

9WkD ^3I         // Draw a thick dark gray coloured circle*we:jb.lP_
        CPen Pen;P/_"f0o$P0IR?
        Pen.CreatePen(0,2,RGB(128,128,128));
V?4`fgc^1rw         dc.SelectObject(&Pen);
T |1xbX0L         .{`"j-{;m`9m
        dc.Ellipse(rcClient);
"Y'sP|Fx
'a%eD6T [8zJd         // Draw a thin light gray coloured circle
6_%t%QZ7W} L;C         Pen.DeleteObject();/}0n5LX~ c
        Pen.CreatePen(0,1,RGB(192,192,192));
:{l ?1}/]C HeU%o         dc.SelectObject(&Pen);
|Nu#~6^3L9z7~ j;Q#{         dc.Ellipse(rcClient);N*Jwl%znd&j
X1E}UDk8H
        // Draw a white arc at the bottom
r A3z@I/W5?         Pen.DeleteObject();
+Z$Y M7w2v#P%| h.BULi         Pen.CreatePen(0,1,RGB(255,255,255));
K!]%?z h2O         dc.SelectObject(&Pen);"oIz!N;u&U v0s
*Y K{8KD8M|-@
        // The arc function is just to add a 3D effect for the control
[)A:a1bJ8s         CPoint ptStart,ptEnd;Z V sv%CX:v
        ptStart = CPoint(rcClient.Width()/2,rcClient.bottom);
9tJqkq G!}Bo:jh         ptEnd    = CPoint(rcClient.right,rcClient.top);
6l`Vj ~"E DO@4i#? Ee
        dc.MoveTo(ptStart);
Q2lAWE E(YG y(C         dc.Arc(rcClient,ptStart,ptEnd);
nF&o"r1Y"\ .Blfq9`"f$k
        CBrush Brush;
]6AI)x-d         Brush.CreateSolidBrush(RGB(255,255,255));
&BB)Gv5jN)S         dc.SelectObject(&Brush);
;hC+Jj kXV
%F(k)OqN_8j']         // Draw the actual ellipse
0x3{'Ke8x bY)Z         dc.Ellipse(rcClient.left+10,rcClient.top+10,rcClient.left+12,rcClient.top+12);6r^4A^+X V/a
    }
3{ M%m:C%Nay     else if(m_nShape==ID_SHAPE_SQUARE)
i dTcV'`+Ci!O S     {t'YF7qs'jIX8}
        // If you have decided that your LED is going to look square in shape, thenk"^],r |_D8|$N2z gV
V5z-I'{F t8D3{/w'S
        // Draw the actual rectangle3]3@ Hbs#IO4F
        dc.FillRect(rcClient,&m_BrushCurrent);v,bg6wL
&oO0f(}-x#_%_ j;a,Y
        // The  code below gives a 3D look to the control. It does nothing more
Z9ZH-YL"Ih'Dl 5t8p*tCBA.l
        // Draw the dark gray lines
oF1ie HG[\         CPen Pen;.e1[uE$i#EB
        Pen.CreatePen(0,1,RGB(128,128,128));A|&YVkK dcf
        dc.SelectObject(&Pen);_|O]8[|v%a` p

,SQh3K r9R.Gk         dc.MoveTo(rcClient.left,rcClient.bottom);L$Xc[,m:G.{#a
        dc.LineTo(rcClient.left,rcClient.top);)ht.d$TtT:Y!I
        dc.LineTo(rcClient.right,rcClient.top);"X7YH eh_{
        
w8K4ON+K         Pen.DeleteObject();
TxmL)@%}'J v2} /i%b eY G7[
        // Draw the light gray lines
,iN|a$T6B%oU,_         Pen.CreatePen(0,1,RGB(192,192,192));uP2e [7O
        dc.SelectObject(&Pen);
B&W B8g!lNZ
o6q BV`         dc.MoveTo(rcClient.right,rcClient.top);
,n#k6|opbCp         dc.LineTo(rcClient.right,rcClient.bottom);Dxmm%q1I
        dc.LineTo(rcClient.left,rcClient.bottom);    3@+?sSvP9Mjr1M
    }
T"K3FX$tH D } r/s*w wO+T@4N%vw
#__"[Y\*I y
控件提供2个简单的设置背景形状和颜色的接口.
*M*P {4t3o!l8F_ SetLED(UINT nIDShape)B u7H%Kt8]C8MN
SetSwitchState(tagItemCOLOR itemColor)
N"p`!a]e(C Bh4]n Xs
具体使用方法可以参考程序调用掩饰Demo.演示效果如下:
(K(v\[L){ [attach]55741[/attach]GF.`k o-N

yw9MQ|7Z 该Led控件只是简单的模拟演示了一下控件的编写方法和步骤,其中由于时间关系代码的封装还不是很流畅,读者可以根据自己的需要进行必要的修改.I9Xo(}0^

b nA,]4|s9v [[i] 本帖最后由 caoguoyang 于 2007-8-20 09:32 编辑 [/i]]

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.