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

📄 imageboardview.cpp

📁 <精通Visual C++图像处理编程>源码 对于图像处理很有帮助
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			(point.y < 0 || point.y > rcClient.bottom))
		{
			nScrollY += point.y;
			nScrollY = BOUND(nScrollY, nMinY, nMaxY);
			SetScrollPos(SB_VERT, nScrollY);
			bNeedRedraw = TRUE;
		}
		if (bNeedRedraw)
		{
			// redraw
			Invalidate(FALSE);
			UpdateWindow();
		}
		// normalize point coordinate
		if (AdjustPointinDib(point))
		{
			ClientToScreen(&point);
			SetCursorPos(point.x, point.y);
			ScreenToClient(&point);
		}
	}

	// use client coordinates
	CPoint ptStart(m_ptStart);
	DibToClient(ptStart);
	// set new rectangle
	if (point.x < ptStart.x)
	{
		m_rcRubber.left = point.x;
		m_rcRubber.right = ptStart.x;
	}	
	else
	{
		m_rcRubber.left = ptStart.x;
		m_rcRubber.right = point.x;
	}
	if (point.y < ptStart.y)
	{
		m_rcRubber.top = point.y;
		m_rcRubber.bottom = ptStart.y;
	}
	else
	{
		m_rcRubber.top = ptStart.y;
		m_rcRubber.bottom = point.y;
	}
	m_rcRubber.NormalizeRect();

	// draw new rectangle
	DoDrawRubber(&dc, m_rcRubber);

	// restore
	dc.SelectObject(pOldPen);
	dc.SetROP2(nOldRop);
}

void CImageBoardView::StopDrawRubber()
{
	if (m_nDrawType == DT_SELECT || m_nDrawType == DT_TEXT)
	{
		m_rcClip = m_rcRubber;

		// if there is rectangle drawn, clear it
		if (! m_rcClip.IsRectEmpty())
		{
			// get DC and set its ROP
			CClientDC dc(this);
			int OldRop = dc.SetROP2(R2_NOTXORPEN);
			// define used pen
			CPen pen(PS_DOT, 1, RGB(0,0,0));
			CPen* pOldPen = dc.SelectObject(&pen);
			
			// draw to clear
			DoDrawRubber(&dc, m_rcClip);
		
			// restore
			dc.SetROP2(OldRop);
			dc.SelectObject(pOldPen);
		}
		
		if (m_nDrawType == DT_TEXT)
		{
			// empty clip area 
			m_rcClip.SetRectEmpty();

			CRect rc = m_rcRubber;

			CClientDC dc(this);
			CFont *pOldFont = dc.SelectObject(m_pFont);
			CRect rcLetter(0,0,1,1);
			int nHeight = dc.DrawText(_T("中"),&rcLetter, DT_CALCRECT);
			int nWidth = 4*rcLetter.Width();
			dc.SelectObject(pOldFont);

			if (rc.Height() < nHeight)
				rc.bottom = rc.top + nHeight;
			if (rc.Width() < nWidth)
				rc.right = rc.left + nWidth;
			ClientToDib(rc);
			if (rc.bottom > m_pDib->GetHeight())
				rc.bottom = m_pDib->GetHeight();
			if (rc.right > m_pDib->GetWidth())
				rc.right = m_pDib->GetWidth();
			DibToClient(rc);

			DWORD style = ES_LEFT;
			if (m_nTextAlign == DT_LEFT)
				style = ES_LEFT;
			else if (m_nTextAlign == DT_CENTER)
				style = ES_CENTER;
			else if (m_nTextAlign == DT_RIGHT)
				style = ES_RIGHT;
			m_EditText.Create(style|WS_VISIBLE|WS_CHILD|ES_MULTILINE, 
						  rc, 
						  this, 
						  IDC_EDIT);
			rc.InflateRect(2,2);
			InvalidateRect(&rc);
			m_EditText.SetFont(m_pFont);
			m_EditText.SetFocus();
		}
	}
	else
	{
		// if there is rectangle drawn, clear it
		CClientDC dc(this);
		CPen pen(m_nPenStyle, m_nPenWidth, m_crPenColor);
		int nOldRop = dc.SetROP2(R2_NOTXORPEN);
		CPen* pOldPen = dc.SelectObject(&pen);
		DoDrawRubber(&dc, m_rcRubber);
		dc.SetROP2(nOldRop);
		dc.SelectObject(pOldPen);
		
		// draw on dib		
		CRect rc = m_rcRubber;
		ClientToDib(rc);
		CBrush brush(m_crFillColor);
		CBrush* pOldBrush;
		CDC * pDibDC = m_pDib->BeginPaint(&dc);
		pOldPen = pDibDC->SelectObject(&pen);
		if (m_nDrawType == DT_RECT_F || 
			m_nDrawType == DT_ROUNDRECT_F || 
			m_nDrawType == DT_ELLIP_F)
		{
			pOldBrush = pDibDC->SelectObject(&brush);
		}
		else
			pOldBrush = dc.SelectObject(CBrush::FromHandle((HBRUSH)GetStockObject(HOLLOW_BRUSH)));

		switch(m_nDrawType)
		{
		case DT_LINE:
			{
				if (m_ptStart == rc.TopLeft() || 
					m_ptStart == rc.BottomRight())
				{
					pDibDC->MoveTo(rc.TopLeft());
					pDibDC->LineTo(rc.BottomRight());
				}
				else
				{
					pDibDC->MoveTo(rc.right, rc.top);
					pDibDC->LineTo(rc.left, rc.bottom);
				}
			}
			break;
		case DT_RECT_H:
		case DT_RECT_F:
			pDibDC->Rectangle(&rc);
			break;
		case DT_ROUNDRECT_H:
		case DT_ROUNDRECT_F:
			pDibDC->RoundRect(&rc, CPoint((int)(rc.Width()/3), (int)(rc.Height()/3)));
			break;
		case DT_ELLIP_H:
		case DT_ELLIP_F:
			pDibDC->Ellipse(&rc);
			break;
		}

		pDibDC->SelectObject(pOldPen);
		pDibDC->SelectObject(pOldBrush);

		m_pDib->EndPaint();

		Invalidate(FALSE);
	}

	// release capture mouse
	ReleaseCapture();
}

BOOL CImageBoardView::PointInDib(CPoint point)
{
	if (m_pDib->IsEmpty())
		return FALSE;

	ClientToDib(point);
	CRect rcDib(0, 0, m_pDib->GetWidth(), m_pDib->GetWidth());
	return rcDib.PtInRect(point);
}

BOOL CImageBoardView::MergeText()
{
	if (! ::IsWindow(m_EditText.m_hWnd))
		return FALSE;

	CString s;
	m_EditText.GetWindowText(s);

	CRect rc;
	m_EditText.GetWindowRect(&rc);
	ScreenToClient(&rc);
	CRect rcClear = rc;
	rcClear.InflateRect(3,3);
	m_EditText.DestroyWindow();
	InvalidateRect(&rcClear);

	// Merge Text into DIB
	if (! s.IsEmpty())
	{
		CClientDC dc(this);

		CDC * pDibDC = m_pDib->BeginPaint(&dc);
		int nOldBkMode = pDibDC->SetBkMode(TRANSPARENT);
		COLORREF crOldTextColor = pDibDC->SetTextColor(m_crPenColor);
		CFont *pOldFont = pDibDC->SelectObject(m_pFont);

		// needed rectangle
		ClientToDib(rc);
		if (rc.bottom > m_pDib->GetHeight())
			rc.bottom = m_pDib->GetHeight();
		if (rc.right > m_pDib->GetWidth())
			rc.right = m_pDib->GetWidth();

		pDibDC->DrawText(s, &rc, m_nTextAlign);
		pDibDC->SetBkMode(nOldBkMode);
		pDibDC->SetTextColor(crOldTextColor);
		pDibDC->SelectObject(pOldFont);
		m_pDib->EndPaint();
	}

	return TRUE;
}

void CImageBoardView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	if (PointInDib(point))
	{
		// Merge and delete old float DIB (if exist)
		MergeFloatDib();

		// if ther is text, just merge it into DIB
		if (! MergeText())	// else, do paint
		{
			if (m_nDrawType == DT_FREELINE)
			{
				m_bDrawFreeline = TRUE;
				m_ptFreelineStart = point;
				SetCapture();

				// set a pixel anyway
				CClientDC dc(this);
				ClientToDib(point);
				CDC * pDibDC = m_pDib->BeginPaint(&dc);
				pDibDC->SetPixel(point, m_crPenColor);
				m_pDib->EndPaint();
				Invalidate(FALSE);
			}
			else if (m_nDrawType == DT_ERASER)
			{
				m_bErasing = TRUE;
				SetCapture();

				// set a pixel anyway
				CClientDC dc(this);
				ClientToDib(point);
				CRect rc(point.x-4, point.y-4, point.x+4, point.y+4);
				CDC * pDibDC = m_pDib->BeginPaint(&dc);
				CBrush brush(m_crFillColor);
				CBrush *pOldBrush = pDibDC->SelectObject(&brush);
				CPen Pen(PS_SOLID, 1, m_crFillColor);
				CPen *pOldPen = pDibDC->SelectObject(&Pen);
				pDibDC->Ellipse(&rc);
				pDibDC->SelectObject(pOldPen);
				pDibDC->SelectObject(pOldBrush);
				m_pDib->EndPaint();
				Invalidate(FALSE);
			}
			else if (m_nDrawType == DT_PICKER)
			{
				CClientDC dc(this);
				COLORREF crColor = dc.GetPixel(point);
				CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd;
				ASSERT_KINDOF(CMainFrame, pAppFrame);
				if (pAppFrame->m_wndPaintParamBar.m_nSelectColorMode == PP_FILL_COLOR)
				{
					m_crFillColor = crColor;
					ShowFillColor();
				}
				else if (pAppFrame->m_wndPaintParamBar.m_nSelectColorMode == PP_PEN_COLOR)
				{
					m_crPenColor = crColor;
					ShowPenColor();
				}
			}
			else if (m_nDrawType == DT_FILL)
			{
				CBrush brush(m_crFillColor);

				CClientDC dc(this);
				COLORREF crColor = dc.GetPixel(point);

				CBrush* pOldBrush = dc.SelectObject(&brush);
				dc.ExtFloodFill(point.x,			// x-coordinate where filling begins
								point.y,			// y-coordinate where filling begins
								crColor,			// fill color  
								FLOODFILLSURFACE);	// fill type
				dc.SelectObject(pOldBrush);

				ClientToDib(point);
				CDC * pDibDC = m_pDib->BeginPaint(&dc);
				pOldBrush = pDibDC->SelectObject(&brush);
				pDibDC->ExtFloodFill(point.x,				// x-coordinate where filling begins
									 point.y,				// y-coordinate where filling begins
									 crColor,				// fill color  
									 FLOODFILLSURFACE);		// fill type
				pDibDC->SelectObject(pOldBrush);
				m_pDib->EndPaint();
			}
			else if (m_nDrawType == DT_CURVE)
			{
				if (! m_bDrawCurve)
				{
					m_bDrawCurve = TRUE;
					m_nDrawCurveStep = 1;
					m_ptCurve[0] = point;
					m_ptCurve[1] = point;
					m_ptCurve[2] = point;
					m_ptCurve[3] = point;
					// capture mouse
					::SetCursor(m_hCursorCurve);
					SetCapture();
				}
				else
				{
					CRect rc;
					GetClientRect(&rc);
					if (! rc.PtInRect(point))
					{
						DrawTmpCurve();
						m_bDrawCurve = FALSE;
						ReleaseCapture();
						::SetCursor(m_hCursorGeneralDraw);
					}
					else
					{
						DrawTmpCurve();
						if (m_nDrawCurveStep == 2)
							m_ptCurve[2] = point;
						else if (m_nDrawCurveStep == 3)
							m_ptCurve[1] = point;
						DrawTmpCurve();
					}
				}
			}
			else
			{
				if (m_nDrawType == DT_LINE)
				{
					// set a pixel anyway
					CClientDC dc(this);
					dc.SetPixel(point, m_crPenColor);

					ClientToDib(point);
					CDC * pDibDC = m_pDib->BeginPaint(&dc);
					pDibDC->SetPixel(point, m_crPenColor);
					m_pDib->EndPaint();
				}
				// start draw rectangle
				StartDrawRubber(point);
				m_bDrawingRubber = TRUE;
			}
		}
	}

	CScrollView::OnLButtonDown(nFlags, point);
}

void CImageBoardView::OnMouseMove(UINT nFlags, CPoint point) 
{
	SetStatusBarCursorPosition(point);	

	// change rectangle
	if (m_bDrawingRubber)
		DrawRubber(point);

	if (m_bDrawCurve && nFlags == MK_LBUTTON)
	{
		DrawTmpCurve();
		if (m_nDrawCurveStep == 1)
			m_ptCurve[3] = point;
		else if (m_nDrawCurveStep == 2)
			m_ptCurve[2] = point;
		else if (m_nDrawCurveStep == 3)
			m_ptCurve[1] = point;
		DrawTmpCurve();
	}

	// draw FREELINE
	if (m_bDrawFreeline)
	{
		CPen pen(m_nPenStyle, m_nPenWidth, m_crPenColor);

		CClientDC dc(this);

		CPoint pt = point;
		ClientToDib(m_ptFreelineStart);
		ClientToDib(pt);
		CDC * pDibDC = m_pDib->BeginPaint(&dc);
		CPen* pOldPen = pDibDC->SelectObject(&pen);
		pDibDC->MoveTo(m_ptFreelineStart);
		pDibDC->LineTo(pt);
		pDibDC->SelectObject(pOldPen);
		m_pDib->EndPaint();
		Invalidate(FALSE);

		// new start point
		m_ptFreelineStart = point;
	}
	else if (m_bErasing)
	{
		// set a pixel anyway
		CClientDC dc(this);
		ClientToDib(point);
		CRect rc(point.x-4, point.y-4, point.x+4, point.y+4);
		CDC * pDibDC = m_pDib->BeginPaint(&dc);
		CBrush brush(m_crFillColor);
		CBrush *pOldBrush = pDibDC->SelectObject(&brush);
		CPen Pen(PS_SOLID, 1, m_crFillColor);
		CPen *pOldPen = pDibDC->SelectObject(&Pen);
		pDibDC->Ellipse(&rc);
		pDibDC->SelectObject(pOldPen);
		pDibDC->SelectObject(pOldBrush);
		m_pDib->EndPaint();
		Invalidate(FALSE);
	}

	CScrollView::OnMouseMove(nFlags, point);
}

void CImageBoardView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	if (m_bDrawFreeline)
	{
		m_bDrawFreeline = FALSE;
		ReleaseCapture();
	}
	else if (m_bErasing)
	{
		m_bErasing = FALSE;
		ReleaseCapture();
	}
	else if (m_bDrawCurve)
	{
		m_nDrawCurveStep++;
		// finish draw curve
		if (m_nDrawCurveStep > 3)
		{
			ReleaseCapture();
			::SetCursor(m_hCursorGeneralDraw);
			m_bDrawCurve = FALSE;
			DrawCurve();
		}
	}
	else if (m_bDrawingRubber)
	{
		StopDrawRubber();
		m_bDrawingRubber = FALSE;

		if (! m_rcClip.IsRectEmpty())
		{
			// adjust position with scroll position
			CRect rcInDib(m_rcClip);
			ClientToDib(rcInDib);

			// create float DIB
			HDIB hDib = m_pDib->CopyRect(rcInDib);

			// create new float DIB window
			CreateFloatWnd(hDib, m_rcClip.TopLeft());
		}
	}

	CScrollView::OnLButtonUp(nFlags, point);
}

void CImageBoardView::DrawTmpCurve()
{
	CPen penCurve(PS_SOLID, m_nPenWidth, m_crPenColor);

	CClientDC dc(this);
	CPen* pOldPen = dc.SelectObject(&penCurve);
	int nOldRop = dc.SetROP2(R2_NOTXORPEN);
	dc.PolyBezier(m_ptCurve, 4);
	dc.SelectObject(pOldPen);
	dc.SetROP2(nOldRop);
}

void CImageBoardView::DrawCurve()
{
	DrawTmpCurve();

	CPen penCurve(PS_SOLID, m_nPenWidth, m_crPenColor);

	CClientDC dc(this);
	CDC * pDibDC = m_pDib->BeginPaint(&dc);

	CPen* pOldPen = pDibDC->SelectObject(&penCurve);
	pDibDC->PolyBezier(m_ptCurve, 4);
	pDibDC->SelectObject(pOldPen);
	m_pDib->EndPaint();

	Invalidate(FALSE);
}

void CImageBoardView::CutSelectedRect()
{
	if (! m_rcClip.IsRectEmpty())
	{
		// adjust position with scroll position

⌨️ 快捷键说明

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