关键字 Led 报警 状态指示
介绍
工控软件开发过程中,Led是非常重要的一个表现形式环节,如何能够直观的反映模拟工控现场的各种按钮或者指示灯是非常重要的一种人机软件实现方法。这里提供静态Led和按钮两种控件,能够更好的模拟现场环境,增加人机界面的人性化。希望对寻求相关开发的人有帮助。
正文
前段时间我在vchelp专栏发表了一些关于工控控件的编写方法的文章,这些时间一直有很多的朋友给我来邮件,感谢很多网络的朋友对我的支持。同时很多人提出:他们在使用工控现场模拟按钮或者指示灯等控件中发现可能关于这些方面的控件不是很多或者不是很形象。现在正好项目空闲有一些时间,在研究了许多工控软件的界面表现形式和开源代码实现的基础上完成了现在两个控件的编写,读者如果有兴趣可以在上面进行扩展,完成更多更好的效果。
控件演示效果见下:提供了静态Led效果和按钮指示效果,其中静态Led控件提供了On(打开), Off(关闭), Flash(闪烁)三种效果。
静态Led控件采用重绘背景的形式实现,根据设定的状态进行不同背景采用绘制外框,内框,内部灯的渐变的方法进行绘制,这样能够形成实现效果上的凹凸的立体效果,具体绘制方法可以见下面代码。
方形控件绘制方法
void CLightCtrl::DrawStateRectangle(CDC *pDC, CRect &rect)
{
CPen pNewPen, *pOldPen;
int Color_R,Color_G,Color_B;
Color_R = (int)GetRValue(m_BorderColor) / m_nBorderWidth;
Color_G = (int)GetGValue(m_BorderColor) / m_nBorderWidth;
Color_B = (int)GetBValue(m_BorderColor) / m_nBorderWidth;
pNewPen.CreatePen(PS_SOLID, 0, RGB( 255, 255, 255));
pOldPen = (CPen *)pDC->SelectObject(&pNewPen);
//画外框
for (int i=0; i<m_nBorderWidth; i++)
{
pNewPen.DeleteObject();
pNewPen.CreatePen(PS_SOLID, 0, RGB(Color_R * i, Color_G * i, Color_B * i));
pDC->SelectObject(&pNewPen);
pDC->MoveTo(i, i);
pDC->LineTo(i + rect.Width() - 2 * i, i);
pDC->LineTo(i + rect.Width() - 2 * i, i + rect.Height() - 2 * i);
pDC->LineTo(i, i + rect.Height() -2 * i);
pDC->LineTo(i, i);
}
//画内框
if (m_enumState == IS_OFF)
{
Color_R = int(0.6 * (int)GetRValue(m_LightOffColor) / m_nLightWidth);
Color_G = int(0.6 * (int)GetGValue(m_LightOffColor) / m_nLightWidth);
Color_B = int(0.6 * (int)GetBValue(m_LightOffColor) / m_nLightWidth);
}
else if(m_enumState == IS_ON)
{
Color_R = int(0.6 * (int)GetRValue(m_LightOnColor) / m_nLightWidth);
Color_G = int(0.6 * (int)GetGValue(m_LightOnColor) / m_nLightWidth);
Color_B = int(0.6 * (int)GetBValue(m_LightOnColor) / m_nLightWidth);
}
for(i=0; i<m_nLightWidth; i++)
{
pNewPen.DeleteObject();
if(m_enumState == IS_OFF)
{
pNewPen.CreatePen(PS_SOLID, 0, RGB(GetRValue(m_LightOffColor) * 0.4 + Color_R * i,
GetGValue(m_LightOffColor) * 0.4 + Color_G * i,
GetBValue(m_LightOffColor) * 0.4 + Color_B * i));
}
else if(m_enumState == IS_ON)
{
pNewPen.CreatePen(PS_SOLID, 0, RGB(GetRValue(m_LightOnColor) * 0.4 + Color_R * i,
GetGValue(m_LightOnColor) * 0.4 + Color_G * i,
GetBValue(m_LightOnColor) * 0.4 + Color_B * i));
}
pDC->SelectObject(&pNewPen);
pDC->MoveTo(i + m_nBorderWidth, i + m_nBorderWidth);
pDC->LineTo(i + m_nBorderWidth + rect.Width() - 2 * (i + m_nBorderWidth),
i + m_nBorderWidth);
pDC->LineTo(i + m_nBorderWidth + rect.Width() - 2 * (i + m_nBorderWidth),
i + m_nBorderWidth+rect.Height() - 2 * (i + m_nBorderWidth));
pDC->LineTo(i + m_nBorderWidth,
i + m_nBorderWidth + rect.Height() - 2 * (i + m_nBorderWidth));
pDC->LineTo(i + m_nBorderWidth, i + m_nBorderWidth);
}
//填充灯
CBrush pBackBrush, *pOldBrush;
if (m_enumState == IS_OFF)
{
pBackBrush.CreateSolidBrush(m_LightOffColor);
}
else if(m_enumState == IS_ON)
{
pBackBrush.CreateSolidBrush(m_LightOnColor);
}
pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);
pDC->FillRect(CRect(m_nBorderWidth + m_nLightWidth,
m_nBorderWidth + m_nLightWidth,
rect.Width() - (m_nBorderWidth + m_nLightWidth) + 2,
rect.Height() - (m_nBorderWidth + m_nLightWidth) + 2),
&pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
//写降标题
pDC->SetTextColor(RGB( 255, 255, 255));
pDC->SetBkMode(TRANSPARENT);
CRect rcTitle(m_nBorderWidth + m_nLightWidth,
m_nBorderWidth + m_nLightWidth,
rect.Width() - (m_nBorderWidth + m_nLightWidth) + 2,
rect.Height() - (m_nBorderWidth + m_nLightWidth) + 2);
pDC->DrawText(m_strCaption, &rcTitle, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
//恢复设置
pDC->SelectObject(pOldPen);
pNewPen.DeleteObject();
}
圆形Led的绘制原理大致同方形Led的绘制,详细方法就不在叙述,可以参考代码。
按钮的绘制原理采用方形按钮绘制的外观的方法进行,采用按钮自绘的方法,根据按钮的当前鼠标状态进行不同状态的绘制。这里增加了鼠标选中与非选中的效果,来模拟现场按钮按下的效果。具体可以见方形按钮的状态绘制。
void CLightButton::DrawStateRectangle(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect m_rectClient = lpDrawItemStruct->rcItem;
UINT nState = lpDrawItemStruct->itemState;
CPen pNewPen, *pOldPen;
int Color_R,Color_G,Color_B;
Color_R = (int)GetRValue(m_BorderColor) / m_nBorderWidth;
Color_G = (int)GetGValue(m_BorderColor) / m_nBorderWidth;
Color_B = (int)GetBValue(m_BorderColor) / m_nBorderWidth;
pNewPen.CreatePen(PS_SOLID, 0, RGB( 255, 255, 255));
pOldPen = (CPen *)pDC->SelectObject(&pNewPen);
CRect rcTitle(0, 0, m_rectClient.Width(), m_rectClient.Height());
//画外框
for(int i=0; i<m_nBorderWidth; i++)
{
Color_R = (int)255 / m_nBorderWidth;
Color_G = (int)255 / m_nBorderWidth;
Color_B = (int)255 / m_nBorderWidth;
pDC->Draw3dRect(m_rectClient.left + i,
m_rectClient.top + i,
m_rectClient.Width() - 2 * i,
m_rectClient.Height() - 2 * i,
RGB(255-Color_R * i, 255 - Color_G * i, 255-Color_B * i),
RGB(Color_R * i, Color_G * i, Color_B * i));
}
//画内框
Color_R = int(0.6 * (int)GetRValue(m_ButtonColor) / m_nLightWidth);
Color_G = int(0.6 * (int)GetGValue(m_ButtonColor) / m_nLightWidth);
Color_B = int(0.6 * (int)GetBValue(m_ButtonColor) / m_nLightWidth);
for(i=0; i<m_nLightWidth; i++)
{
if (lpDrawItemStruct->itemState & ODS_SELECTED)
{
pNewPen.DeleteObject();
pNewPen.CreatePen(PS_SOLID, 0, RGB(GetRValue(m_ButtonColor) * 0.4 + Color_R * (m_nLightWidth - i),
GetGValue(m_ButtonColor) * 0.4 + Color_G * (m_nLightWidth - i),
GetBValue(m_ButtonColor) * 0.4 + Color_B * (m_nLightWidth - i)));
rcTitle = CRect(4, 2, m_rectClient.Width(), m_rectClient.Height());
}
else
{
pNewPen.DeleteObject();
pNewPen.CreatePen(PS_SOLID, 0, RGB(GetRValue(m_ButtonColor) * 0.4 + Color_R * i,
GetGValue(m_ButtonColor) * 0.4 + Color_G * i,
GetBValue(m_ButtonColor) * 0.4 + Color_B * i));
}
pDC->SelectObject(&pNewPen);
pDC->MoveTo(i + m_nBorderWidth, i + m_nBorderWidth);
pDC->LineTo(i + m_nBorderWidth + m_rectClient.Width() - 2 * (i + m_nBorderWidth),
i + m_nBorderWidth);
pDC->LineTo(i + m_nBorderWidth + m_rectClient.Width() - 2 * (i + m_nBorderWidth),
i + m_nBorderWidth + m_rectClient.Height() - 2 * (i + m_nBorderWidth));
pDC->LineTo(i + m_nBorderWidth,
i + m_nBorderWidth + m_rectClient.Height() - 2 * (i + m_nBorderWidth));
pDC->LineTo(i + m_nBorderWidth, i + m_nBorderWidth);
}
//填充按钮
pDC->FillSolidRect(m_nBorderWidth + m_nLightWidth,
m_nBorderWidth + m_nLightWidth,
m_rectClient.Width() - 2 * (m_nBorderWidth + m_nLightWidth) + 2,
m_rectClient.Height() - 2 * (m_nBorderWidth + m_nLightWidth) + 2,
m_ButtonColor);
pDC->SelectObject(&pNewPen);
//写降标题
CFont pNewFont, *pOldFont;
pNewFont.CreatePointFont(120, "Impat", pDC);
pOldFont = (CFont *)pDC->SelectObject(&pNewFont);
pDC->SetTextColor(RGB( 255, 255, 255));
pDC->SetBkMode(TRANSPARENT);
GetWindowText(m_strCaption, MAXNAMELENGTH);
pDC->DrawText(m_strCaption, &rcTitle, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
//恢复设置
pDC->SelectObject(pOldFont);
pNewFont.DeleteObject();
pDC->SelectObject(pOldPen);
pNewPen.DeleteObject();
}
使用方法:在要使用控件的界面上,将相关的控件变量定义成完成的控件变量对象,然后根据控件接口进行先关的参数设定就可以完成效果了。
这里Led和按钮都采用同样的展现形式进行绘制,如果各位有更好或者更美观的实现方法可以在上面的基础上完成,也希望您能够将您的效果和源代码共享出来,希望能和我联系
QQ:5516853
EM:successq_g@163.com
正文完
欢迎访问最专业的网吧论坛,无盘论坛,网吧经营,网咖管理,网吧专业论坛
https://bbs.txwb.com
关注天下网吧微信/下载天下网吧APP/天下网吧小程序,一起来超精彩
|
本文来源:vczx 作者:佚名