📄 lamparray.cpp
字号:
/////////////////////////////////////////////////////////
// 灯阵列LampArray封装类
// 版本:1.03
// 最后修改日期:2002.1.25
/////////////////////////////////////////////////////////
// LampArray.cpp : implementation file
//
#include "stdafx.h"
#include "LampArray.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// LampArray
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:LampArray(CWnd * parent)
//输入参数:父窗口的指针
//返回值:无
//作用:构造函数,初始化变量的值,创建并显示对象
LampArray::LampArray(CWnd * parent)
{
LA_Width = 260; //默认的阵列大小
LA_Height = 100;
LA_BorderWidth = 3; //默认的边框宽度
LA_Rows = 3; //默认的灯阵列的行数和列数
LA_Columns = 5;
LA_FontSize = 14; //字体大小
LA_Status = LA_WORK; //仪表的默认状态
LA_LampStyle = LA_ELLIPSE; //默认的灯形状
LA_BdLightColor = RGB(255, 255, 255); //默认边界颜色
LA_BdDarkColor = RGB(100, 100, 100);
LA_TextColor = RGB(255, 255, 255); //文字的颜色
int i; //定义灯的默认文字
CString subtext;
LA_Text = "";
for(i = 0; i < (int)(LA_Rows * LA_Columns); i ++)
{
subtext.Format("灯%d", i);
LA_Text += subtext;
if(i != (int)(LA_Rows * LA_Columns - 1))
LA_Text += ",";
}
LA_TextOffset.x = 22; //灯的文字相对于灯的左上角的偏移坐标
LA_TextOffset.y = 2;
LA_LampLightColor = RGB(255, 0, 0); //灯点亮状态的颜色
LA_LampDarkColor = RGB(0, 200, 0); //灯熄灭状态的颜色
LA_LampPos.x = 10; //左上角的灯相对于仪表窗口左上角的位置坐标
LA_LampPos.y = 10;
LA_LampWidth = 20; //灯的宽度和高度(对于圆形灯,为椭圆的长轴和短轴)
LA_LampHeight = 20;
LA_LampBdWidth = 2; //灯的边界宽度
LA_LampXSpace = 30; //灯在X方向和Y方向的间距
LA_LampYSpace = 10;
LA_LampStatus = new int[LA_Rows * LA_Columns]; //初始化灯状态数组
memset((void *)LA_LampStatus, 0, LA_Rows * LA_Columns * sizeof(LA_LampStatus[0]));
LA_BkColor = GetSysColor(COLOR_3DFACE); //默认仪表背景颜色和对话框背景颜色一致
LA_BorderTop = 1; //默认情况下,四个边界都要显示
LA_BorderBottom = 1;
LA_BorderLeft = 1;
LA_BorderRight = 1;
//创建相应的静态控件并且显示
CRect rect;
rect.left = rect.top = 0;
rect.bottom = LA_Height - 1;
rect.right = LA_Width - 1;
Create(NULL, WS_CHILD | WS_VISIBLE | SS_NOTIFY, rect, parent);
SetTimer(1, 50, NULL);
}
LampArray::~LampArray()
{
LA_Font.DeleteObject();
delete [] LA_LampStatus;
KillTimer(1);
}
BEGIN_MESSAGE_MAP(LampArray, CStatic)
//{{AFX_MSG_MAP(LampArray)
ON_WM_PAINT()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// LampArray message handlers
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:OnPaint()
//输入参数:无
//返回值:无
//作用:重载函数,完成仪表界面的绘制
void LampArray::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
DrawFace();
// Do not call CStatic::OnPaint() for painting messages
}
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:DrawFace()
//输入参数:无
//返回值:无
//作用:完成仪表界面的绘制
void LampArray::DrawFace()
{
int i, j, k;
CClientDC dc(this);
CBitmap bmpc;
bmpc.CreateCompatibleBitmap(&dc, LA_Width, LA_Height); //创建与系统兼容的位图
BITMAP bmp;
bmpc.GetBitmap(&bmp);
COLORREF temp_color;
if(!LA_Font.m_hObject)
LA_Font.CreateFont(LA_FontSize, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_STROKE_PRECIS, CLIP_STROKE_PRECIS, DRAFT_QUALITY, VARIABLE_PITCH | FF_SWISS, _T("Arial")); //创建一个默认的字体
//绘制仪表的背景色
CDC dcmem;
dcmem.CreateCompatibleDC(&dc);
CBitmap * pbitmapold = (CBitmap *)dcmem.SelectObject(&bmpc);
CBrush brush, *pbrushold;
brush.CreateSolidBrush(LA_BkColor);
pbrushold= (CBrush *)dcmem.SelectObject(&brush);
dcmem.SelectStockObject(NULL_PEN);
dcmem.Rectangle(0, 0, bmp.bmWidth + 1, bmp.bmHeight + 1);
dcmem.SelectObject(pbrushold);
brush.DeleteObject();
//绘制仪表的边框
brush.CreateSolidBrush(LA_BdDarkColor);
pbrushold = (CBrush *)dcmem.SelectObject(&brush);
if(LA_BorderTop)
dcmem.Rectangle(0, 0, LA_Width + 1, LA_BorderWidth);
if(LA_BorderLeft)
dcmem.Rectangle(0, 0, LA_BorderWidth, LA_Height + 1);
dcmem.SelectObject(pbrushold);
brush.DeleteObject();
brush.CreateSolidBrush(LA_BdLightColor);
pbrushold = (CBrush *)dcmem.SelectObject(&brush);
if(LA_BorderBottom)
dcmem.Rectangle(0, LA_Height - LA_BorderWidth + 1, LA_Width + 1, LA_Height + 1);
if(LA_BorderRight)
dcmem.Rectangle(LA_Width - LA_BorderWidth + 1, 0, LA_Width + 1, LA_Height + 1);
dcmem.SelectObject(pbrushold);
brush.DeleteObject();
//绘制灯阵列
for(i = 0; i < (int)LA_Rows; i ++)
{
for(j = 0; j < (int)LA_Columns; j ++)
{
COLORREF bdcolor = 0;
if(LA_LampStatus[i * LA_Columns + j]) //灯点亮状态
{
if(LA_LampStyle == LA_RECTANGLE)
{
bdcolor = LA_LampLightColor;
temp_color = GetNextColor(LA_LampLightColor, 0.8);
brush.CreateSolidBrush(temp_color);
pbrushold = (CBrush *)dcmem.SelectObject(&brush);
dcmem.Rectangle(LA_LampPos.x + j * (LA_LampWidth + LA_LampXSpace), LA_LampPos.y + i * (LA_LampHeight + LA_LampYSpace), LA_LampPos.x + LA_LampWidth + j * (LA_LampWidth + LA_LampXSpace), LA_LampPos.y + LA_LampHeight + i * (LA_LampHeight + LA_LampYSpace));
dcmem.SelectObject(pbrushold);
brush.DeleteObject();
}
else if(LA_LampStyle == LA_ELLIPSE)
{
int r = (int)(0.375 * ((LA_LampWidth > LA_LampHeight) ? LA_LampWidth : LA_LampHeight));
temp_color = GetNextColor(LA_LampLightColor, 0.4);
for(k = r; k > 0; k --)
{
temp_color = GetNextColor(temp_color, 1.2);
brush.CreateSolidBrush(temp_color);
pbrushold = (CBrush *)dcmem.SelectObject(&brush);
dcmem.Ellipse(LA_LampPos.x + j * (LA_LampWidth + LA_LampXSpace) + r - k, LA_LampPos.y + i * (LA_LampHeight + LA_LampYSpace) + r - k, LA_LampPos.x + LA_LampWidth + j * (LA_LampWidth + LA_LampXSpace) - r + k, LA_LampPos.y + LA_LampHeight + i * (LA_LampHeight + LA_LampYSpace) - r + k);
dcmem.SelectObject(pbrushold);
brush.DeleteObject();
}
}
}
else //灯熄灭状态
{
if(LA_LampStyle == LA_RECTANGLE)
{
bdcolor = LA_LampDarkColor;
temp_color = GetNextColor(LA_LampDarkColor, 0.5);
brush.CreateSolidBrush(temp_color);
pbrushold = (CBrush *)dcmem.SelectObject(&brush);
dcmem.Rectangle(LA_LampPos.x + j * (LA_LampWidth + LA_LampXSpace), LA_LampPos.y + i * (LA_LampHeight + LA_LampYSpace), LA_LampPos.x + LA_LampWidth + j * (LA_LampWidth + LA_LampXSpace), LA_LampPos.y + LA_LampHeight + i * (LA_LampHeight + LA_LampYSpace));
dcmem.SelectObject(pbrushold);
brush.DeleteObject();
}
else if(LA_LampStyle == LA_ELLIPSE)
{
int r = (int)(0.375 * ((LA_LampWidth > LA_LampHeight) ? LA_LampWidth : LA_LampHeight));
temp_color = GetNextColor(LA_LampDarkColor, 0.2);
for(k = r; k > 0; k --)
{
temp_color = GetNextColor(temp_color, 1.2);
brush.CreateSolidBrush(temp_color);
pbrushold = (CBrush *)dcmem.SelectObject(&brush);
dcmem.Ellipse(LA_LampPos.x + j * (LA_LampWidth + LA_LampXSpace) + r - k, LA_LampPos.y + i * (LA_LampHeight + LA_LampYSpace) + r - k, LA_LampPos.x + LA_LampWidth + j * (LA_LampWidth + LA_LampXSpace) - r + k, LA_LampPos.y + LA_LampHeight + i * (LA_LampHeight + LA_LampYSpace) - r + k);
dcmem.SelectObject(pbrushold);
brush.DeleteObject();
}
}
}
if(LA_LampStyle == LA_RECTANGLE) //如果是矩形按钮,绘制3D边框
{
brush.CreateSolidBrush(bdcolor);
pbrushold = (CBrush *)dcmem.SelectObject(&brush);
dcmem.Rectangle(LA_LampPos.x + j * (LA_LampWidth + LA_LampXSpace), LA_LampPos.y + i * (LA_LampHeight + LA_LampYSpace), LA_LampPos.x + LA_LampWidth + j * (LA_LampWidth + LA_LampXSpace), LA_LampPos.y + LA_LampBdWidth + i * (LA_LampHeight + LA_LampYSpace));
dcmem.Rectangle(LA_LampPos.x + j * (LA_LampWidth + LA_LampXSpace), LA_LampPos.y + i * (LA_LampHeight + LA_LampYSpace), LA_LampPos.x + LA_LampBdWidth + j * (LA_LampWidth + LA_LampXSpace), LA_LampPos.y + LA_LampHeight + i * (LA_LampHeight + LA_LampYSpace));
dcmem.SelectObject(pbrushold);
brush.DeleteObject();
brush.CreateSolidBrush(GetNextColor(bdcolor, 0.3));
pbrushold = (CBrush *)dcmem.SelectObject(&brush);
dcmem.Rectangle(LA_LampPos.x + j * (LA_LampWidth + LA_LampXSpace), LA_LampPos.y + LA_LampHeight - LA_LampBdWidth + i * (LA_LampHeight + LA_LampYSpace), LA_LampPos.x + LA_LampWidth + j * (LA_LampWidth + LA_LampXSpace), LA_LampPos.y + LA_LampHeight + i * (LA_LampHeight + LA_LampYSpace));
dcmem.Rectangle(LA_LampPos.x + LA_LampWidth - LA_LampBdWidth + j * (LA_LampWidth + LA_LampXSpace), LA_LampPos.y + i * (LA_LampHeight + LA_LampYSpace), LA_LampPos.x + LA_LampWidth + j * (LA_LampWidth + LA_LampXSpace), LA_LampPos.y + LA_LampHeight + i * (LA_LampHeight + LA_LampYSpace));
dcmem.SelectObject(pbrushold);
brush.DeleteObject();
}
}
}
//绘制灯阵列的文字
CFont * pfontold = (CFont *)dcmem.SelectObject(&LA_Font);
int index;
CString text, alltext = LA_Text;
int mode = dcmem.SetBkMode(TRANSPARENT);
dcmem.SetTextColor(LA_TextColor);
for(k = 0; k < (int)(LA_Rows * LA_Columns); k ++)
{
index = alltext.Find(",");
if(index != -1)
text = alltext.Left(index);
else
text = alltext;
alltext = alltext.Right(alltext.GetLength() - text.GetLength() - 1);
i = k / LA_Columns;
j = k % LA_Columns;
dcmem.TextOut(LA_LampPos.x + LA_TextOffset.x + j * (LA_LampWidth + LA_LampXSpace), LA_LampPos.y + i * (LA_LampHeight + LA_LampYSpace) + LA_TextOffset.y, text);
}
dcmem.SetBkMode(mode);
dcmem.SelectObject(pfontold);
//将内存DC的内容一次画在屏幕DC上
dc.BitBlt(0, 0, bmp.bmWidth, bmp.bmHeight, &dcmem, 0, 0, SRCCOPY);
dcmem.SelectObject(pbitmapold);
bmpc.DeleteObject();
dcmem.DeleteDC();
}
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:LA_MoveWindow(int x, int y)
//输入参数:仪表窗口左上角的新坐标
//返回值:无
//作用:移动仪表的窗口
void LampArray::LA_MoveWindow(int x, int y)
{
CRect rect;
GetWindowRect(&rect);
MoveWindow(x, y, rect.Width(), rect.Height(), true);
}
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:LA_SetLampStatus(UINT rows, UINT columns, UINT status)
//输入参数:待设置的灯的行位置rows和列位置columns(注意行和列是从0开始算起的),
// 以及它的新状态status,status为1表示点亮,为0表示熄灭
//返回值:无
//作用:设置某个灯的状态
void LampArray::LA_SetLampStatus(UINT rows, UINT columns, UINT status)
{
if(rows * columns + columns > LA_Rows * LA_Columns - 1)
return;
LA_LampStatus[rows * columns + columns] = status;
DrawFace();
}
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:LA_SetLampStatus(UINT offset, UINT status)
//输入参数:待设置的灯的位置序号offset(相对于第一个灯,第一个灯序号为0),以及它的新状态status,status为1表示点亮,为0表示熄灭
//返回值:无
//作用:设置某个灯的状态
void LampArray::LA_SetLampStatus(UINT offset, UINT status)
{
if(offset > LA_Rows * LA_Columns - 1)
return;
LA_LampStatus[offset] = status;
DrawFace();
}
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:OnTimer(UINT nIDEvent)
//输入参数:定时器触发事件的ID
//返回值:无
//作用:重载WM_TIMER消息处理函数,完成自检状态的界面更新显示
void LampArray::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
int index;
switch(LA_Status)
{
case LA_TEST:
index = rand() % (LA_Rows * LA_Columns);
if(LA_GetLampStatus(index))
LA_SetLampStatus(index, 0);
else
LA_SetLampStatus(index, 1);
break;
case LA_WORK:
break;
default:
break;
}
CStatic::OnTimer(nIDEvent);
}
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:LA_GetLampStatus(UINT offset)
//输入参数:目标灯的位置序号offset(相对于第一个灯,第一个灯序号为0)
//返回值:灯的状态,0表示熄灭,1表示点亮,-1表示该灯不存在
//作用:获取某个灯的状态
int LampArray::LA_GetLampStatus(UINT offset)
{
if(offset > LA_Rows * LA_Columns - 1)
return -1;
return LA_LampStatus[offset];
}
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:LA_GetLampStatus(UINT rows, UINT columns)
//输入参数:目标灯的行位置rows和列位置columns
//返回值:灯的状态,0表示熄灭,1表示点亮,-1表示该灯不存在
//作用:获取某个灯的状态
int LampArray::LA_GetLampStatus(UINT rows, UINT columns)
{
if(rows * columns + columns > LA_Rows * LA_Columns - 1)
return -1;
return LA_LampStatus[rows * columns + columns];
}
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:LA_GetLampStatus(UINT rows, UINT columns)
//输入参数:仪表的状态常量,可以是LA_TEST(自检状态)或者LA_WORK(工作状态)
//返回值:无
//作用:获取某个灯的状态
void LampArray::LA_SetStatus(UINT status)
{
LA_Status = status;
memset((void *)LA_LampStatus, 0, LA_Rows * LA_Columns * sizeof(LA_LampStatus[0]));
DrawFace();
}
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:LA_SetBkColor(COLORREF color)
//输入参数:仪表的背景颜色
//返回值:无
//作用:设置仪表的背景颜色
void LampArray::LA_SetBkColor(COLORREF color)
{
LA_BkColor = color;
}
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:LA_SetFontSize(UINT size)
//输入参数:字体大小,单位是象素
//返回值:无
//作用:设置文字字体大小
void LampArray::LA_SetFontSize(UINT size)
{
LA_FontSize = size;
LA_Font.DeleteObject();
LA_Font.CreateFont(LA_FontSize, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_STROKE_PRECIS, CLIP_STROKE_PRECIS, DRAFT_QUALITY, VARIABLE_PITCH | FF_SWISS, _T("Arial")); //创建一个默认的字体
}
/////////////////////////////////////////////////////////////////////////////////////////
//函数名:LA_SetArraySize(UINT rows, UINT columns)
//输入参数:灯阵列的行数目rows和列数目columns
//返回值:无
//作用:设置灯阵列的大小
void LampArray::LA_SetArraySize(UINT rows, UINT columns)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -