gdiview.cpp

来自「MFC编程实例」· C++ 代码 · 共 798 行 · 第 1/2 页

CPP
798
字号
void CGDIView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	int nCurrentTool;
	CGDIDoc *pDoc;
	CPoint pt;

	if(m_bmpDraw.GetSafeHandle() != NULL)
	{
		pDoc=(CGDIDoc *)GetDocument();
		nCurrentTool=pDoc->GetCurrentTool();
		::ReleaseCapture();
		pt=NormalizePtPosition(point);
		switch(nCurrentTool)
		{
			case TOOL_FREESEL:
			{
				CClientDC dc(this);
				CPen *pPenOld;
				CRect rect;

				pPenOld=dc.SelectObject(&m_penDot);
				dc.MoveTo(m_ptPrevious);
				dc.LineTo(point);
				dc.SelectObject(pPenOld);
				m_dcMem.LineTo(pt);
				m_dcMem.CloseFigure();
				m_dcMem.EndPath();
				m_rgnFreeSel.CreateFromPath(&m_dcMem);
				m_rgnFreeSel.GetRgnBox(rect);
				m_trackerSel.m_rect=UnnormalizeTrackerRect(rect);
				BackupCurrentBmp();
				BackupSelection();
				Invalidate(FALSE);
				break;
			}
			case TOOL_RECTSEL:
			{
				CClientDC dc(this);

				if(!m_trackerSel.m_rect.IsRectEmpty())
				{
					dc.DrawFocusRect(m_trackerSel.m_rect);
				}
				m_trackerSel.m_rect.right=point.x+GetScrollPosition().x;
				m_trackerSel.m_rect.bottom=point.y+GetScrollPosition().y;
				BackupCurrentBmp();
				BackupSelection();
				Invalidate(FALSE);
				break;
			}
			case TOOL_PEN:
			{
				if(pt != m_ptMouseDown)
				{
					DrawPoint(point);
					pDoc->SetModifiedFlag(TRUE);
				}
				break;
			}
			case TOOL_LINE:
			{
				ResumeBackupBmp();
				DrawLine(m_ptMouseDown, pt);
				break;
			}
		}
	}
	CScrollView::OnLButtonUp(nFlags, point);
}

void CGDIView::OnMouseMove(UINT nFlags, CPoint point) 
{
	int nCurrentTool;
	CGDIDoc *pDoc;
	CPoint pt;

	if(m_bmpDraw.GetSafeHandle() != NULL)
	{
		pDoc=(CGDIDoc *)GetDocument();
		nCurrentTool=pDoc->GetCurrentTool();
		pt=NormalizePtPosition(point);
		switch(nCurrentTool)
		{
			case TOOL_FREESEL:
			{
				if(nFlags & MK_LBUTTON)
				{
					CClientDC dc(this);
					CPen *pPenOld;

					pPenOld=dc.SelectObject(&m_penDot);
					dc.MoveTo(m_ptPrevious);
					dc.LineTo(point);
					m_ptPrevious=point;
					dc.SelectObject(pPenOld);
					m_dcMem.LineTo(pt);
				}
				break;
			}
			case TOOL_RECTSEL:
			{
				if(nFlags & MK_LBUTTON)
				{
					CClientDC dc(this);

					if(!m_trackerSel.m_rect.IsRectEmpty())
					{
						dc.DrawFocusRect(m_trackerSel.m_rect);
					}
					m_trackerSel.m_rect.right=point.x;
					m_trackerSel.m_rect.bottom=point.y;
					if(!m_trackerSel.m_rect.IsRectEmpty())
					{
						dc.DrawFocusRect(m_trackerSel.m_rect);
					}
				}
				break;
			}
			case TOOL_PEN:
			{
				if(nFlags & MK_LBUTTON)
				{
					if(pt != m_ptMouseDown)
					{
						DrawPoint(point);
						pDoc->SetModifiedFlag(TRUE);
					}
				}
				break;
			}
			case TOOL_LINE:
			{
				if(nFlags & MK_LBUTTON)
				{
					ResumeBackupBmp();
					DrawLine(m_ptMouseDown, pt);
				}
				break;
			}
		}
	}
	CScrollView::OnMouseMove(nFlags, point);
}

CPoint CGDIView::NormalizePtPosition(CPoint pt)
{
	int nRatio;
	CGDIDoc *pDoc;

	pDoc=(CGDIDoc *)GetDocument();
	nRatio=pDoc->GetRatio();
	pt.Offset(GetScrollPosition());

	return CPoint(pt.x/nRatio, pt.y/nRatio);
}

void CGDIView::DrawPoint(CPoint pt)
{
	int nPalIndex;
	CGDIDoc *pDoc;

	pDoc=(CGDIDoc *)GetDocument();
	nPalIndex=pDoc->GetFgdIndex();
	m_dcMem.SetPixel(pt, PALETTEINDEX(nPalIndex));
	Invalidate(FALSE);
}

void CGDIView::DrawLine(CPoint ptStart, CPoint ptEnd)
{
	int nPalIndex;
	CGDIDoc *pDoc;
	CPen pen;
	CPen *pPenOld;

	pDoc=(CGDIDoc *)GetDocument();
	nPalIndex=pDoc->GetFgdIndex();
	pen.CreatePen(PS_SOLID, 1, PALETTEINDEX(nPalIndex));
	pPenOld=m_dcMem.SelectObject(&pen);
	m_dcMem.MoveTo(ptStart);
	m_dcMem.LineTo(ptEnd);
	m_dcMem.SelectObject(pPenOld);
	Invalidate(FALSE);
}

void CGDIView::BackupSelection()
{
	CDC dcMem;
	CPalette *pPalOld;
	CPalette *pPal;
	CGDIDoc *pDoc;
	BITMAP bm;
	CBitmap *pBmpOld;
	CRect rect;
	int nBgdIndex;

	if(m_bmpSelBackup.GetSafeHandle() != NULL)m_bmpSelBackup.DeleteObject();
	pDoc=(CGDIDoc *)GetDocument();
	pPal=pDoc->GetPalette();
	ASSERT(pPal->GetSafeHandle());
	nBgdIndex=pDoc->GetBgdIndex();
	dcMem.CreateCompatibleDC(&m_dcMem);
	pPalOld=dcMem.SelectPalette(pPal, FALSE);

	rect=NormalizeTrackerRect(m_trackerSel.m_rect);
	m_bmpDraw.GetBitmap(&bm);
	m_bmpSelBackup.CreateCompatibleBitmap(&m_dcMem, rect.Width(), rect.Height());
	pBmpOld=dcMem.SelectObject(&m_bmpSelBackup);
	dcMem.FillSolidRect(0, 0, rect.Width(), rect.Height(), PALETTEINDEX(nBgdIndex));
	if(rect.left < 0)rect.left=0;
	if(rect.top < 0)rect.top=0;
	if(rect.right >= bm.bmWidth)rect.right=bm.bmWidth-1;
	if(rect.bottom >= bm.bmHeight)rect.bottom=bm.bmHeight-1;
	dcMem.BitBlt
	(
		0, 0,
		rect.Width(), rect.Height(),
		&m_dcMem,
		rect.left, rect.top,
		SRCCOPY
	);

	dcMem.SelectObject(pBmpOld);
	dcMem.SelectPalette(pPal, FALSE);
}

void CGDIView::StretchCopySelection()
{
	CDC dcMem;
	CPalette *pPalOld;
	CPalette *pPal;
	CGDIDoc *pDoc;
	BITMAP bm;
	CBitmap *pBmpOld;
	CRect rect;

	if(m_bmpSelBackup.GetSafeHandle() == NULL)return;

	pDoc=(CGDIDoc *)GetDocument();
	pPal=pDoc->GetPalette();
	ASSERT(pPal->GetSafeHandle());
	dcMem.CreateCompatibleDC(&m_dcMem);
	pPalOld=dcMem.SelectPalette(pPal, FALSE);

	rect=NormalizeTrackerRect(m_trackerSel.m_rect);
	m_bmpSelBackup.GetBitmap(&bm);
	pBmpOld=dcMem.SelectObject(&m_bmpSelBackup);
	m_dcMem.StretchBlt
	(
		rect.left, rect.top,
		rect.Width(), rect.Height(),
		&dcMem,
		0, 0,
		bm.bmWidth, bm.bmHeight,
		SRCCOPY
	);
	dcMem.SelectObject(pBmpOld);
	dcMem.SelectPalette(pPal, FALSE);
}

void CGDIView::BackupCurrentBmp()
{
	CDC dcMem;
	CPalette *pPalOld;
	CPalette *pPal;
	CGDIDoc *pDoc;
	BITMAP bm;
	CBitmap *pBmpOld;

	if(m_bmpBackup.GetSafeHandle() != NULL)m_bmpBackup.DeleteObject();
	pDoc=(CGDIDoc *)GetDocument();
	pPal=pDoc->GetPalette();
	ASSERT(pPal->GetSafeHandle());
	dcMem.CreateCompatibleDC(&m_dcMem);
	pPalOld=dcMem.SelectPalette(pPal, FALSE);

	m_bmpDraw.GetBitmap(&bm);
	m_bmpBackup.CreateCompatibleBitmap(&m_dcMem, bm.bmWidth, bm.bmHeight);
	pBmpOld=dcMem.SelectObject(&m_bmpBackup);
	dcMem.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &m_dcMem, 0, 0, SRCCOPY);

	dcMem.SelectObject(pBmpOld);
	dcMem.SelectPalette(pPal, FALSE);
}

void CGDIView::ResumeBackupBmp()
{
	CDC dcMem;
	CPalette *pPalOld;
	CPalette *pPal;
	CGDIDoc *pDoc;
	BITMAP bm;
	CBitmap *pBmpOld;

	ASSERT(m_bmpBackup.GetSafeHandle() != NULL);
	pDoc=(CGDIDoc *)GetDocument();
	pPal=pDoc->GetPalette();
	ASSERT(pPal->GetSafeHandle());
	dcMem.CreateCompatibleDC(&m_dcMem);
	pPalOld=dcMem.SelectPalette(pPal, FALSE);

	m_bmpDraw.GetBitmap(&bm);
	pBmpOld=dcMem.SelectObject(&m_bmpBackup);
	m_dcMem.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcMem, 0, 0, SRCCOPY);

	dcMem.SelectObject(pBmpOld);
	dcMem.SelectPalette(pPal, FALSE);
}

BOOL CGDIView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	if(m_bmpDraw.GetSafeHandle() != NULL)
	{
		if
		(
			!(
				m_trackerSel.m_rect.IsRectEmpty() != TRUE && 
				m_trackerSel.SetCursor(this, nHitTest) == TRUE
			)
		)
		{
			if
			(
				MouseWithinBitmap() == TRUE && 
				HTVSCROLL != nHitTest && HTHSCROLL != nHitTest
			)
			{
				
				::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));
				return TRUE;
			}
		}
		else return TRUE;
	}
	return CScrollView::OnSetCursor(pWnd, nHitTest, message);
}

BOOL CGDIView::MouseWithinBitmap()
{
	CPoint point;
	CPoint ptScroll;
	CRect rect;
	CRect rectBmp;
	BITMAP bm;
	int nRatio;
	CGDIDoc *pDoc;

	pDoc=(CGDIDoc *)GetDocument();
	nRatio=pDoc->GetRatio();
	ptScroll=GetScrollPosition();
	::GetCursorPos(&point);
	GetWindowRect(rect);
	point.Offset(-rect.left, -rect.top);
	point.Offset(ptScroll);

	ASSERT(m_bmpDraw.GetSafeHandle());
	m_bmpDraw.GetBitmap(&bm);
	rectBmp=CRect(0, 0, bm.bmWidth*nRatio, bm.bmHeight*nRatio);

	return rectBmp.PtInRect(point);
}

void CGDIView::ResetTracker()
{
	m_trackerSel.m_rect=CRect(0, 0, 0, 0);
}

CRect CGDIView::NormalizeTrackerRect(CRect rect)
{
	int nRatio;
	CGDIDoc *pDoc;

	pDoc=(CGDIDoc *)GetDocument();
	nRatio=pDoc->GetRatio();

	rect.NormalizeRect();
	rect.left/=nRatio;
	rect.top/=nRatio;
	rect.right/=nRatio;
	rect.bottom/=nRatio;
	return rect;
}

CRect CGDIView::UnnormalizeTrackerRect(CRect rect)
{
	CPoint pt;
	int nRatio;
	CGDIDoc *pDoc;

	pDoc=(CGDIDoc *)GetDocument();
	nRatio=pDoc->GetRatio();

	pt=GetScrollPosition();
	rect.left*=nRatio;
	rect.top*=nRatio;
	rect.right*=nRatio;
	rect.bottom*=nRatio;
	rect.OffsetRect(pt);
	return rect;
}

⌨️ 快捷键说明

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