📄 bmpshow.cpp
字号:
m_nColorEntries = 0;
break;
default:
ASSERT(FALSE);
}
}//end if
else
{
m_nColorEntries = m_lpBMPHdr->biClrUsed;
}
ASSERT((m_nColorEntries >= 0) && (m_nColorEntries <= 256));
}
void CBmpShow::ComputeImageSize(LPBITMAPINFOHEADER lpbmih, LPDWORD lpdwSize)
{
if(lpbmih->biSize != sizeof(BITMAPINFOHEADER))
{
TRACE("Not a valid Windows bitmap -- probably an OS/2 bitmap\n");
throw new CException;
}
//有的图片的bisizeImage不一定就是正确的值
m_dwImageSize = m_lpBMPHdr->biSizeImage;
if(m_dwImageSize == 0)
{//宽度要4字节对齐
DWORD dwBytes = ((DWORD) m_lpBMPHdr->biWidth * m_lpBMPHdr->biBitCount) / 32;
if(((DWORD) m_lpBMPHdr->biWidth * m_lpBMPHdr->biBitCount) % 32)
{
dwBytes++;
}
dwBytes *= 4;
//没被压缩
m_dwImageSize = dwBytes * m_lpBMPHdr->biHeight;
m_lpBMPHdr->biSizeImage = m_dwImageSize;
}
}
void CBmpShow::SetBmpText(const CString &strText, BOOL bRepaint)
{
m_strBmpText = strText;
PaintBmpAndText();
CRect rcTemp = m_textTracker.m_rect;
m_textTracker.m_rect -= m_rcDraw.TopLeft();
m_textTracker.Draw(m_pMemDC);
m_textTracker.m_rect = rcTemp;
if (bRepaint)
{
Invalidate();
}
}
BOOL CBmpShow::SetBmpInfo(const LPBITMAPINFOHEADER lpbmih, const LPVOID lpvBits, int* pnCharLimit)
{
if (m_lpBMPHdr != NULL)
{
delete[] m_lpBMPHdr;
m_lpBMPHdr = NULL;
}
m_lpBMPHdr = new BITMAPINFOHEADER;
memcpy(m_lpBMPHdr, lpbmih, sizeof(BITMAPINFOHEADER));
ComputePaletteSize(m_lpBMPHdr->biBitCount);
if (m_nColorEntries != 0)
{
AfxMessageBox("本图片不是一个真彩色位图");
delete m_lpBMPHdr;
return FALSE;
}
// m_dwImageSize = lpbmih->biSizeImage;
ComputeImageSize(m_lpBMPHdr, &m_dwImageSize);
if (m_lpDIBits != NULL)
{
delete[] m_lpDIBits;
m_lpDIBits = NULL;
}
m_lpDIBits = new BYTE[m_dwImageSize];
memcpy(m_lpDIBits, lpvBits, m_dwImageSize);
if (m_lpDIBits != NULL)
{
delete[] m_lpDIBits;
m_lpDIBits = NULL;
}
CDC *pDC = GetDC();
CreateMemObject(pDC, (LPBITMAPINFO)m_lpBMPHdr, pnCharLimit);
ComputeDrawRect();
ReleaseDC(pDC);
Invalidate();
return TRUE;
}
BOOL CBmpShow::SaveModify(LPBITMAPINFOHEADER lpbmih, LPVOID lpvBits)
{
PaintBmpAndText();
int nCount = GetDIBits(m_pMemDC->GetSafeHdc(), (HBITMAP)m_pMemBmp->m_hObject, 0, m_lpBMPHdr->biHeight,
(LPVOID)lpvBits, (BITMAPINFO*)lpbmih, DIB_RGB_COLORS);
return TRUE;
}
BOOL CBmpShow::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return FALSE;
// return CStatic::OnEraseBkgnd(pDC);
}
void CBmpShow::ComputeDrawRect()
{
CRect rcClient;
GetClientRect(rcClient);
CRect rcDraw(rcClient);
float fWidComp = (float)m_lpBMPHdr->biWidth / (float)rcClient.Width();
float fHeiComp = (float)m_lpBMPHdr->biHeight / (float)rcClient.Height();
/* if ((fWidComp < 1.0) && (fHeiComp < 1.0))
{//图片小,居中显示
rcDraw.left = (rcClient.Width() - m_lpBMPHdr->biWidth) / 2 + rcClient.left;
rcDraw.right = rcDraw.left + m_lpBMPHdr->biWidth;
rcDraw.top = (rcDraw.Height() - m_lpBMPHdr->biHeight) / 2 + rcClient.top;
rcDraw.bottom = rcDraw.top + m_lpBMPHdr->biHeight;
}
else if (fWidComp > fHeiComp)
{//宽度优先处理,超过显示区域,缩小处理,宽度和现示区域相同
rcDraw.top = (rcClient.Height() - int((float)m_lpBMPHdr->biHeight/fWidComp)) / 2 + rcClient.top;
rcDraw.bottom = rcDraw.top + int((float)m_lpBMPHdr->biHeight/fWidComp);
}
else
{//高度优先处理
rcDraw.left = (rcClient.Width() - int((float)m_lpBMPHdr->biWidth/fHeiComp)) / 2 + rcClient.left;
rcDraw.right = rcDraw.left + int((float)m_lpBMPHdr->biWidth/fHeiComp);
}*/
if (fWidComp < 1.0)
{
rcDraw.left = (rcClient.Width() - m_lpBMPHdr->biWidth) / 2 + rcClient.left;
rcDraw.right = rcDraw.left + m_lpBMPHdr->biWidth;
}
if (fHeiComp < 1.0)
{
rcDraw.top = (rcDraw.Height() - m_lpBMPHdr->biHeight) / 2 + rcClient.top;
rcDraw.bottom = rcDraw.top + m_lpBMPHdr->biHeight;
}
m_rcDraw = rcDraw;
m_textTracker.SetLimitRegion(m_rcDraw);
//计算文本矩形的初始尺寸
TEXTMETRIC tm;
m_pMemDC->GetTextMetrics(&tm);
m_textTracker.m_rect.left = m_rcDraw.left + 10;
m_textTracker.m_rect.right = m_rcDraw.right - 10;
m_textTracker.m_rect.top = m_rcDraw.top + 10;
m_textTracker.m_rect.bottom = m_textTracker.m_rect.top + 10 + tm.tmHeight + tm.tmExternalLeading;
m_textTracker.SetMinInterval(tm.tmMaxCharWidth, tm.tmHeight + tm.tmExternalLeading);
}
void CBmpShow::PaintBmpAndText()
{//绘制图像和文字
SetDIBits(m_pMemDC->GetSafeHdc(), (HBITMAP)m_pMemBmp->m_hObject,
0, m_lpBMPHdr->biHeight, (LPVOID)m_lpDIBits, (BITMAPINFO*)m_lpBMPHdr, DIB_RGB_COLORS);
if (m_strBmpText.GetLength() > 0)
{
CRect rcText = m_textTracker.m_rect - m_rcDraw.TopLeft();
m_pMemDC->SetBkMode(TRANSPARENT);
m_pMemDC->SetTextColor(RGB(220, 220, 220));
rcText.OffsetRect(1, 1);
CString strText = NewLineString(m_strBmpText, rcText);
m_pMemDC->DrawText(strText, rcText, DT_LEFT|DT_WORDBREAK);
// m_pMemDC->TextOut(11, 11, m_strBmpText);
m_pMemDC->SetTextColor(RGB(0, 0, 0));
rcText.OffsetRect(-1, -1);
m_pMemDC->DrawText(strText, rcText, DT_LEFT|DT_WORDBREAK);
// m_pMemDC->TextOut(10, 10, m_strBmpText);
}
}
BOOL CBmpShow::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
if ((pWnd == this) && (m_textTracker.SetCursor(pWnd, nHitTest)))
{
return TRUE;
}
return CStatic::OnSetCursor(pWnd, nHitTest, message);
}
void CBmpShow::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
int nIn = m_textTracker.HitTest(point);
if (nIn >= 0)
{
m_textTracker.Track(this, point, TRUE);
PaintBmpAndText();
CRect rcTemp = m_textTracker.m_rect;
m_textTracker.m_rect -= m_rcDraw.TopLeft();
m_textTracker.Draw(m_pMemDC);
m_textTracker.m_rect = rcTemp;
Invalidate();
}
CStatic::OnLButtonDown(nFlags, point);
}
CString CBmpShow::NewLineString(const CString &strSrc, const RECT rect)
{//根据举行的宽度,插入换行符
TEXTMETRIC tm;
m_pMemDC->GetTextMetrics(&tm);
CString strNew = strSrc;
if (0 == strNew.GetLength())
{
return strNew;
}
int nLineCharNum = abs(rect.right-rect.left) / tm.tmAveCharWidth;
if (nLineCharNum <= 0)
{
nLineCharNum = 0;
}
int nLeadChar = 0;
int nLineLen = 0;
for (int i=0; i<strNew.GetLength(); i++)
{
if (IsDBCSLeadByte(strNew[i]))
{
nLeadChar++;
}
nLineLen++;
if ((strNew[i] == 0x0d) && (strNew[i+1] == 0x0a))
{
nLineLen = 0;
nLeadChar = 0;
continue;
}
if (nLineLen > nLineCharNum)
{
if ((0==nLeadChar%2) && IsDBCSLeadByte(strNew[i]))
{
strNew.Insert(i-1, (BYTE)0x0a);//\n
strNew.Insert(i-1, (BYTE)0x0d);//\r
}
else
{
strNew.Insert(i, (BYTE)0x0a);
strNew.Insert(i, (BYTE)0x0D);
i++;
}
nLineLen = 0;
nLeadChar = 0;
}
}
return strNew;
}
void CBmpShow::CreateScrollBar()
{
/* CRect rcClient;
GetClientRect(rcClient);
if (m_lpBMPHdr->biWidth > rcClient.Width())
{
m_nSBarHei = 15;
CRect rcBar(rcClient);
rcBar.top = rcBar.bottom - m_nSBarHei;
SCROLLINFO sbinfo;
ZeroMemory(&sbinfo, sizeof(SCROLLINFO));
sbinfo.cbSize = sizeof(SCROLLINFO);
sbinfo.fMask = SIF_ALL;
sbinfo.nMin = 0;
sbinfo.nPage = m_lpBMPHdr->biWidth / 10;
sbinfo.nMax = m_lpBMPHdr->biWidth - sbinfo.nPage;
VERIFY(m_ScrollBarHor.Create(
SBS_HORZ | WS_CHILD | WS_VISIBLE, rcBar, this, 500));
}*/
}
void CBmpShow::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CStatic::OnMouseMove(nFlags, point);
}
int CBmpShow::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CStatic::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -