📄 bitmapbox.cpp
字号:
//////////////////////////////////////////////////////////////////////
// FileFury
// Copyright (c) 2000 Tenebril Incorporated
// All rights reserved.
//
// This source code is governed by the Tenebril open source
// license (http://www.tenebril.com/developers/opensource/license.html)
//
// For more information on this and other open source applications,
// visit the Tenebril OpenSource page:
// http://www.tenebril.com/developers/opensource
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Resource.h"
#include "BitmapBox.h"
CBitmapBox::CBitmapBox()
{
InitBackDC = false;
Tiling = false;
}
CBitmapBox::~CBitmapBox()
{
}
BEGIN_MESSAGE_MAP(CBitmapBox, CWnd)
ON_WM_DRAWITEM()
END_MESSAGE_MAP()
BOOL CBitmapBox::Create(DWORD dwStyle, const RECT& rect,
CWnd* pParentWnd, UINT nID,
UINT BitmapID, CSize bmpSize)
{
BitmapSize = bmpSize;
BOOL Result;
Result = CWnd::CreateEx(WS_EX_LEFT,
_T("BUTTON"), NULL, dwStyle | BS_OWNERDRAW, rect, pParentWnd, nID);
SetBitmap(BitmapID);
return Result;
}
static CSize GetBitmapSize(CBitmap *Bmp)
{
BITMAP bm;
CSize size;
Bmp->GetBitmap(&bm);
size.cx = bm.bmWidth;
size.cy = bm.bmHeight;
return size;
}
void CBitmapBox::SetBitmap(UINT BitmapID)
{
// if(BackBitmap)
// {
// delete BackBitmap;
// BackBitmap = NULL;
// }
if(!InitBackDC)
{
InitBackDC = true;
CClientDC ClientDC(this);
BackDC.CreateCompatibleDC(&ClientDC);
BackColor = RGB(191, 191, 191);
}
if(BitmapID > 0)
{
BackBitmap = new CBitmap;
BackBitmap->LoadBitmap(BitmapID);
BackDC.SelectObject(BackBitmap);
BitmapSize = GetBitmapSize(BackBitmap);
}
else
{
CRect ClientRect;
CBrush BackBrush(RGB(191, 191, 191));
GetClientRect(&ClientRect);
BackBitmap = new CBitmap;
BackBitmap->CreateCompatibleBitmap(&BackDC,
ClientRect.Width(), ClientRect.Height());
BackDC.SelectObject(BackBitmap);
BackDC.FillRect(ClientRect, &BackBrush);
}
InvalidateRect(NULL, FALSE);
}
BOOL CBitmapBox::LoadBMPImage(LPCTSTR sBMPFile, CBitmap& bitmap, CPalette *pPal,
CSize *BmpSize)
{
CFile file;
if(!file.Open( sBMPFile, CFile::modeRead))
return FALSE;
BITMAPFILEHEADER bmfHeader; // Read file header
if(file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
return FALSE; // File type should be 'BM'
if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))
return FALSE;
// Get length of the remainder of the file and allocate memory
DWORD nPackedDIBLen = file.GetLength() - sizeof(BITMAPFILEHEADER);
HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nPackedDIBLen);
if (hDIB == 0)
return FALSE; // Read the remainder of the bitmap file.
if (file.ReadHuge((LPSTR)hDIB, nPackedDIBLen) != nPackedDIBLen )
{
::GlobalFree(hDIB);
return FALSE;
}
BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB ;
BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
// If bmiHeader.biClrUsed is zero we have to infer the number
// of colors from the number of bits used to specify it.
if(BmpSize)
{
BmpSize->cx = (int)bmiHeader.biWidth;
BmpSize->cy = (int)bmiHeader.biHeight;
}
int nColors = bmiHeader.biClrUsed ? bmiHeader.biClrUsed :
1 << bmiHeader.biBitCount; LPVOID lpDIBBits;
if( bmInfo.bmiHeader.biBitCount > 8 )
lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
else
lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
// Create the logical palette
if( pPal != NULL )
{ // Create the palette
if( nColors <= 256 )
{
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
pLP->palVersion = 0x300;
pLP->palNumEntries = nColors;
for( int i=0; i < nColors; i++)
{
pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
pLP->palPalEntry[i].peFlags = 0;
}
pPal->CreatePalette( pLP );
delete[] pLP;
}
}
CClientDC dc(NULL);
CPalette* pOldPalette = NULL;
if( pPal )
{
pOldPalette = dc.SelectPalette( pPal, FALSE );
dc.RealizePalette();
}
HBITMAP hBmp = CreateDIBitmap( dc.m_hDC,
&bmiHeader, // pointer to bitmap size and format data
CBM_INIT, // initialization flag
lpDIBBits, // pointer to initialization data
&bmInfo, // pointer to bitmap color-format data
DIB_RGB_COLORS); // color-data usage
bitmap.Attach( hBmp );
if( pOldPalette )
dc.SelectPalette( pOldPalette, FALSE );
::GlobalFree(hDIB);
return TRUE;
}
void CBitmapBox::SetBitmap(char *BitmapName, bool IsResource, bool Tile)
{
bool Clear = false;
CBitmap *OldBitmap = BackBitmap;
CClientDC ClientDC(this);
CRect ClientRect;
GetClientRect(&ClientRect);
if(!InitBackDC)
{
InitBackDC = true;
BackDC.CreateCompatibleDC(&ClientDC);
BackColor = RGB(0, 191, 0);
}
if(BitmapName && strlen(BitmapName) > 0)
{
BackBitmap = new CBitmap;
if(IsResource)
BackBitmap->LoadBitmap(BitmapName);
else
{
CPalette Palette;
CSize NewBitmapSize;
if(!LoadBMPImage(BitmapName, *BackBitmap, &Palette, &NewBitmapSize))
{
BitmapSize.cx = ClientRect.Width();
BitmapSize.cy = ClientRect.Height();
BackBitmap->CreateCompatibleBitmap(&BackDC,
BitmapSize.cx, BitmapSize.cy);
Clear = true;
}
else
BitmapSize = NewBitmapSize;
}
BackDC.SelectObject(BackBitmap);
}
else
{
BitmapSize.cx = ClientRect.Width();
BitmapSize.cy = ClientRect.Height();
BackBitmap->CreateCompatibleBitmap(&BackDC,
BitmapSize.cx, BitmapSize.cy);
Clear = true;
}
if(Clear)
{
CRect ClipRect;
CBrush WhiteBrush(RGB(255, 255, 255));
ClipRect.top = 0;
ClipRect.left = 0;
ClipRect.right = BitmapSize.cx;
ClipRect.bottom = BitmapSize.cy;
BackDC.FillRect(ClipRect, &WhiteBrush);
}
else
{
// if(OldBitmap)
// delete OldBitmap;
}
Tiling = Tile;
InvalidateRect(NULL, FALSE);
}
void CBitmapBox::DrawItem(LPDRAWITEMSTRUCT DrawItemStruct)
{
CRect ClientRect;
CClientDC DrawDC(this);
GetClientRect(&ClientRect);
CPoint StartPoint;
CDC MemDC;
CBitmap MemBmp, *OldBmp;
if(!InitBackDC)
{
InitBackDC = true;
BackDC.CreateCompatibleDC(&DrawDC);
if(BackBitmap)
{
BackDC.SelectObject(BackBitmap);
BackColor = BackDC.GetPixel(0, 0);
}
else
BackColor = RGB(0, 191, 0);
}
CBrush BackBrush(BackColor);
MemDC.CreateCompatibleDC(&DrawDC);
MemBmp.CreateCompatibleBitmap(&DrawDC, ClientRect.Width(), ClientRect.Height());
OldBmp = MemDC.SelectObject(&MemBmp);
CRect ZeroClient = CRect(0, 0, ClientRect.Width(), ClientRect.Height());
MemDC.FillRect(&ZeroClient, &BackBrush);
StartPoint.x = (int)((ClientRect.Width() - BitmapSize.cx) / 2);
StartPoint.y = (int)((ClientRect.Height() - BitmapSize.cy) / 2);
if(BackBitmap)
{
if(!Tiling || (StartPoint.x <= 0 && StartPoint.y <= 0))
MemDC.BitBlt(StartPoint.x, StartPoint.y, BitmapSize.cx, BitmapSize.cy,
&BackDC, 0, 0, SRCCOPY);
else
{
for(StartPoint.x = 0; StartPoint.x < ClientRect.Width();
StartPoint.x += BitmapSize.cx)
{
for(StartPoint.y = 0; StartPoint.y < ClientRect.Height();
StartPoint.y += BitmapSize.cy)
{
MemDC.BitBlt(StartPoint.x, StartPoint.y,
BitmapSize.cx, BitmapSize.cy,
&BackDC, 0, 0, SRCCOPY);
}
}
}
}
DrawDC.BitBlt(ClientRect.left, ClientRect.top,
ClientRect.Width(), ClientRect.Height(), &MemDC, 0, 0, SRCCOPY);
MemDC.SelectObject(OldBmp);
return;
}
CBackBitmapBox::CBackBitmapBox()
{
InitBackDC = false;
}
CBackBitmapBox::~CBackBitmapBox()
{
}
BEGIN_MESSAGE_MAP(CBackBitmapBox, CWnd)
ON_WM_DRAWITEM()
END_MESSAGE_MAP()
BOOL CBackBitmapBox::Create(DWORD dwStyle, const RECT& rect,
CWnd* pParentWnd, UINT nID,
LPCTSTR BmpID, CSize bmpSize, COLORREF BackgroundColor)
{
BitmapSize = bmpSize;
VERIFY(BackBitmap.LoadBitmap(BmpID));
OriginalImageBackground = BackgroundColor;
return CWnd::CreateEx(WS_EX_LEFT,
_T("BUTTON"), NULL, dwStyle | BS_OWNERDRAW, rect, pParentWnd, nID);
}
BOOL CBackBitmapBox::Create(DWORD dwStyle, const RECT& rect,
CWnd* pParentWnd, UINT nID,
UINT BmpID, CSize bmpSize, COLORREF BackgroundColor)
{
BitmapSize = bmpSize;
VERIFY(BackBitmap.LoadBitmap(BmpID));
OriginalImageBackground = BackgroundColor;
return CWnd::CreateEx(WS_EX_LEFT,
_T("BUTTON"), NULL, dwStyle | BS_OWNERDRAW, rect, pParentWnd, nID);
}
BOOL CBackBitmapBox::LoadBMPImage(LPCTSTR sBMPFile, CBitmap& bitmap, CPalette *pPal,
CSize *BmpSize)
{
CFile file;
if(!file.Open( sBMPFile, CFile::modeRead))
return FALSE;
BITMAPFILEHEADER bmfHeader; // Read file header
if(file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
return FALSE; // File type should be 'BM'
if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))
return FALSE;
// Get length of the remainder of the file and allocate memory
DWORD nPackedDIBLen = file.GetLength() - sizeof(BITMAPFILEHEADER);
HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nPackedDIBLen);
if (hDIB == 0)
return FALSE; // Read the remainder of the bitmap file.
if (file.ReadHuge((LPSTR)hDIB, nPackedDIBLen) != nPackedDIBLen )
{
::GlobalFree(hDIB);
return FALSE;
}
BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB ;
BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
// If bmiHeader.biClrUsed is zero we have to infer the number
// of colors from the number of bits used to specify it.
if(BmpSize)
{
BmpSize->cx = (int)bmiHeader.biWidth;
BmpSize->cy = (int)bmiHeader.biHeight;
}
int nColors = bmiHeader.biClrUsed ? bmiHeader.biClrUsed :
1 << bmiHeader.biBitCount; LPVOID lpDIBBits;
if( bmInfo.bmiHeader.biBitCount > 8 )
lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
else
lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
// Create the logical palette
if( pPal != NULL )
{ // Create the palette
if( nColors <= 256 )
{
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
pLP->palVersion = 0x300;
pLP->palNumEntries = nColors;
for( int i=0; i < nColors; i++)
{
pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
pLP->palPalEntry[i].peFlags = 0;
}
pPal->CreatePalette( pLP );
delete[] pLP;
}
}
CClientDC dc(NULL);
CPalette* pOldPalette = NULL;
if( pPal )
{
pOldPalette = dc.SelectPalette( pPal, FALSE );
dc.RealizePalette();
}
HBITMAP hBmp = CreateDIBitmap( dc.m_hDC,
&bmiHeader, // pointer to bitmap size and format data
CBM_INIT, // initialization flag
lpDIBBits, // pointer to initialization data
&bmInfo, // pointer to bitmap color-format data
DIB_RGB_COLORS); // color-data usage
bitmap.Attach( hBmp );
if( pOldPalette )
dc.SelectPalette( pOldPalette, FALSE );
::GlobalFree(hDIB);
return TRUE;
}
void CBackBitmapBox::DrawItem(LPDRAWITEMSTRUCT DrawItemStruct)
{
CRect ClientRect;
CClientDC DrawDC(this);
GetClientRect(&ClientRect);
CPoint StartPoint;
CDC MemDC;
CBitmap MemBmp, *OldBmp;
if(!InitBackDC)
{
InitBackDC = true;
BackDC.CreateCompatibleDC(&DrawDC);
BackDC.SelectObject(&BackBitmap);
BackColor = BackDC.GetPixel(0, 0);
}
CBrush BackBrush(BackColor);
MemDC.CreateCompatibleDC(&DrawDC);
MemBmp.CreateCompatibleBitmap(&DrawDC, ClientRect.Width(), ClientRect.Height());
OldBmp = MemDC.SelectObject(&MemBmp);
CRect ZeroClient = CRect(0, 0, ClientRect.Width(), ClientRect.Height());
MemDC.FillRect(&ZeroClient, &BackBrush);
StartPoint.x = (int)((ClientRect.Width() - BitmapSize.cx) / 2);
StartPoint.y = (int)((ClientRect.Height() - BitmapSize.cy) / 2);
MemDC.BitBlt(StartPoint.x, StartPoint.y, BitmapSize.cx, BitmapSize.cy,
&BackDC, 0, 0, SRCCOPY);
/* Combine the image (MemDC) with the background (DrawDC) */
CBitmap MaskBmp, *OldMaskBmp;
CDC MaskDC;
MaskDC.CreateCompatibleDC(&DrawDC);
/* Create monochrome bitmap for the mask */
MaskBmp.CreateBitmap(ClientRect.Width(), ClientRect.Height(), 1, 1, NULL);
OldMaskBmp = MaskDC.SelectObject(&MaskBmp);
/* Set image background color */
MemDC.SetBkColor(OriginalImageBackground);
/* Mask is white wherever the icon is colored */
MaskDC.BitBlt(0, 0, ClientRect.Width(), ClientRect.Height(), &MemDC, 0, 0, SRCCOPY);
/* Make the background black wherever the icon is colored */
DrawDC.SetBkColor(RGB(255,255,255));
DrawDC.SetTextColor(RGB(0,0,0));
DrawDC.BitBlt(ClientRect.left, ClientRect.top,
ClientRect.Width(), ClientRect.Height(),
&MaskDC, 0, 0, SRCAND);
MemDC.SetBkColor(RGB(0,0,0));
MemDC.SetTextColor(RGB(255,255,255));
MemDC.BitBlt(0, 0, ClientRect.Width(), ClientRect.Height(),
&MaskDC, 0, 0, SRCAND);
/* OR the bitmaps together */
DrawDC.BitBlt(ClientRect.left, ClientRect.top,
ClientRect.Width(), ClientRect.Height(),
&MemDC, 0, 0, SRCPAINT);
MaskDC.SelectObject(OldMaskBmp);
MemDC.SelectObject(OldBmp);
return;
}
CFontPreviewBox::CFontPreviewBox()
{
}
CFontPreviewBox::~CFontPreviewBox()
{
}
BEGIN_MESSAGE_MAP(CFontPreviewBox, CWnd)
ON_WM_DRAWITEM()
END_MESSAGE_MAP()
BOOL CFontPreviewBox::Create(DWORD dwStyle, const RECT& rect,
CWnd* pParentWnd, UINT nID)
{
return CWnd::CreateEx(WS_EX_LEFT,
_T("BUTTON"), NULL, dwStyle | BS_OWNERDRAW, rect, pParentWnd, nID);
}
void CFontPreviewBox::SetFont(LOGFONT font)
{
LogFont = font;
InvalidateRect(NULL, FALSE);
}
void CFontPreviewBox::DrawItem(LPDRAWITEMSTRUCT DrawItemStruct)
{
CRect ClientRect;
CClientDC DrawDC(this);
COLORREF BackColor = RGB(255, 255, 255);
CFont ViewFont, *OldFont;
GetClientRect(&ClientRect);
CDC MemDC;
CBitmap MemBmp, *OldBmp;
CBrush BackBrush(BackColor);
MemDC.CreateCompatibleDC(&DrawDC);
MemBmp.CreateCompatibleBitmap(&DrawDC, ClientRect.Width(), ClientRect.Height());
OldBmp = MemDC.SelectObject(&MemBmp);
CRect ZeroClient = CRect(0, 0, ClientRect.Width(), ClientRect.Height());
MemDC.FillRect(&ZeroClient, &BackBrush);
ViewFont.CreateFontIndirect(&LogFont);
OldFont = MemDC.SelectObject(&ViewFont);
MemDC.DrawText("ABCXYZ\nabcxyz", -1, ZeroClient, DT_NOCLIP);
DrawDC.BitBlt(ClientRect.left, ClientRect.top,
ClientRect.Width(), ClientRect.Height(), &MemDC, 0, 0, SRCCOPY);
MemDC.SelectObject(OldBmp);
MemDC.SelectObject(OldFont);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -