⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fluxdevice.cpp

📁 上位机图形显示程序,可用于8051单片机的开发,通信及控制
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////
//			流量检测设备FluxDevice封装类
//	版本:1.03
//	最后修改日期:2002.1.25
/////////////////////////////////////////////////////////

// FluxDevice.cpp : implementation file
//

#include "stdafx.h"
#include "FluxDevice.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// FluxDevice


/////////////////////////////////////////////////////////////////////////////////////////
//函数名:FluxDevice(CWnd *parent)
//输入参数:父窗口的指针
//返回值:无
//作用:构造函数,初始化变量的值,创建并显示对象
FluxDevice::FluxDevice(CWnd *parent)
{
	FD_Width = 60;		//仪表的默认尺寸
	FD_Height = 150;

	FD_Origin.x = 25;	//仪表的内部坐标系原点
	FD_Origin.y = 140;

	FD_Status = FD_WORK;	//仪表的默认状态
	
	FD_TestDirection = 1;	//仪表测试状态下,初始油量变化方向

	FD_HighLevelRatio = 0.7;	//油量的高/中档分界	
	FD_MiddleLevelRatio = 0.4;	//油量的中/低档分界

	FD_PipeLength = 130;	//默认的油量筒长
	FD_PipeRadius = 15;		//默认的油管半径

	FD_FrameLength = 10;	//油管两头框架的长度
	FD_FrameRadius = 18;	//默认的框架半径

	FD_MaxFlux = 50;		//默认的最大流量
	FD_CurrentFlux = 0;		//默认的当前流量

	FD_BigGridLength = 10;	//默认的大刻度线长度
	FD_BigGridNum = 5;		//默认的大刻度的格子数目

	FD_SmallGridLength = 5;	//默认的小刻度线长度
	FD_SmallGridNum = 25;	//默认的小刻度的格子数目

	FD_GridXOffset = 0;		//默认的刻度线相对于原点的X方向偏移量
	
	FD_TextOffset.x = 10;	//标注文字相对于刻度线的位置偏移
	FD_TextOffset.y = -5;	

	FD_FontSize = 12;	//默认的标注文字字体大小

	FD_GridColor = RGB(255, 255, 255);	//默认的刻度颜色
	FD_TextColor = RGB(0, 55, 0);	//默认的文字颜色

	FD_HighLevelColor = RGB(0, 255, 0);	//高流量状态的油筒颜色

	FD_MiddleLevelColor = RGB(255, 255, 0);	//中流量状态的油筒颜色
	
	FD_LowLevelColor = RGB(255, 0, 0);	//低流量状态的油筒颜色

	FD_FrameFrontColor = RGB(255, 255, 255);//油筒框架外表面的颜色

	FD_FrameBackColor = RGB(180, 180, 180);	//油筒框架内表面的颜色

	FD_BkColor = GetSysColor(COLOR_3DFACE);	//仪表的背景颜色

	//创建相应的静态控件并且显示
	CRect rect;			
	rect.left = rect.top = 0;
	rect.bottom = FD_Height - 1; 
	rect.right = FD_Width - 1;
	Create(NULL, WS_CHILD | WS_VISIBLE | SS_NOTIFY, rect, parent);	
	
	SetTimer(1, 50, NULL);
}

FluxDevice::~FluxDevice()
{
	FD_Font.DeleteObject();
	KillTimer(1);
}


BEGIN_MESSAGE_MAP(FluxDevice, CStatic)
	//{{AFX_MSG_MAP(FluxDevice)
	ON_WM_PAINT()
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// FluxDevice message handlers


/////////////////////////////////////////////////////////////////////////////////////////
//函数名:OnPaint()
//输入参数:无
//返回值:无
//作用:重载函数,完成仪表的界面绘制
void FluxDevice::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 FluxDevice::DrawFace()
{
	CClientDC dc(this);
	
	int i;
	CBitmap bmpc;
	bmpc.CreateCompatibleBitmap(&dc, FD_Width, FD_Height);	//创建与系统兼容的位图
	BITMAP bmp;
	bmpc.GetBitmap(&bmp);
	
	if(!FD_Font.m_hObject)
		FD_Font.CreateFont(FD_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;
	CBrush brush, *pbrushold;
	dcmem.CreateCompatibleDC(&dc);
	CBitmap * pbitmapold = (CBitmap *)dcmem.SelectObject(&bmpc);
	brush.CreateSolidBrush(FD_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();
	
	COLORREF temp_color;
	int r;

	//绘制框架内表面
	temp_color = FD_FrameBackColor;
	r = (int)(0.8 * FD_FrameRadius);
	for(i = 0; i < r; i ++)
	{
		temp_color = GetNextColor(temp_color, 0.8);
		brush.CreateSolidBrush(temp_color);
		pbrushold = (CBrush *)dcmem.SelectObject(&brush);
		dcmem.Rectangle(FD_Origin.x - FD_FrameRadius + i, FD_Origin.y + 1, FD_Origin.x + FD_FrameRadius - i, FD_Origin.y - FD_PipeLength - 1);
		dcmem.SelectObject(pbrushold);
		brush.DeleteObject();
	}
	
	//绘制框架外表面
	r = (int)(0.9 * FD_FrameRadius);
	temp_color = GetNextColor(FD_FrameFrontColor, - r * 15);
	for(i = 0; i < r; i ++)
	{
		temp_color = GetNextColor(temp_color, 15);
		brush.CreateSolidBrush(temp_color);
		pbrushold = (CBrush *)dcmem.SelectObject(&brush);
		dcmem.Rectangle(FD_Origin.x - FD_FrameRadius + i, FD_Origin.y, FD_Origin.x + FD_FrameRadius - i, FD_Origin.y + FD_FrameLength);
		dcmem.Rectangle(FD_Origin.x - FD_FrameRadius + i, FD_Origin.y - FD_PipeLength, FD_Origin.x + FD_FrameRadius - i, FD_Origin.y - FD_FrameLength - FD_PipeLength);
		dcmem.SelectObject(pbrushold);
		brush.DeleteObject();
	}

	//绘制油筒内的液体
	double ratio = FD_CurrentFlux / FD_MaxFlux;
	if(ratio >= FD_HighLevelRatio)
		temp_color = FD_HighLevelColor;
	else if(ratio >= FD_MiddleLevelRatio)
		temp_color = FD_MiddleLevelColor;
	else
		temp_color = FD_LowLevelColor;
	r = (int)(0.8 * FD_PipeRadius);
	temp_color = GetNextColor(temp_color, -r * 15);
	for(i = 0; i < r; i ++)
	{
		temp_color = GetNextColor(temp_color, 15);
		brush.CreateSolidBrush(temp_color);
		pbrushold = (CBrush *)dcmem.SelectObject(&brush);
		dcmem.Rectangle(FD_Origin.x - FD_PipeRadius + i, FD_Origin.y, FD_Origin.x + FD_PipeRadius - i, FD_Origin.y - (int)(FD_PipeLength * ratio));
		dcmem.SelectObject(pbrushold);
		brush.DeleteObject();
	}
	
	//绘制大刻度线(并标注文字)
	CPen pen, *ppenold;
	CFont *pfontold;
	pen.CreatePen(PS_SOLID, 1, FD_GridColor);
	ppenold = (CPen *)dcmem.SelectObject(&pen);
	CString text;
	int mode = dcmem.SetBkMode(TRANSPARENT);
	pfontold = (CFont *)dcmem.SelectObject(&FD_Font);
	dcmem.SetTextColor(FD_TextColor);
	for(i = 1; i <= (int)FD_BigGridNum; i ++)
	{
		dcmem.MoveTo(FD_Origin.x + FD_GridXOffset, FD_Origin.y - i * FD_PipeLength / FD_BigGridNum);
		dcmem.LineTo(FD_Origin.x + FD_GridXOffset + FD_BigGridLength, FD_Origin.y - i * FD_PipeLength / FD_BigGridNum);
		text.Format("%d", (int)(i * FD_MaxFlux / FD_BigGridNum));
		dcmem.TextOut(FD_Origin.x + FD_GridXOffset + FD_BigGridLength + FD_TextOffset.x, FD_Origin.y - i * FD_PipeLength / FD_BigGridNum + FD_TextOffset.y, text);
	}
	dcmem.SelectObject(pfontold);
	dcmem.SetBkMode(mode);
	dcmem.SelectObject(ppenold);
	pen.DeleteObject();

	//绘制小刻度线
	pen.CreatePen(PS_SOLID, 1, FD_GridColor);
	ppenold = (CPen *)dcmem.SelectObject(&pen);
	for(i = 1; i <= (int)FD_SmallGridNum; i ++)
	{
		dcmem.MoveTo(FD_Origin.x + FD_GridXOffset, FD_Origin.y - i * FD_PipeLength / FD_SmallGridNum);
		dcmem.LineTo(FD_Origin.x + FD_GridXOffset + FD_SmallGridLength, FD_Origin.y - i * FD_PipeLength / FD_SmallGridNum);
	}
	dcmem.SelectObject(ppenold);
	pen.DeleteObject();


	//将内存DC的内容一次画在屏幕DC上
	dc.BitBlt(0, 0, bmp.bmWidth, bmp.bmHeight, &dcmem, 0, 0, SRCCOPY);

 	dcmem.SelectObject(pbitmapold);
	bmpc.DeleteObject();
	dcmem.DeleteDC();
}


/////////////////////////////////////////////////////////////////////////////////////////
//函数名:FD_MoveWindow(int x, int y)
//输入参数:仪表窗口的新位置坐标
//返回值:无
//作用:该函数移动仪表的窗口
void FluxDevice::FD_MoveWindow(int x, int y)
{
	CRect rect;
	GetWindowRect(&rect);
	MoveWindow(x, y, rect.Width(), rect.Height(), true);
}


/////////////////////////////////////////////////////////////////////////////////////////
//函数名:OnTimer(UINT nIDEvent)
//输入参数:定时器触发事件ID
//返回值:无
//作用:重载WM_TIMER的消息处理函数,完成自检状态下的显示更新
void FluxDevice::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	switch(FD_Status)
	{
	case FD_TEST:	//自检状态
		FD_CurrentFlux += FD_TestDirection * 2;
		if(FD_CurrentFlux > FD_MaxFlux)
		{
			FD_CurrentFlux = FD_MaxFlux;
			FD_TestDirection = - FD_TestDirection;
		}
		if(FD_CurrentFlux < 0)
		{
			FD_CurrentFlux = 0;
			FD_TestDirection = - FD_TestDirection;
		}
		DrawFace();
		break;
	case FD_WORK:	//工作状态
		break;
	default:
		break;
	}
	CStatic::OnTimer(nIDEvent);
}


/////////////////////////////////////////////////////////////////////////////////////////
//函数名:FD_SetStatus(UINT status)
//输入参数:仪表的状态常量status,可以是FD_TEST(自检状态)或者FD_WORK(工作状态)
//返回值:无
//作用:该函数设置仪表的当前状态。
void FluxDevice::FD_SetStatus(UINT status)
{
	FD_Status = status;
	FD_CurrentFlux = 0;
	DrawFace();
}


/////////////////////////////////////////////////////////////////////////////////////////
//函数名:FD_SetCurrentFlux(double flux)
//输入参数:被检测流量的当前值
//返回值:无
//作用:设置被显示流量的当前值。
void FluxDevice::FD_SetCurrentFlux(double flux)
{
	if(FD_Status != FD_WORK)
		return;
	FD_CurrentFlux = flux;
	if(FD_CurrentFlux > FD_MaxFlux)
		FD_CurrentFlux = FD_MaxFlux;
	if(FD_CurrentFlux < 0)
		FD_CurrentFlux = 0;
	DrawFace();
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -