📄 quakeview.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 + -