📄 bmpshow.cpp
字号:
// 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 + -