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

📄 bmpshow.cpp

📁 thinking in java 3rd 英文版的
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// BmpShow.cpp : implementation file
//

#include "stdafx.h"
#include "BmpShow.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CBmpShow

CBmpShow::CBmpShow()
{
	m_lpDIBits = NULL;
	m_pMemBmp = NULL;
	m_pOldBmp = NULL;
	m_lpBMPHdr = NULL;
	m_pMemDC = NULL;
	m_dwImageSize = 0;
	m_strBmpText = "";
	m_rcDraw.SetRect(0, 0, 0, 0);

	m_textTracker.m_rect.SetRect(0, 0, 0, 0);
	m_textTracker.m_nStyle = CRectTracker::resizeInside | CRectTracker::dottedLine;

//	m_nSBarWid = 0;
//	m_nSBarHei = 0;

}

CBmpShow::~CBmpShow()
{
	if (m_lpDIBits != NULL)
	{
		delete[] m_lpDIBits;
		m_lpDIBits = NULL;		
	}
	
	if (m_pMemBmp != NULL)
	{
		m_pMemDC->SelectObject(m_pOldBmp);		
		delete m_pMemBmp;
		m_pMemBmp = NULL;
	}
	if (m_pMemDC != NULL)
	{
		m_pMemDC->DeleteDC();
		delete m_pMemDC;
		m_pMemDC = NULL;
	}
	if (m_lpBMPHdr != NULL)
	{
		delete[] m_lpBMPHdr;
		m_lpBMPHdr = NULL;
	}
	m_pOldBmp = NULL;
}


BEGIN_MESSAGE_MAP(CBmpShow, CStatic)
	//{{AFX_MSG_MAP(CBmpShow)
	ON_WM_PAINT()
	ON_WM_ERASEBKGND()
	ON_WM_SETCURSOR()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_CREATE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBmpShow message handlers

BOOL CBmpShow::SetReadBmpPath(LPCTSTR pszPath, int* pnCharLimit)
{
	BOOL bSuccess = FALSE;
	CFile file;
	CDC* pDC = NULL;
	int size = 0;
	UINT uCounts = 0;
	BOOL bOpen = file.Open(pszPath, CFile::modeRead);
	if (!bOpen)
	{
		AfxMessageBox("读取位图文件出错");
		goto end;
	}

	BITMAPFILEHEADER bmfh;
	ZeroMemory(&bmfh, sizeof(BITMAPFILEHEADER));
	uCounts = file.Read((LPVOID) &bmfh, 
		sizeof(BITMAPFILEHEADER));
	if(uCounts != sizeof(BITMAPFILEHEADER)) 
	{
		AfxMessageBox("读取位图文件出错");
		goto end;
	}
	if(bmfh.bfType != 0x4d42) 
	{
		AfxMessageBox("本文件不是位图图片");
		goto end;
	}
	size = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
	if (m_lpBMPHdr != NULL)
	{
		delete[] m_lpBMPHdr;
		m_lpBMPHdr = NULL;
	}
	m_lpBMPHdr = (LPBITMAPINFOHEADER) new char[size];
	// BITMAPINFOHEADER和颜色表
	uCounts = file.Read(m_lpBMPHdr, size); 
	ComputePaletteSize(m_lpBMPHdr->biBitCount);
	
	if (m_nColorEntries != 0)
	{
		AfxMessageBox("本图片不是一个真彩色位图");
		goto end;
	}
	ComputeImageSize(m_lpBMPHdr, &m_dwImageSize);	
/*	if (m_dwImageSize != m_lpBMPHdr->biSizeImage)
	{
		AfxMessageBox("位图数据不正常, biSizeImage 不等于 (biWidth * biHeight * biBitCount / 8)");
		goto end;
	}*/
	if (m_lpDIBits != NULL)
	{
		delete[] m_lpDIBits;
		m_lpDIBits = NULL;
	}
	m_lpDIBits = (LPBYTE) new char[m_dwImageSize];

	uCounts = file.Read(m_lpDIBits, m_dwImageSize); 
	
	pDC = GetDC();
	CreateMemObject(pDC, (LPBITMAPINFO)m_lpBMPHdr, pnCharLimit);
	ComputeDrawRect();
	CreateScrollBar();
	ReleaseDC(pDC);

	//MAKEINTRESOURCE(32649)
	HCURSOR hCursor;	
	hCursor = AfxGetApp()->LoadStandardCursor(MAKEINTRESOURCE(32649));
	::SetCursor(hCursor);

	Invalidate();
	bSuccess = TRUE;
	
end:
	file.Close();	
	return bSuccess;
}

void CBmpShow::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here	
	CRect rcClient;
	GetClientRect(rcClient);
	if(m_lpBMPHdr == NULL) 
	{
		dc.FillSolidRect(rcClient, RGB(200, 200, 200));		
		return;
	}		
    //为了不闪烁,分四个矩形刷灰色
	CRect rcLeft(rcClient), rcRight(rcClient), rcUp(rcClient), rcDown(rcClient);
	rcLeft.right = m_rcDraw.left;
	rcRight.left = m_rcDraw.right;
	rcUp.bottom = m_rcDraw.top;
	rcUp.left = rcLeft.right;
	rcUp.right = rcRight.left;
	rcDown.top = m_rcDraw.bottom;
	rcDown.left = rcLeft.right;
	rcDown.right = rcRight.left;
	dc.FillSolidRect(rcLeft, RGB(200, 200, 200));
	dc.FillSolidRect(rcRight, RGB(200, 200, 200));
	dc.FillSolidRect(rcUp, RGB(200, 200, 200));
	dc.FillSolidRect(rcDown, RGB(200, 200, 200));


//	dc.StretchBlt(m_rcDraw.left, m_rcDraw.top, m_rcDraw.Width(), m_rcDraw.Height(), 
//		m_pMemDC, 0, 0, m_lpBMPHdr->biWidth, m_lpBMPHdr->biHeight, SRCCOPY);
	dc.BitBlt(m_rcDraw.left, m_rcDraw.top, m_rcDraw.Width(), m_rcDraw.Height(), 
		m_pMemDC, 0, 0, SRCCOPY); 
	// Do not call CStatic::OnPaint() for painting messages
}

BOOL CBmpShow::SetSaveBmpPath(LPCTSTR pszPath)
{
	if (0 == m_dwImageSize)
	{
		return FALSE;
	}
	CFile file;
	BOOL bOpen = file.Open(pszPath, CFile::modeCreate|CFile::modeWrite);
	if (!bOpen)
	{
		AfxMessageBox("保存位图失败");
		return FALSE;
	}

	BITMAPFILEHEADER bmfh;
	bmfh.bfType = 0x4d42;  // 'BM'
	int sizeHdr = sizeof(BITMAPINFOHEADER) + 
		sizeof(RGBQUAD) * m_nColorEntries;
	bmfh.bfSize = 0;
	bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
	bmfh.bfOffBits = 
		sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
		sizeof(RGBQUAD) * m_nColorEntries;	
	
	BYTE *pTemp = new BYTE[m_dwImageSize];
	ZeroMemory(pTemp, m_dwImageSize);
	PaintBmpAndText();
	int nCount = GetDIBits(m_pMemDC->GetSafeHdc(), (HBITMAP)m_pMemBmp->m_hObject, 0, m_lpBMPHdr->biHeight, 
		(LPVOID)pTemp, (BITMAPINFO*)m_lpBMPHdr, DIB_RGB_COLORS);
	
	file.Write((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));
	file.Write((LPVOID) m_lpBMPHdr,  sizeHdr);
	file.Write((LPVOID)(pTemp), m_dwImageSize);
	file.Close();
	delete[] pTemp;
	
	return TRUE;
}

BOOL CBmpShow::CreateMemObject(CDC *pDC, BITMAPINFO *lpbmi, int* pnLineChar)
{
	if (IsBadWritePtr(m_lpDIBits, m_dwImageSize))
	{
		return FALSE;
	}
	
	if (NULL == m_pMemDC)
	{
		m_pMemDC = new CDC();
		m_pMemDC->CreateCompatibleDC(pDC);
	}

	if (m_pMemBmp != NULL)
	{
		m_pMemDC->SelectObject(m_pOldBmp);		
		delete m_pMemBmp;
		m_pMemBmp = NULL;
	}

/*	CPen pen, *oldPen;
	oldPen = NULL;
	pen.CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
	oldPen = m_pMemDC->SelectObject(&pen); */
	

	m_pMemBmp = new CBitmap();
	m_pMemBmp->CreateCompatibleBitmap(pDC, m_lpBMPHdr->biWidth+10, m_lpBMPHdr->biHeight+10);
	m_pOldBmp = m_pMemDC->SelectObject(m_pMemBmp);
	m_pMemDC->FillSolidRect(0, 0, m_lpBMPHdr->biWidth+10, m_lpBMPHdr->biHeight+10, RGB(255, 255, 255));

/*	SetDIBitsToDevice(m_pMemDC->GetSafeHdc(), 0, 0, 
		m_lpBMPHdr->biWidth, m_lpBMPHdr->biHeight, 
		0, 0, 0, m_lpBMPHdr->biHeight, m_lpDIBits, (LPBITMAPINFO)lpbmi, DIB_RGB_COLORS);*/

	SetDIBits(m_pMemDC->GetSafeHdc(), (HBITMAP)m_pMemBmp->m_hObject, 
		0, m_lpBMPHdr->biHeight, (LPVOID)m_lpDIBits, (BITMAPINFO*)m_lpBMPHdr, DIB_RGB_COLORS);

	
//	m_pMemDC->SelectStockObject(NULL_BRUSH);
//	CFont      fontText;
	
  //  fontText.CreateFont(-120, 0, 0, 0, 400, FALSE, FALSE, 0,
	//	ANSI_CHARSET, OUT_DEFAULT_PRECIS,
	//	CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
	//	DEFAULT_PITCH | FF_SWISS, "Arial");
   // CFont* pOldFont = (CFont*) pDC->SelectObject(&fontText);	
	

	TEXTMETRIC tm;
	m_pMemDC->GetTextMetrics(&tm);
	int nLineChar = (m_lpBMPHdr->biWidth - 20) / tm.tmAveCharWidth;
	int nLineNum = (m_lpBMPHdr->biHeight - 20) / (tm.tmHeight + tm.tmExternalLeading);
	*pnLineChar = nLineChar * nLineNum;
	if (0 == *pnLineChar)
	{
		*pnLineChar = 1;
	}
	
//	m_pMemDC->SelectObject(pOldFont);
//	m_pMemDC->SelectObject(oldPen);

	return TRUE;

}

void CBmpShow::ComputePaletteSize(int nBitCounts)
{
	if((m_lpBMPHdr == NULL) || (m_lpBMPHdr->biClrUsed == 0))
	{
		switch(nBitCounts) 
		{
		case 1:
			m_nColorEntries = 2;
			break;
		case 4:
			m_nColorEntries = 16;
			break;
		case 8:
			m_nColorEntries = 256;
			break;
		case 16:
		case 24:
		case 32:

⌨️ 快捷键说明

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