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

📄 curvectrl.cpp

📁 功能非常强大的数据采集系统
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// 参数:
//-------------------------------------------------------------------------------------------------
void CCurveCtrl::ShowCross(BOOL bShow)
{
	m_bShowCross = bShow;
}

//-------------------------------------------------------------------------------------------------
// 功能:
// 参数:
//-------------------------------------------------------------------------------------------------
BOOL CCurveCtrl::IsShowCross()
{
	return m_bShowCross;
}

// description : set margin, leave a blank in each direction outside of drawing area 
//               to show title, label, and so on
void CCurveCtrl::SetMargin(const CRect& rect)
{
	m_Margin = rect;
}

CRect CCurveCtrl::GetMargin()
{
	return m_Margin;
}

// enable/disable edit by using mouse key operation
void CCurveCtrl::EnableEdit(BOOL bEdit)
{
	if (GetSelectedCount() > 0)
		m_bEdit = bEdit;
	else
		m_bEdit = FALSE;
}

BOOL CCurveCtrl::CanEditCurve()
{
	return m_bEdit;
}

void CCurveCtrl::SetGridLineStyle(int iStyle)
{
	m_iGridLineStyle = iStyle;
}

int	 CCurveCtrl::GetGridLineStyle()
{
	return m_iGridLineStyle;
}

// description : non-edit mode: select/deselect one or more(by Shift or Ctrl key pressed) curves 
//                              by clicking left button of mouse;
//               edit mode: if parameter "point" is near key point of a curve, select key point and ready to move;
//                          if parameter "point" is not near key point but near to line between two key points, add key point.
//                          note that the edited curve must be selected before editing.
//                
void CCurveCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
{
	//鼠标拖动图形:记录起点
	m_pPoint=point;														//保存鼠标按下的点

	//disable tooltip	
	if (m_Tooltip.m_hWnd)
		m_Tooltip.Activate(FALSE);										//tooltip无效
	
	int iPt = -1;
	CCurve*	 pCurentCur = NULL;											//绘图的指针
	
	//has any curve near point
	for (int iIndex = 0; iIndex < m_ArrCurve.GetSize(); iIndex++)		//查找所有的曲线
	{
		if (m_ArrCurve[iIndex]->IsPointNearCurve(point, iPt))			//鼠标位置在曲线的边缘?
		{
			pCurentCur = m_ArrCurve[iIndex];							//是:获得绘制曲线的指针
			break;
		}
	}

	// calculate value by point in pixel
	float fHori = 0.0f, fVert = 0.0f;									//临时变量
	if (pCurentCur)														//有效的绘图指针?
	{
		if (iPt > -1)													//???在在曲线范围外
		{
			fHori = pCurentCur->m_fArrHoriValue[iPt];
			fVert = pCurentCur->m_fArrVertValue[iPt];
		}
		else															//???在曲线范围内
		{
			CalculateValue(point, fHori, fVert);
		}
	}
	
	// non-edit mode
	if (!m_bEdit)
	{			
		// multi-select if Ctrl or Shift key are pressed
		if ((nFlags & MK_CONTROL) == MK_CONTROL || (nFlags & MK_SHIFT) == MK_SHIFT)
		{
			if (pCurentCur)
			{				
				// save previous status(selected or not) 
				BOOL bOldSel = pCurentCur->m_bSelected;
				// change status of the curve (deselected or not)
				pCurentCur->m_bSelected = !pCurentCur->m_bSelected;
				
				// send message to owner
				int nMsg = pCurentCur->m_bSelected ? CVN_CURVE_SELECTED : CVN_CURVE_CANCELSELECT;					
				BOOL bKeepOld = SendMessageToParent(nMsg,
													pCurentCur,
													iIndex,	// curve index in this CCurveCtrl
													fHori,
													fVert					
													);
				// restore previous status if owner does not permit to change 
				if (bKeepOld)
				{
					pCurentCur->m_bSelected = bOldSel;
				}
			}
		}
		else // single-select
		{			
			// deselect all curve
			for (int iQ = 0; iQ < m_ArrCurve.GetSize(); iQ++)
			{
				m_ArrCurve[iQ]->m_bSelected = FALSE;
			}

			if (pCurentCur != NULL)
			{		
				// save previous status(selected or not) 
				BOOL bOldSel = pCurentCur->m_bSelected;
				// change status of the curve (deselected or not)
				pCurentCur->m_bSelected = !pCurentCur->m_bSelected;

				// send message to owner
				int nMsg = pCurentCur->m_bSelected ? CVN_CURVE_SELECTED : CVN_CURVE_CANCELSELECT;					
				BOOL bKeepOld = SendMessageToParent(nMsg,
													pCurentCur,
													iIndex,	// curve index in this CCurveCtrl
													fHori,
													fVert					
													);
				// restore previous status if owner does not permit to change 
				if (bKeepOld)
				{
					pCurentCur->m_bSelected = bOldSel;
				}
			}
			else 			// send message to owner if no curve is selected 
			{
				SendMessageToParent(CVN_CURVE_SELECTNONE,
							        pCurentCur,
									-1, // no curve selected
									fHori,
									fVert
									);
				
				// disable edit mode if no curve selected
				m_bEdit = FALSE;
			}
		}
	}
	else if(pCurentCur && pCurentCur->IsSelected())// under edit mode, the edited curve must be selected already
	{
		// if index of key point of the curve is valid, move point when mouse move
		if (iPt >= 0)
		{
			m_iCurPoint  = iPt;
			m_pCurveEdit = pCurentCur;
			SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
			SetCapture();

			// save value before moving
			m_fOldHori = pCurentCur->m_fArrHoriValue[iPt];
			m_fOldVert = pCurentCur->m_fArrVertValue[iPt];
		}
		else // if index invalidate, then add key point to the curve
		{			
			// calculate value by point
			float fHori, fVert;
			CalculateValue(point, fHori, fVert);
			
			// insert values to sorted data arrays, and get the index of the new key point
			int iH = InsertDataToCurve(pCurentCur, fHori, fVert, point);

			// to notify owner that new key point is added 
			int bDontAdd = SendMessageToParent(CVN_MVALUE_ADD, 
											pCurentCur, 
											iH, 
											fHori,
											fVert
											);			
			// whether to add the new point is determined by owner
			if (bDontAdd)
			{
				pCurentCur->m_fArrHoriValue.RemoveAt(iH);
				pCurentCur->m_fArrVertValue.RemoveAt(iH);
				pCurentCur->m_ArrPoint.RemoveAt(iH);
			}
			
			m_iCurPoint  = -1;
			m_pCurveEdit = NULL;
		}
	}
	
	Invalidate();
	
	CWnd::OnLButtonDown(nFlags, point);
}

//-------------------------------------------------------------------------------------------------
// 功能:non-edit mode: refresh to draw cross(if shown) and tooltip
//           edit mode: change cursor and move the selected key point
// 参数:nFlags:
//		  point:mouse坐标点
//-------------------------------------------------------------------------------------------------
void CCurveCtrl::OnMouseMove(UINT nFlags, CPoint point) 
{	
	// change point if has any key point selected
	return;
	if (m_bEdit && m_pCurveEdit && m_iCurPoint >= 0)
	{
		SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
		
		float fHori, fVert;
		if (CalculateValue(point, fHori, fVert))
		{
			// change vertical value only
			m_pCurveEdit->m_ArrPoint[m_iCurPoint].y = point.y;
			m_pCurveEdit->m_fArrVertValue[m_iCurPoint] = fVert;		
		}
	}
	else
	{		
		// if there is any key point nearby
		int iPoint = -1;
		CCurve* pCurentCur = NULL;
		for (int iIndex = 0; iIndex < m_ArrCurve.GetSize(); iIndex++)
		{
			if (m_ArrCurve[iIndex]->IsPointNearCurve(point, iPoint))
			{
				pCurentCur = m_ArrCurve[iIndex];
				break;
			}
		}

		// if parameter point is near one key point of a selected curve
		if (pCurentCur && iPoint >= 0 && pCurentCur->IsSelected())
		{
			// change cursor
			if (m_bEdit)
				SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
			
			// use tooltip to show the values of key point nearby
			CString		strTip;
			strTip.Format(_T("%s[%d]: %d,%.4f"), pCurentCur->GetCurveName(), iPoint, int(pCurentCur->m_fArrHoriValue[iPoint]), pCurentCur->m_fArrVertValue[iPoint]);
			
			if(m_Tooltip.m_hWnd)
			{
				m_Tooltip.Activate(TRUE);			
				m_Tooltip.UpdateTipText(strTip, this);

				MSG msg;
				msg.hwnd= m_hWnd;
				msg.message= WM_MOUSEMOVE;
				msg.wParam= nFlags;
				msg.lParam= MAKELPARAM(LOWORD(point.x), LOWORD(point.y));
				msg.time= 0;
				msg.pt.x= point.x;
				msg.pt.y= point.y;
				
				m_Tooltip.RelayEvent(&msg);
			}
		}
	}
	
	Invalidate();

	CWnd::OnMouseMove(nFlags, point);
}

// description : handle left mouse button up, notify owner if data changed
void CCurveCtrl::OnLButtonUp(UINT nFlags, CPoint point) 
{
	if (m_bEdit && m_pCurveEdit && m_iCurPoint >=0)
	{
		BOOL bKeepOld = SendMessageToParent(CVN_MVALUE_CHANG, 
											m_pCurveEdit, 
											m_iCurPoint, 
											m_pCurveEdit->m_fArrHoriValue[m_iCurPoint],
											m_pCurveEdit->m_fArrVertValue[m_iCurPoint]
											);

		if (bKeepOld) // owner does not permit to change data, restore previous values
		{
			m_pCurveEdit->m_fArrHoriValue[m_iCurPoint] = m_fOldHori;
			m_pCurveEdit->m_fArrVertValue[m_iCurPoint] = m_fOldVert;
		}
		else     
		{			
			CalculateVertRange(m_pCurveEdit->m_fArrVertValue[m_iCurPoint], TRUE);
			CalculateVertRange(m_pCurveEdit->m_fArrVertValue[m_iCurPoint], FALSE);
		}

		// cursor style
		SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));

		m_pCurveEdit = NULL;
		m_iCurPoint = -1;
		ReleaseCapture();
		Invalidate();
	}	

	//拖动鼠标移动图形:依据为鼠标按下的点与鼠标抬起的点的差,再换算成采集的点数;
	float	fHori, fVert,fHori1;
	if(CalculateValue(m_pPoint, fHori1, fVert))							//计算鼠标按下的点
	{
		if(CalculateValue(point, fHori, fVert))							//计算鼠标抬起的点
		{
			if(fHori1!=fHori)											//相同点?
			{
				int v_iNum=int(fHori1-fHori);							//差值
				m_fHoriBegin+=v_iNum;									//移动起点
				m_fHoriEnd+=v_iNum;										//移动终点
				Invalidate();											//绘图
			}
		}
	}

	CWnd::OnLButtonUp(nFlags, point);
}

// description : delete key point after right mouse button clicked when enable edit
void CCurveCtrl::OnRButtonDown(UINT nFlags, CPoint point) 
{
	if (m_bEdit)
	{
		// get the nearby curve
		int			iPt = -1;
		CCurve*		pCurentCur = NULL;
		for (int iIndex = 0; iIndex < m_ArrCurve.GetSize(); iIndex++)
		{
			if (m_ArrCurve[iIndex]->IsPointNearCurve(point, iPt))
			{
				pCurentCur = m_ArrCurve[iIndex];
				break;
			}
		}

		// if there is one  and be selected and near point
		if (pCurentCur && pCurentCur->IsSelected() && iPt >= 0)
		{
			int bKeep = SendMessageToParent(CVN_MVALUE_DELETE, 
											pCurentCur, 
											iPt, 
											pCurentCur->m_fArrHoriValue[iPt],
											pCurentCur->m_fArrVertValue[iPt]
											);
			// whether delete the point determined by message handle function
			if (!bKeep)
			{
				pCurentCur->m_ArrPoint.RemoveAt(iPt);
				pCurentCur->m_fArrHoriValue.RemoveAt(iPt);
				pCurentCur->m_fArrVertValue.RemoveAt(iPt);
				
				// remove the curve object if there is no point in it
				if (pCurentCur->m_fArrHoriValue.GetSize() == 0)
				{
					ASSERT(m_ArrCurve[iIndex] == pCurentCur);
					delete pCurentCur;
					m_ArrCurve.RemoveAt(iIndex);
				}
			}
			
			Invalidate();
		}
	}	
	
	CWnd::OnRButtonDown(nFlags, point);
}

// description : notify owner that curve mode or data changed
// in parameter: nMessage -- message id
//               pCurve   -- curve object
//               iIndex   -- index of curve or key point
//               fHori    -- horizontal value
//               fVert    -- vertical value
// return      :  0:permit to change;  else: do not change
LRESULT CCurveCtrl::SendMessageToParent(int nMessage, CCurve* pCurve, int iIndex, float fHori, float fVert) const
{
    if (!IsWindow(m_hWnd))
        return 0;

	// struct to save parameter
    NM_CURVECTRL nmcurve;

	nmcurve.pCurve		 = (void*)pCurve;
	nmcurve.iIndex		 = iIndex;
	nmcurve.fHori		 = fHori;
	nmcurve.fVert		 = fVert;	
    nmcurve.hdr.hwndFrom = m_hWnd;
    nmcurve.hdr.idFrom   = GetDlgCtrlID();
    nmcurve.hdr.code     = nMessage;

	// send message to owner, owner is parent or not
    CWnd *pOwner = GetOwner();
    if (pOwner && IsWindow(pOwner->m_hWnd))
        return pOwner->SendMessage(WM_NOTIFY, nmcurve.hdr.idFrom, (LPARAM)&nmcurve);
    else
        return 0;
}



//-------------------------------------------------------------------------------------------------
// 功能:鼠标滚轮消息响应
// 参数:zDelta=120向前(放大);zDelta=120向后(缩小);
//-------------------------------------------------------------------------------------------------
BOOL CCurveCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
{
	// TODO: Add your message handler code here and/or call default
	m_fHoriBegin+=10;
	return CWnd::OnMouseWheel(nFlags, zDelta, pt);
}

⌨️ 快捷键说明

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