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

📄 quakeview.cpp

📁 本程序源码是为日本一家地震监测机构编写的
💻 CPP
字号:
// QuakeView.cpp : implementation file
//

#include "stdafx.h"
#include "CQuakeDemo.h"
#include "QuakeView.h"

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

//线程安全////////////////////////////////////////////////////////////////
CCriticalSection g_CriSection;
//////////////////////////////////////////////////////////////////////////

// CQuakeView

IMPLEMENT_DYNCREATE(CQuakeView, CBaseView)

CQuakeView::CQuakeView()
{
	m_XPicRate		=	0.5;			//图片的显示区域的大小长度比例
	m_YPicRate		=	1;
	
	m_PicSpace		=	2;				//图片上下的间隔大小(像素单位)
	
	m_MemBKCor		=	RGB(0,0,0);		//震动区域的背景颜色
	
	m_pDIArray		=	new DrawItemArray;//数据接口类变量初始化
	m_pTempSave		=	m_pDIArray;
	
	m_pFileManager	=	NULL;
	m_pDrawManager	=	NULL;
	m_pWarnList		=	NULL;
	
	m_CurRate		=	0.0;
	m_bModify		=	FALSE;			//Mark设置记录
	m_nFloorSize	=	0;
	//加载图标
	m_YellowMark	=	AfxGetApp()->LoadIcon(IDI_ICON_YELLOW);
	m_RedMark		=	AfxGetApp()->LoadIcon(IDI_ICON_RED);	
	m_LogoPicPN		=	"Logo.jpg";
}

CQuakeView::~CQuakeView()
{
	delete m_pTempSave;
}


BEGIN_MESSAGE_MAP(CQuakeView, CBaseView)
	//{{AFX_MSG_MAP(CQuakeView)
	ON_WM_ERASEBKGND()
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CQuakeView drawing

void CQuakeView::OnDraw(CDC* pDC)
{	
	BitBltMemDC(pDC);
}

/////////////////////////////////////////////////////////////////////////////
// CQuakeView diagnostics

#ifdef _DEBUG
void CQuakeView::AssertValid() const
{
	CBaseView::AssertValid();
}

void CQuakeView::Dump(CDumpContext& dc) const
{
	CBaseView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CQuakeView message handlers

BOOL CQuakeView::OnEraseBkgnd(CDC* pDC) 
{/*禁止背景重画*/return TRUE;}


//设置绘图模式
void CQuakeView::SetDrawType(DrawType type/* = DT_Userdefined/**/)
{
	m_DrawType = type;
}

//获得绘图模式
DrawType CQuakeView::GetDrawType() const
{
	return m_DrawType;
}

////////////////////////////////////////////////////////////////////////////////////
//图像文件处理函数
////////////////////////////////////////////////////////////////////////////////////
int  CQuakeView::GetFloorSize()const
{
	return 	m_pDIArray->GetSize();
}
////////////////////////////////////////////////////////////////////////////////////
//警告操作函数
////////////////////////////////////////////////////////////////////////////////////
void CQuakeView::SetRedMark(int index)
{
	if(!(*m_pDIArray)[index].bRMark)
	{
		(*m_pDIArray)[index].bRMark = TRUE;
		m_bModify = TRUE;		
	}
}

void CQuakeView::SetYellowMark(int index)
{
	if(!(*m_pDIArray)[index].bYMark)
	{
		(*m_pDIArray)[index].bYMark = TRUE;
		m_bModify = TRUE;
	}	
}

void CQuakeView::ResetMark()
{
	for(int i = 0; i < m_pDIArray->GetSize(); i++)
	{
		(*m_pDIArray)[i].bRMark = FALSE;
		(*m_pDIArray)[i].bYMark = FALSE;
	}
	m_bModify = TRUE;
}

void CQuakeView::ShowMark()
{
	if(!m_bModify)return;
	UpdateView();
	m_bModify = FALSE;
}

////////////////////////////////////////////////////////////////////////////////////
//区域计算函数
////////////////////////////////////////////////////////////////////////////////////

//计算整个客户区域,区域分配计算关键主要函数
void CQuakeView::CalcDrawRect(const CRect &MemRect)
{	
	m_QuakeRect = m_MemRect = MemRect;
	double temp = m_QuakeRect.Width();
	int xpic = int(temp * m_XPicRate);
	temp = m_QuakeRect.Height();
	int ypic = int(temp * m_YPicRate);
	CRectPlus::CalcSizeInRect(m_QuakeRect,CSize(xpic,ypic),m_PicRect);
}

/********************************************************************
Name  : CalcPicRect
~~~~~~
Does  : 用m_PicRect计算m_DIArray中的每个图片矩形面积
~~~~~~
InPut : bKScale是否保持比例绘制楼层图片
~~~~~~
OutPut: 更新计算m_pDIArray中的数据
~~~~~~	
Remark: 更新数据:	m_pDIArray->drect 图片矩形
~~~~~~				m_pDIArray->RRect  红色警告矩形
					m_pDIArray->YRect  黄色警告矩形
*********************************************************************/
void CQuakeView::CalcPicRect(BOOL bKScale /*=TRUE*/)
{
	if(m_pDIArray->GetSize() == 0) return;
	//计算内矩形长宽/////////////////////////////////////////////////
	float xtotal(0),ytotal(0);
	//图片高度之间的修正高度总和
	int space(0);              
	for(int i = 0; i < m_pDIArray->GetSize(); i++)
	{
		if(xtotal < (*m_pDIArray)[i].pic.m_Width)
		{
			xtotal = float((*m_pDIArray)[i].pic.m_Width);
		}
		ytotal += (*m_pDIArray)[i].pic.m_Height;		
	}
	//高度要修正去掉 m_PicSpace 的高度
	space = m_PicSpace * (m_pDIArray->GetSize() - 1);
	//计算合适的比例/////////////////////////////////////////////////
	float rateX(0), rateY(0);
	CRectPlus::CalcProperRate(CPoint(int(xtotal),int(ytotal)),CPoint(m_PicRect.Width(),m_PicRect.Height()-space),rateX,rateY,bKScale);
	//最终计算每个图片的矩形区域////////////////////////////////////
	//记录绘图的左上角坐标
	int x(0),y(0);
	int nTinyModify = m_PicRect.Height()%m_pDIArray->GetSize();
	nTinyModify = nTinyModify/2;
	y = (m_PicRect.Height() - space - int(rateY * ytotal))/2 + m_PicRect.top + nTinyModify;
	
	CSize sico(16,16);
	CRect temprect;

	for(i = 0; i < m_pDIArray->GetSize(); i++)
	{
		if(bKScale)
		{
			x = ((m_PicRect.Width() - int(rateX * (*m_pDIArray)[i].pic.m_Width))/2)+m_PicRect.left;
			(*m_pDIArray)[i].drect.left    = x;
			(*m_pDIArray)[i].drect.right   = x + int(rateX * (*m_pDIArray)[i].pic.m_Width);
		}
		else
		{
			(*m_pDIArray)[i].drect.left  = m_PicRect.left;
			(*m_pDIArray)[i].drect.right = m_PicRect.right;
		}
		(*m_pDIArray)[i].drect.top     = y;		
		(*m_pDIArray)[i].drect.bottom  = y + int(rateY * (*m_pDIArray)[i].pic.m_Height);
		(*m_pDIArray)[i].drect.NormalizeRect();
		y += (int(rateY * (*m_pDIArray)[i].pic.m_Height) + m_PicSpace);
		(*m_pDIArray)[i].disp = 0;
		//计算警告标志区域
		CRectPlus::CalcSizeInRect((*m_pDIArray)[i].drect,sico,temprect);
		(*m_pDIArray)[i].RRect       = temprect;
		(*m_pDIArray)[i].RRect.left  = (*m_pDIArray)[i].drect.left;
		(*m_pDIArray)[i].RRect.right = (*m_pDIArray)[i].drect.left + sico.cx;

		(*m_pDIArray)[i].YRect       = temprect;
		(*m_pDIArray)[i].YRect.right = (*m_pDIArray)[i].drect.right;
		(*m_pDIArray)[i].YRect.left  = (*m_pDIArray)[i].drect.right - sico.cx;
	}
}

/********************************************************************
Name  : CreateMemPic
~~~~~~
Does  : 生成内存图像
~~~~~~
InPut : 绘图设备指针
~~~~~~
OutPut: None
~~~~~~	
Time  : 2005:4:16   19:23
~~~~~~	
*********************************************************************/
void CQuakeView::CreateMemPic(CDC *pDC)
{
	CDC *pMemDC = CreateMemDC(pDC);
	//绘制图片///////////////////////////////////
	pMemDC->FillSolidRect(m_MemRect,m_MemBKCor);
	if(m_pDIArray->GetSize() == 0)
	{			
		DrawLogo(pMemDC,m_QuakeRect);
	}
	else
	{
		for(int i = 0; i < m_pDIArray->GetSize(); i++)
		{
			(*m_pDIArray)[i].pic.Show(pMemDC,(*m_pDIArray)[i].drect);
			if((*m_pDIArray)[i].bRMark)
				pMemDC->DrawIcon((*m_pDIArray)[i].RRect.TopLeft(),m_RedMark);
			if((*m_pDIArray)[i].bYMark)
				pMemDC->DrawIcon((*m_pDIArray)[i].YRect.TopLeft(),m_YellowMark);
		}
	}
}

void CQuakeView::DrawLogo(CDC* pDC, LPCRECT drect)
{	
	if(IsFileExist(m_LogoPicPN))
	{
		CRect rect;
		m_LogoPic.Load(m_LogoPicPN);
		CSize PicSize(m_LogoPic.m_Width,m_LogoPic.m_Height);
		CRectPlus::CalcSizeInRect(drect,PicSize,rect);
		m_LogoPic.Show(pDC,rect);
	}
	else
	{
		pDC->SetTextColor(RGB(0,255,0));
		pDC->SetBkColor(RGB(0,0,0));	
		pDC->TextOut(drect->left,drect->top,"******");
	}
}

/********************************************************************
Name  : TimeProc()/QuakeDraw()
~~~~~~
Does  : 绘制震动图像
~~~~~~
InPut : None,Use Class Member
~~~~~~
OutPut: 如果读取数据结束则返回FALSE,否则返回TRUE
~~~~~~	
Time  : 2005:4:16   19:16
~~~~~~	
*********************************************************************/
void CQuakeView::TimeProc()
{
	g_CriSection.Lock();

	static int		nDisp;			//保存数据文件或得的位移量
	static int		nDrawDisp;		//保存绘图的位移量
	static CRect	UpdateRect;		//保存绘图更新的矩形区域
	static int		MaxDrawDisp;	//最大绘图位移
	//计算绘图允许的最大位移
	MaxDrawDisp = m_PicRect.left - m_QuakeRect.left;		
	//绘制图片/楼层的数据和数组的序号是相反的/下标为0的数据是顶层的数据
	CDC *pMemDC = GetMemDC();
	for(int i = 0; i < m_nFloorSize; i++)
	{
		//从数据源获得数据
		m_pFileManager->GetStepData(i,m_DispBuffer[i]);
		//数据处理
		Process(i,MaxDrawDisp,nDisp);
		//滚动绘图
		nDrawDisp = (*m_pDIArray)[i].disp - nDisp;
		pMemDC->ScrollDC(nDrawDisp,0,(*m_pDIArray)[i].drect,NULL,NULL,UpdateRect);
		pMemDC->FillSolidRect(UpdateRect,m_MemBKCor);
		(*m_pDIArray)[i].drect.left  += nDrawDisp;
		(*m_pDIArray)[i].drect.right += nDrawDisp;		
		(*m_pDIArray)[i].disp = nDisp;
		//警告标志判断
		if(m_MaxDispArray[i].Disp > (*m_pWarnList)[i].fRed)
			SetRedMark(i);
		if(m_MaxDispArray[i].Disp > (*m_pWarnList)[i].fYellow)
			SetYellowMark(i);
		ShowMark();
	}
    //拷屏显示
	CClientDC dc(this);
	BitBltMemDC(&dc);
	g_CriSection.Unlock();
}

/********************************************************************
Name  : Process
~~~~~~
Does  : 处理文件的原始数据
~~~~~~
InPut : Index:楼层索引号 dispitem:楼层的位移数 MaxDrawDisp:绘图允许的最大位移
~~~~~~
OutPut: The return value always to be TRUE, drawdisp为最终计算得出的绘图位移
~~~~~~	
Time  : 2005:4:16   18:34
~~~~~~	
*********************************************************************/
BOOL CQuakeView::Process(int index, const int &MaxDrawDisp, int &drawdisp)
{	
	//倍率处理,计算绘图位移
	switch(m_DrawType)
	{
	case DT_Userdefined:
		{
			drawdisp = int(m_DispBuffer[index].Disp * m_CurRate * (-1));
			if(abs(drawdisp) > MaxDrawDisp)
				drawdisp > 0 ? drawdisp = MaxDrawDisp : drawdisp = MaxDrawDisp * (-1);
		}
		break;
	case DT_Auto:
		break;
	}
	//更新最大位移链表
	static double fDisp;
	if(index == (m_nFloorSize-1))
		fDisp = fabs(m_DispBuffer[index].Disp);
	else
		fDisp = fabs(m_DispBuffer[index].Disp - m_DispBuffer[index+1].Disp);
	//判断最大偏移位移,满足条件是的时候更新最大偏移位移
	if(fDisp > m_MaxDispArray[index].Disp)
	{
		m_MaxDispArray[index].Disp = fDisp;
		m_MaxDispArray[index].Time = m_DispBuffer[index].Time;
	}
	return TRUE;
}

void CQuakeView::SetRate(double rate)
{
	g_CriSection.Lock();
	m_CurRate = rate;
	g_CriSection.Unlock();
}

void CQuakeView::GetBufferAt(int index, DispStruct &dispitem)const
{
	g_CriSection.Lock();
	dispitem  =  m_DispBuffer[index];
	g_CriSection.Unlock();
}

void CQuakeView::GetMaxDisp(int index, DispStruct &dispitem)
{
	g_CriSection.Lock();
	dispitem = m_MaxDispArray[index];
	g_CriSection.Unlock();
}

void CQuakeView::OnSize(UINT nType, int cx, int cy) 
{
	CBaseView::OnSize(nType, cx, cy);	
	UpdateView();
}

void CQuakeView::SetFileManager(CQuakeFileManager* pFileManager)
{
	ASSERT(pFileManager != NULL);
	m_pFileManager = pFileManager;
}

void CQuakeView::SetDrawManager(CQuakeDrawManager* pDrawManager)
{
	ASSERT(pDrawManager != NULL);
	m_pDrawManager = pDrawManager;
	//初始化其他子对象
	m_pDIArray	= &(pDrawManager->m_DIArray);
	m_pWarnList = &(pDrawManager->m_WarnList);	
}

void CQuakeView::UpdateView()
{	
	//重新生成图像
	g_CriSection.Lock();
	CRect ClientRect;
	GetClientRect(ClientRect);
	
	CalcDrawRect(ClientRect);	
	CalcPicRect();              //根据计算出来图片的矩形面积,计算每个图片的矩形位置
	CClientDC dc(this);
	CreateMemPic(&dc);		    //生成内存图像	
	InvalidateRect(m_MemRect);  //更新显示图像
	g_CriSection.Unlock();
}

void CQuakeView::ClearView()
{
	ASSERT(m_pFileManager != NULL);
	m_DispBuffer.RemoveAll();
	m_MaxDispArray.RemoveAll();
	m_DispBuffer.SetSize(m_nFloorSize);//准备数据缓冲区
	m_MaxDispArray.SetSize(m_nFloorSize);//准备记录正负最大偏移链表	
}

void CQuakeView::OnInitialUpdate() 
{
	CBaseView::OnInitialUpdate();
	//更新文件和绘图数据
	if(m_pFileManager != NULL)
	{
		m_nFloorSize =	m_pFileManager->GetFileCount();
		
		m_DispBuffer.RemoveAll();
		m_MaxDispArray.RemoveAll();
		m_DispBuffer.SetSize(m_nFloorSize);//准备数据缓冲区
		m_MaxDispArray.SetSize(m_nFloorSize);//准备记录正负最大偏移链表
	}
}





















⌨️ 快捷键说明

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