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

📄 oscopectrl.cpp

📁 另外一款开放源码的高质量p2p源码软件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			m_PlotData[iTrend].dCurrentPosition = dNewPoint[iTrend];
		if(bAdd2List)
			m_PlotData[iTrend].lstPoints.AddTail(m_PlotData[iTrend].dCurrentPosition);
		// <-----khaos-
	}
	if(m_nTrendPoints > 0)
	{
		if(CustShift.m_nPointsToDo == 0)
		{
			CustShift.m_nPointsToDo = m_nTrendPoints - 1;
			CustShift.m_nWidthToDo = m_nPlotWidth;
			CustShift.m_nRmndr = 0;
		}
		m_nShiftPixels = (CustShift.m_nWidthToDo + CustShift.m_nRmndr) / CustShift.m_nPointsToDo;
		CustShift.m_nRmndr = (CustShift.m_nWidthToDo + CustShift.m_nRmndr) % CustShift.m_nPointsToDo;
		if(CustShift.m_nPointsToDo == 1)
			m_nShiftPixels = CustShift.m_nWidthToDo;
		CustShift.m_nWidthToDo -= m_nShiftPixels;
		CustShift.m_nPointsToDo--;
	}
	
	// now comes DrawPoint's shift process
	
	if(m_dcPlot.GetSafeHdc() != NULL)
	{
		if(m_nShiftPixels > 0)
		{
			ScrollRect.left = m_rectPlot.left;
			ScrollRect.top  = m_rectPlot.top + 1;
			ScrollRect.right  = m_rectPlot.left + m_nPlotWidth;
			ScrollRect.bottom = m_rectPlot.top + 1 + m_nPlotHeight;
			ScrollRect = m_rectPlot;
			ScrollRect.right ++;
			m_dcPlot.ScrollDC(-m_nShiftPixels, 0, (LPCRECT)&ScrollRect, (LPCRECT)&ScrollRect, NULL, NULL);
			
			// establish a rectangle over the right side of plot
			// which now needs to be cleaned up proir to adding the new point
			rectCleanUp = m_rectPlot;
			rectCleanUp.left  = rectCleanUp.right - m_nShiftPixels + 1;
			rectCleanUp.right ++;
			// fill the cleanup area with the background
			m_dcPlot.FillRect(rectCleanUp, &m_brushBack);
		}
		
		// draw the next line segement
		for(iTrend = 0; iTrend < m_NTrends; iTrend ++)
		{
			currY = m_rectPlot.bottom -
				(long)((m_PlotData[iTrend].dCurrentPosition - m_PlotData[iTrend].dLowerLimit) * m_PlotData[iTrend].dVerticalFactor);
			m_PlotData[iTrend].nPrevY = currY;
			
			// store the current point for connection to the next point
			m_PlotData[iTrend].dPreviousPosition = m_PlotData[iTrend].dCurrentPosition;
		}
	}
	
	// -----------------------------------------
	
	if(bInvalidate && m_bDoUpdate)
		Invalidate();
	
	return;
} // AppendEmptyPoint
 
////////////////////////////////////////////////////////////////////////////
void COScopeCtrl::OnPaint() 
{
	CPaintDC dc(this);  // device context for painting
	CDC memDC;
	CBitmap memBitmap;
	CBitmap* oldBitmap; // bitmap originally found in CMemDC
	
	// no real plotting work is performed here, 
	// just putting the existing bitmaps on the client
	
	// to avoid flicker, establish a memory dc, draw to it 
	// and then BitBlt it to the client
	memDC.CreateCompatibleDC(&dc);
	memBitmap.CreateCompatibleBitmap(&dc, m_nClientWidth, m_nClientHeight);
	oldBitmap = (CBitmap *)memDC.SelectObject(&memBitmap);
	
	if(memDC.GetSafeHdc() != NULL)
	{
		// first drop the grid on the memory dc
		memDC.BitBlt(0, 0, m_nClientWidth, m_nClientHeight, 
			&m_dcGrid, 0, 0, SRCCOPY);
		// now add the plot on top as a "pattern" via SRCPAINT.
		// works well with dark background and a light plot
		memDC.BitBlt(0, 0, m_nClientWidth, m_nClientHeight, 
			&m_dcPlot, 0, 0, SRCPAINT);  // SRCPAINT
		// finally send the result to the display
		dc.BitBlt(0, 0, m_nClientWidth, m_nClientHeight, 
		          &memDC, 0, 0, SRCCOPY);
	}
	memDC.SelectObject(oldBitmap); // FoRcHa
	memBitmap.DeleteObject();
} // OnPaint

/////////////////////////////////////////////////////////////////////////////
void COScopeCtrl::DrawPoint()
{
	// this does the work of "scrolling" the plot to the left
	// and appending a new data point all of the plotting is 
	// directed to the memory based bitmap associated with m_dcPlot
	// the will subsequently be BitBlt'd to the client in OnPaint
	
	int currX, prevX, currY, prevY, iTrend;
	
	CPen *oldPen;
	CRect ScrollRect, rectCleanUp;
	
	if(m_dcPlot.GetSafeHdc() != NULL)
	{
		//	BitBlt was replaced by call to ScrollDC
		//		m_dcPlot.BitBlt(m_rectPlot.left, m_rectPlot.top+1, 
		//		                m_nPlotWidth, m_nPlotHeight, &m_dcPlot, 
		//		                m_rectPlot.left+m_nShiftPixels, m_rectPlot.top+1, 
		//		                SRCCOPY) ;
		if(m_nShiftPixels > 0)
		{
			ScrollRect.left = m_rectPlot.left;
			ScrollRect.top  = m_rectPlot.top + 1;
			ScrollRect.right  = m_rectPlot.left + m_nPlotWidth;
			ScrollRect.bottom = m_rectPlot.top + 1 + m_nPlotHeight;
			ScrollRect = m_rectPlot;
			ScrollRect.right ++;
			m_dcPlot.ScrollDC(-m_nShiftPixels, 0, (LPCRECT)&ScrollRect, (LPCRECT)&ScrollRect, NULL, NULL);
			
			// establish a rectangle over the right side of plot
			// which now needs to be cleaned up proir to adding the new point
			rectCleanUp = m_rectPlot;
			rectCleanUp.left  = rectCleanUp.right - m_nShiftPixels + 1;
			rectCleanUp.right ++;
			// fill the cleanup area with the background
			m_dcPlot.FillRect(rectCleanUp, &m_brushBack);
		}
		
		// draw the next line segement
		for(iTrend = 0; iTrend < m_NTrends; iTrend ++)
		{
			// grab the plotting pen
			oldPen = m_dcPlot.SelectObject(&m_PlotData[iTrend].penPlot);
			
			// move to the previous point
			prevX = m_rectPlot.right - m_nShiftPixels;
			if(m_PlotData[iTrend].nPrevY > 0)
			{
				prevY = m_PlotData[iTrend].nPrevY;
			}
			else
			{
				prevY = m_rectPlot.bottom - 
				(long)((m_PlotData[iTrend].dPreviousPosition - m_PlotData[iTrend].dLowerLimit) * m_PlotData[iTrend].dVerticalFactor);
			}
			m_dcPlot.MoveTo(prevX - 1, prevY);
			// draw to the current point
			currX = m_rectPlot.right;
			currY = m_rectPlot.bottom -
				(long)((m_PlotData[iTrend].dCurrentPosition - m_PlotData[iTrend].dLowerLimit) * m_PlotData[iTrend].dVerticalFactor);
			m_PlotData[iTrend].nPrevY = currY;
			if(abs(prevX - currX) > abs(prevY - currY))
			{
				currX += prevX - currX>0 ? -1 : 1;
			}
			else 
			{
				currY += prevY - currY>0 ? -1 : 1;
			}
			m_dcPlot.LineTo(currX - 1, currY);
			if(drawBars)
				m_dcPlot.LineTo(currX - 1, m_rectPlot.bottom);
			// m_dcPlot.Rectangle(currX-1,currY,currX-1,m_rectPlot.bottom);
			
			// restore the pen 
			m_dcPlot.SelectObject(oldPen);
			
			// if the data leaks over the upper or lower plot boundaries
			// fill the upper and lower leakage with the background
			// this will facilitate clipping on an as needed basis
			// as opposed to always calling IntersectClipRect
			if((prevY <= m_rectPlot.top) || (currY <= m_rectPlot.top))
				m_dcPlot.FillRect(CRect(prevX - 1, m_rectClient.top, currX + 5, m_rectPlot.top + 1), &m_brushBack);
			if((prevY >= m_rectPlot.bottom) || (currY >= m_rectPlot.bottom))
				m_dcPlot.FillRect(CRect(prevX - 1, m_rectPlot.bottom + 1, currX + 5, m_rectClient.bottom + 1), &m_brushBack);
			
			// store the current point for connection to the next point
			m_PlotData[iTrend].dPreviousPosition = m_PlotData[iTrend].dCurrentPosition;
		}
	}
} // end DrawPoint

/////////////////////////////////////////////////////////////////////////////
void COScopeCtrl::OnSize(UINT nType, int cx, int cy)
{
	if ((!cx && !cy) || (cx==m_oldcx && cy==m_oldcy))
		return;

	int iTrend;
	CWnd::OnSize(nType, cx, cy);
	m_oldcx=cx;m_oldcy=cy;
	
	// NOTE: OnSize automatically gets called during the setup of the control
	
	GetClientRect(m_rectClient);
	
	// set some member variables to avoid multiple function calls
	m_nClientHeight = m_rectClient.Height();
	m_nClientWidth  = m_rectClient.Width();
	
	// the "left" coordinate and "width" will be modified in
	// InvalidateCtrl to be based on the width of the y axis scaling
	m_rectPlot.left   = 20; 
	m_rectPlot.top    = 10;
	m_rectPlot.right  = m_rectClient.right - 10;
	m_rectPlot.bottom = m_rectClient.bottom - 25;
	
	// set some member variables to avoid multiple function calls
	m_nPlotHeight = m_rectPlot.Height();
	m_nPlotWidth  = m_rectPlot.Width();
	
	// set the scaling factor for now, this can be adjusted
	// in the SetRange functions
	for(iTrend = 0; iTrend < m_NTrends; iTrend ++)
		m_PlotData[iTrend].dVerticalFactor = (double)m_nPlotHeight / m_PlotData[iTrend].dRange;
	
	// destroy and recreate the grid bitmap
	CClientDC dc(this); 
	if(m_pbitmapOldGrid && m_bitmapGrid.GetSafeHandle() && m_dcGrid.GetSafeHdc())
	{
		m_dcGrid.SelectObject(m_pbitmapOldGrid);
		m_bitmapGrid.DeleteObject();
		m_bitmapGrid.CreateCompatibleBitmap(&dc, m_nClientWidth, m_nClientHeight);
		m_pbitmapOldGrid = m_dcGrid.SelectObject(&m_bitmapGrid);
	}
	
	// destroy and recreate the plot bitmap
	if(m_pbitmapOldPlot && m_bitmapPlot.GetSafeHandle() && m_dcPlot.GetSafeHdc())
	{
		m_dcPlot.SelectObject(m_pbitmapOldPlot);
		m_bitmapPlot.DeleteObject();
		m_bitmapPlot.CreateCompatibleBitmap(&dc, m_nClientWidth, m_nClientHeight);
		m_pbitmapOldPlot = m_dcPlot.SelectObject(&m_bitmapPlot);
	}
	
	InvalidateCtrl();
} // OnSize


/////////////////////////////////////////////////////////////////////////////
void COScopeCtrl::Reset()
{
	// to clear the existing data (in the form of a bitmap)
	// simply invalidate the entire control
	InvalidateCtrl();
}

int COScopeCtrl::ReCreateGraph(void)
{
	int i;
	for(i = 0; i < m_NTrends; i++)
	{
		m_PlotData[i].dPreviousPosition = 0.0;
		m_PlotData[i].nPrevY = -1;
	}
	
	double *pAddPoints = new double[m_NTrends];
	
	int iCnt = m_PlotData[0].lstPoints.GetCount();
	for(i = 0; i < iCnt; i++)
	{	
		for(int iTrend = 0; iTrend < m_NTrends; iTrend++)
		{
			POSITION pos = m_PlotData[iTrend].lstPoints.FindIndex(i);
			if(pos)
				pAddPoints[iTrend] = m_PlotData[iTrend].lstPoints.GetAt(pos);
			else
				pAddPoints[iTrend] = 0;
		}
		// -khaos--+++> Pass false for new bUseTrendRatio parameter so that graph is recreated correctly...
		AppendPoints(pAddPoints, false, false, false);
		// <-----khaos-
	}
	
	delete[] pAddPoints;

	return 0;
}

void COScopeCtrl::OnTimer(UINT nIDEvent)
{
	if(nIDEvent == m_nRedrawTimer)
	{
		KillTimer(m_nRedrawTimer);
		m_nRedrawTimer = 0;
		m_bDoUpdate = true;
		ReCreateGraph();
	}

	CWnd::OnTimer(nIDEvent);
}

⌨️ 快捷键说明

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