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

📄 bitmapwnd.cpp

📁 Bug管理系统
💻 CPP
字号:
// BitmapWnd.cpp : implementation file
//

#include "stdafx.h"
#include "btnetsc.h"
#include "BitMapWnd.h"
#include <atlimage.h>
#include "stroke.h"

// CBitmapWnd

CBitmapWnd::CBitmapWnd()
{
	m_hBitmap = 0;
	m_pImg = NULL;
	m_Pen.CreatePen(PS_SOLID, 3, RGB(255,0,0));
}
CBitmapWnd::~CBitmapWnd()
{
	DeleteStrokes();
	if (m_pImg)
	{
		m_pImg->Detach();
		delete m_pImg;
	}	
}
void CBitmapWnd::DeleteStrokes()
{
	while (!m_strokeList.IsEmpty())
		{
			delete m_strokeList.RemoveHead();
		}
}


BEGIN_MESSAGE_MAP(CBitmapWnd, CStatic)
	//{{AFX_MSG_MAP(CBitmapWnd)
	ON_WM_PAINT()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN() 
	ON_WM_LBUTTONUP() 
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CBitmapWnd::SetBitmap(HBITMAP hbitmap)
{
	m_hBitmap = hbitmap;
	if (m_pImg)
	{
		m_pImg->Detach();
		delete m_pImg;
	}
	m_pImg = new CImage();
	m_pImg->Attach(hbitmap);

	// get source bitmap dimensions
	int nWidthSource = m_pImg->GetWidth();
	int nHeightSource = m_pImg->GetHeight();

	// get target window dimensions
	RECT rect;
	::GetClientRect(this->m_hWnd,&rect);
	int nWidthTarget = rect.right-rect.left;
	int nHeightTarget = rect.bottom-rect.top;

	// Don't stretch the bitmap.   If it is smaller than
	// the window, use make the target area the same
	// size as the bitmap.
	if (nWidthTarget > nWidthSource
	&& nHeightTarget > nHeightSource)
	{
		m_nX = nWidthSource;
		m_nY = nHeightSource;
	}
	else {

		// We are going to shrink the bitmap, but
		// we want to preserve the aspect ratio.
		float nWidthRatio 
			= (float)nWidthSource/(float)nWidthTarget;
		float nHeightRatio 
			= (float)nHeightSource/(float)nHeightTarget;

		if (nHeightRatio > nWidthRatio)
		{
			// Shrink the height to fit window.
			// Shrink the width to preserve aspect ratio.
			m_nX = (int)(((float)nHeightTarget*(float)nWidthSource)
				/(float)nHeightSource);
			m_nY = nHeightTarget;
		}
		else if (nWidthRatio > nHeightRatio)
		{
			// Shrink the width to fit window.
			// Shrink the height to preserve aspect ratio.
			m_nX = nWidthTarget;
			m_nY = (int)(((float)nWidthTarget*(float)nHeightSource)
				/(float)nWidthSource);
		}
	}

	DeleteStrokes();
}




void CBitmapWnd::OnPaint()
{
	if (m_hBitmap)	
	{
		CPaintDC dc(this);
		m_pImg->StretchBlt(dc.m_hDC,
			0,0,
			m_nX, m_nY,
			0,0, m_pImg->GetWidth(),m_pImg->GetHeight(),
			SRCCOPY);

		POSITION pos = m_strokeList.GetHeadPosition();
		CPen* pOldPen = dc.SelectObject(&m_Pen);
		while (pos != NULL)
		{
			CStroke* pStroke = m_strokeList.GetNext(pos);
			pStroke->DrawStroke(&dc);
		}
		dc.SelectObject(pOldPen);

	}
	else
	{
		CStatic::OnPaint();
	}

}

HBITMAP CBitmapWnd::GetBitmap()
{
	CClientDC dc(this);
	CDC MemDC; 
	MemDC.CreateCompatibleDC(&dc);
	HBITMAP hBitmap = ::CreateCompatibleBitmap(dc.m_hDC, 
		m_pImg->GetWidth(),m_pImg->GetHeight());
	MemDC.SelectObject(hBitmap);
	
	m_pImg->BitBlt(MemDC,
		0,0,
		m_pImg->GetWidth(),m_pImg->GetHeight(),
		0,0, 
		SRCCOPY);

	RECT rect;
	::GetClientRect(this->m_hWnd,&rect);
	float nClientWidth = (float) m_nX;// rect.right-rect.left;
	float nClientHeight = (float) m_nY; // rect.bottom-rect.top;
	

	float fXFactor = ((float) m_pImg->GetWidth())/nClientWidth;
	float fYFactor = ((float) m_pImg->GetHeight())/nClientHeight;

	POSITION pos = m_strokeList.GetHeadPosition();
	CPen* pOldPen = MemDC.SelectObject(&m_Pen);
	while (pos != NULL)
	{
		CStroke* pStroke = m_strokeList.GetNext(pos);
		pStroke->DrawStroke(&MemDC, fXFactor, fYFactor);
	}
	MemDC.SelectObject(pOldPen);
/*
	// Save as a JPEG
	ATL::CImage img;
	img.Attach(hBitmap);
	img.Save("c:\\temp\\a.jpeg", Gdiplus::ImageFormatJPEG);
	img.Detach();
*/
	return hBitmap;
}


// CBitmapWnd message handlers
void CBitmapWnd::OnMouseMove(UINT nFlags, CPoint point)
{ 
	if (!m_hBitmap) return;


	// Mouse movement is interesting in the Scribble application
	// only if the user is currently drawing a new stroke by dragging
	// the captured mouse.

	if (GetCapture() != this)
		return; // If this window (view) didn't capture the mouse,
				// then the user isn't drawing in this window.

	CClientDC dc(this);

	m_pStrokeCur->m_pointArray.Add(point);

	// Draw a line from the previous detected point in the mouse
	// drag to the current point.
	CPen* pOldPen = dc.SelectObject(&m_Pen);
	dc.MoveTo(m_ptPrev);
	dc.LineTo(point);
	dc.SelectObject(pOldPen);
	m_ptPrev = point;
	return;
}
void CBitmapWnd::OnLButtonDown(UINT nFlags, CPoint point)
{ 
	if (!m_hBitmap) return;

	m_pStrokeCur = NewStroke();
	// Add first point to the new stroke
	m_pStrokeCur->m_pointArray.Add(point);

	SetCapture();       // Capture the mouse until button up.
	m_ptPrev = point;   // Serves as the MoveTo() anchor point for the
						// LineTo() the next point, as the user drags the
						// mouse.

	return;
}



void CBitmapWnd::OnLButtonUp(UINT nFlags, CPoint point)
{ 
	if (!m_hBitmap) return;

	// Mouse button up is interesting in the Scribble application
	// only if the user is currently drawing a new stroke by dragging
	// the captured mouse.

	if (GetCapture() != this)
		return; // If this window (view) didn't capture the mouse,
				// then the user isn't drawing in this window.

	CClientDC dc(this);

	CPen* pOldPen = dc.SelectObject(&m_Pen);
	dc.MoveTo(m_ptPrev);
	dc.LineTo(point);
	dc.SelectObject(pOldPen);
	m_pStrokeCur->m_pointArray.Add(point);

	// Tell the stroke item that we're done adding points to it.
	// This is so it can finish computing its bounding rectangle.
	m_pStrokeCur->FinishStroke();

	ReleaseCapture();   // Release the mouse capture established at
						// the beginning of the mouse drag.
	
	return;

}

CStroke* CBitmapWnd::NewStroke()
{
	// I'm ignoring the pen width here
	CStroke* pStrokeItem = new CStroke(1);
	m_strokeList.AddTail(pStrokeItem);
	return pStrokeItem;
}

⌨️ 快捷键说明

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