📄 oscopectrl.cpp
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "stdafx.h"
#include <math.h>
#include "emule.h"
#include "OScopeCtrl.h"
#include "emuledlg.h"
#include "Preferences.h"
#include "OtherFunctions.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// COScopeCtrl
COScopeCtrl::COScopeCtrl(int NTrends)
{
int i;
COLORREF PresetColor[16] =
{
RGB(0xFF, 0x00, 0x00),
RGB(0xFF, 0xC0, 0xC0),
RGB(0xFF, 0xFF, 0x00),
RGB(0xFF, 0xA0, 0x00),
RGB(0xA0, 0x60, 0x00),
RGB(0x00, 0xFF, 0x00),
RGB(0x00, 0xA0, 0x00),
RGB(0x00, 0x00, 0xFF),
RGB(0x00, 0xA0, 0xFF),
RGB(0x00, 0xFF, 0xFF),
RGB(0x00, 0xA0, 0xA0),
RGB(0xC0, 0xC0, 0xFF),
RGB(0xFF, 0x00, 0xFF),
RGB(0xA0, 0x00, 0xA0),
RGB(0xFF, 0xFF, 0xFF),
RGB(0x80, 0x80, 0x80)
};
// since plotting is based on a LineTo for each new point
// we need a starting point (i.e. a "previous" point)
// use 0.0 as the default first point.
// these are public member variables, and can be changed outside
// (after construction).
// G.Hayduk: NTrends is the number of trends that will be drawn on
// the plot. First 15 plots have predefined colors, but others will
// be drawn with white, unless you call SetPlotColor
m_PlotData = new PlotData_t[NTrends];
m_NTrends = NTrends;
for(i = 0; i < m_NTrends; i++)
{
if(i < 15)
m_PlotData[i].crPlotColor = PresetColor[i]; // see also SetPlotColor
else
m_PlotData[i].crPlotColor = RGB(255, 255, 255); // see also SetPlotColor
m_PlotData[i].penPlot.CreatePen(PS_SOLID, 0, m_PlotData[i].crPlotColor);
m_PlotData[i].dPreviousPosition = 0.0;
m_PlotData[i].nPrevY = -1;
m_PlotData[i].dLowerLimit = -10.0;
m_PlotData[i].dUpperLimit = 10.0;
m_PlotData[i].dRange = m_PlotData[i].dUpperLimit -
m_PlotData[i].dLowerLimit; // protected member variable
m_PlotData[i].lstPoints.AddTail(0.0);
// Initialize our new trend ratio variable to 1
m_PlotData[i].iTrendRatio = 1;
m_PlotData[i].LegendLabel.Format(_T("Legend %i"),i);
m_PlotData[i].BarsPlot = false;
}
// public variable for the number of decimal places on the y axis
// G.Hayduk: I've deleted the possibility of changing this parameter
// in SetRange, so change it after constructing the plot
m_nYDecimals = 1;
// set some initial values for the scaling until "SetRange" is called.
// these are protected varaibles and must be set with SetRange
// in order to ensure that m_dRange is updated accordingly
// m_nShiftPixels determines how much the plot shifts (in terms of pixels)
// with the addition of a new data point
drawBars = false;
autofitYscale = false;
m_nShiftPixels = 1;
m_nTrendPoints = 0;
m_nMaxPointCnt = 1024;
CustShift.m_nPointsToDo = 0;
// G.Hayduk: actually I needed an OScopeCtrl to draw specific number of
// data samples and stretch them on the plot ctrl. Now, OScopeCtrl has
// two modes of operation: fixed Shift (when m_nTrendPoints=0,
// m_nShiftPixels is in use), or fixed number of Points in the plot width
// (when m_nTrendPoints>0)
// When m_nTrendPoints>0, CustShift structure is in use
// background, grid and data colors
// these are public variables and can be set directly
m_crBackColor = RGB(0, 0, 0); // see also SetBackgroundColor
m_crGridColor = RGB(0, 255, 255); // see also SetGridColor
// protected variables
m_brushBack.CreateSolidBrush(m_crBackColor);
// public member variables, can be set directly
m_str.XUnits.Format(_T("Samples")); // can also be set with SetXUnits
m_str.YUnits.Format(_T("Y units")); // can also be set with SetYUnits
// protected bitmaps to restore the memory DC's
m_pbitmapOldGrid = NULL;
m_pbitmapOldPlot = NULL;
// G.Hayduk: configurable number of grids init
// you are free to change those between contructing the object
// and calling Create
m_nXGrids = 6;
m_nYGrids = 5;
m_nTrendPoints = -1;
m_bDoUpdate = true;
m_nRedrawTimer = 0;
ready = false;
} // COScopeCtrl
/////////////////////////////////////////////////////////////////////////////
COScopeCtrl::~COScopeCtrl()
{
// just to be picky restore the bitmaps for the two memory dc's
// (these dc's are being destroyed so there shouldn't be any leaks)
if(m_pbitmapOldGrid != NULL)
m_dcGrid.SelectObject(m_pbitmapOldGrid);
if(m_pbitmapOldPlot != NULL)
m_dcPlot.SelectObject(m_pbitmapOldPlot);
delete[] m_PlotData;
// G.Hayduk: If anyone notices that I'm not freeing or deleting
// something, please let me know: hayduk@hello.to
} // ~COScopeCtrl
BEGIN_MESSAGE_MAP(COScopeCtrl, CWnd)
//{{AFX_MSG_MAP(COScopeCtrl)
ON_WM_PAINT()
ON_WM_SIZE()
//}}AFX_MSG_MAP
ON_WM_TIMER()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COScopeCtrl message handlers
/////////////////////////////////////////////////////////////////////////////
BOOL COScopeCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
{
BOOL result;
static CString className = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW);
result = CWnd::CreateEx(WS_EX_CLIENTEDGE /*| WS_EX_STATICEDGE*/,
className, NULL, dwStyle,
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
pParentWnd->GetSafeHwnd(), (HMENU)nID);
if(result != 0)
InvalidateCtrl();
InitWindowStyles(this);
ready=true;
return result;
} // Create
/////////////////////////////////////////////////////////////////////////////
// Set Trend Ratio
// This allows us to set a ratio for a trend in our plot. Basically, this
// trend will be divided by whatever the ratio was set to, so that we can have
// big numbers and little numbers in the same plot. Wrote this especially for
// eMule.
// iTrend is an integer specifying which trend of this plot we should set the
// ratio for.
// iRatio is an integer defining what we should divide this trend's data by.
// For example, to have a 1:2 ratio of Y-Scale to this trend, iRatio would be 2.
// iRatio is 1 by default (No change in scale of data for this trend)
// This function now borrows a bit from eMule Plus v1
void COScopeCtrl::SetTrendRatio(int iTrend, unsigned int iRatio)
{
ASSERT(iTrend < m_NTrends && iRatio > 0); // iTrend must be a valid trend in this plot.
if (iRatio != m_PlotData[iTrend].iTrendRatio) {
double dTrendModifier = (double) m_PlotData[iTrend].iTrendRatio / iRatio;
m_PlotData[iTrend].iTrendRatio = iRatio;
//m_PlotData[iTrend].dPreviousPosition = 0.0;
//m_PlotData[iTrend].nPrevY = -1;
int iCnt = m_PlotData[iTrend].lstPoints.GetCount();
for(int i = 0; i < iCnt; i++)
{
POSITION pos = m_PlotData[iTrend].lstPoints.FindIndex(i);
if(pos)
m_PlotData[iTrend].lstPoints.SetAt(pos,m_PlotData[iTrend].lstPoints.GetAt(pos)*dTrendModifier);
}
InvalidateCtrl();
}
}
void COScopeCtrl::SetLegendLabel(CString string, int iTrend)
{
m_PlotData[iTrend].LegendLabel = string;
InvalidateCtrl(false);
}
void COScopeCtrl::SetBarsPlot(bool BarsPlot, int iTrend)
{
m_PlotData[iTrend].BarsPlot = BarsPlot;
InvalidateCtrl(false);
}
void COScopeCtrl::SetRange(double dLower, double dUpper, int iTrend)
{
ASSERT(dUpper > dLower);
m_PlotData[iTrend].dLowerLimit = dLower;
m_PlotData[iTrend].dUpperLimit = dUpper;
m_PlotData[iTrend].dRange = m_PlotData[iTrend].dUpperLimit - m_PlotData[iTrend].dLowerLimit;
m_PlotData[iTrend].dVerticalFactor = (double)m_nPlotHeight / m_PlotData[iTrend].dRange;
// clear out the existing garbage, re-start with a clean plot
InvalidateCtrl();
} // SetRange
void COScopeCtrl::SetRanges(double dLower, double dUpper)
{
int iTrend;
ASSERT(dUpper > dLower);
for(iTrend = 0; iTrend < m_NTrends; iTrend ++)
{
m_PlotData[iTrend].dLowerLimit = dLower;
m_PlotData[iTrend].dUpperLimit = dUpper;
m_PlotData[iTrend].dRange = m_PlotData[iTrend].dUpperLimit - m_PlotData[iTrend].dLowerLimit;
m_PlotData[iTrend].dVerticalFactor = (double)m_nPlotHeight / m_PlotData[iTrend].dRange;
}
// clear out the existing garbage, re-start with a clean plot
InvalidateCtrl();
} // SetRanges
/////////////////////////////////////////////////////////////////////////////
// G.Hayduk: Apart from setting title of axis, now you can optionally set
// the limits strings
// (string which will be placed on the left and right of axis)
void COScopeCtrl::SetXUnits(CString string, CString XMin, CString XMax)
{
m_str.XUnits = string;
m_str.XMin = XMin;
m_str.XMax = XMax;
InvalidateCtrl(false);
} // SetXUnits
/////////////////////////////////////////////////////////////////////////////
// G.Hayduk: Apart from setting title of axis, now you can optionally set
// the limits strings
// (string which will be placed on the bottom and top of axis)
void COScopeCtrl::SetYUnits(CString string, CString YMin, CString YMax)
{
m_str.YUnits = string;
m_str.YMin = YMin;
m_str.YMax = YMax;
// clear out the existing garbage, re-start with a clean plot
InvalidateCtrl();
} // SetYUnits
/////////////////////////////////////////////////////////////////////////////
void COScopeCtrl::SetGridColor(COLORREF color)
{
m_crGridColor = color;
// clear out the existing garbage, re-start with a clean plot
InvalidateCtrl();
} // SetGridColor
/////////////////////////////////////////////////////////////////////////////
void COScopeCtrl::SetPlotColor(COLORREF color, int iTrend)
{
m_PlotData[iTrend].crPlotColor = color;
m_PlotData[iTrend].penPlot.DeleteObject();
m_PlotData[iTrend].penPlot.CreatePen(PS_SOLID, 0, m_PlotData[iTrend].crPlotColor);
// clear out the existing garbage, re-start with a clean plot
// InvalidateCtrl() ;
} // SetPlotColor
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -