📄 bmphelper.cpp
字号:
//
// CBMPHelper - General helper class for BMP stuff
// Looks better than the global var/function variant of it!
// (No problems if we use different images on, for example, multiple views in a document)
//
// Also added the possible use of transparent images (normally only under Win98/Win2000 only)
// You can copy MSIMG32.DLL also onto your WinNT4 system32 dir. Works fine..
// Dunno for Win95..
//
// This code runs only in transparent if the MSIMG32.DLL is found...
// Otherwise the Non-transparent code is used to display the image
//
// Albert 'The Mad Butcher!' van Peppen, 17 Dec, 1999
//
#include "stdafx.h"
#include "BMPHelper.h"
#include "memdc.h"
#include <math.h>
CBMPHelper::CBMPHelper()
{
m_oldRect.SetRect(0,0,0,0);
}
CRect &CBMPHelper::GetOldRect()
{
return m_oldRect;
}
void CBMPHelper::DrawTheBackground(CWnd *view,CDC *pDC,CPalette *mp_palette,CBitmap *mp_bitmap,BOOL middle, BOOL bFitToClient, BOOL bUseTransparent)
{
if (pDC->IsPrinting()) {
return;
}
CRect rect;
CPalette *old_palette=NULL;
// Select and realize the palette
if(pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE && mp_palette->m_hObject != NULL) {
old_palette=pDC->SelectPalette( mp_palette, FALSE );
pDC->RealizePalette();
}
view->GetClientRect(rect);
pDC->DPtoLP(rect);
CMemDC DC(pDC,rect);
CDC dcImage;
if(!dcImage.CreateCompatibleDC(pDC)) {
return;
}
BITMAP bm;
mp_bitmap->GetBitmap(&bm);
// Paint the image.
CBitmap* pOldBitmap = dcImage.SelectObject(mp_bitmap);
if (bUseTransparent) {
HMODULE msimg32 = ::LoadLibrary("msimg32.dll");
if (!msimg32) {
TRACE("Library 'Msimg32.dll' was not loaded\n");
goto JustNormal; // If transparent not possible, then non-transparent...
}
void (WINAPI *transparentblt)(HDC,int,int,int,int,HDC,int,int,int,int,UINT);
(FARPROC &)transparentblt = GetProcAddress(msimg32, "TransparentBlt");
CBrush NewBrush(GetSysColor(COLOR_APPWORKSPACE));
CBrush* pOldBrush = (CBrush*)DC->SelectObject(&NewBrush);
CRect crect;
m_oldRect = CRect((rect.Width()-bm.bmWidth)/2,(rect.Height()-bm.bmHeight)/2,(rect.Width()-bm.bmWidth)/2+ bm.bmWidth,(rect.Height()-bm.bmHeight)/2+ bm.bmHeight);
pDC->GetClipBox(&crect);
DC->PatBlt( crect.left, crect.top, crect.Width(), crect.Height(), PATCOPY);
DC->SelectObject(pOldBrush);
NewBrush.DeleteObject();
if (middle || bFitToClient) {
if (middle) { // Just in the middle
transparentblt(DC->m_hDC,
m_oldRect.left, m_oldRect.top, bm.bmWidth, bm.bmHeight,
dcImage.m_hDC,
0, 0, bm.bmWidth, bm.bmHeight,
GetSysColor(COLOR_WINDOW));
}
else { // So, bFitToClient is TRUE ;)
transparentblt(DC->m_hDC,
rect.left, rect.top, rect.Width(), rect.Height(),
dcImage.m_hDC,
0, 0, bm.bmWidth, bm.bmHeight,
GetSysColor(COLOR_WINDOW));
}
}
else {
int i;
int j;
for (i = ((int)floor((double)rect.left/bm.bmWidth)) * bm.bmWidth; i <= rect.right/*rect.Width()*/; i += bm.bmWidth) {
for (j = ((int)floor((double)rect.top/bm.bmHeight)) * bm.bmHeight; j <= rect.bottom/*rect.Height()*/;j += bm.bmHeight) {
transparentblt(DC->m_hDC, i, j, bm.bmWidth, bm.bmHeight, dcImage.m_hDC, 0, 0, bm.bmWidth, bm.bmHeight,GetSysColor(COLOR_WINDOW));
}
}
}
dcImage.SelectObject(pOldBitmap);
pDC->SelectPalette(old_palette,FALSE);
pDC->RealizePalette();
FreeLibrary (msimg32);
}
else {
JustNormal: // If no transparent possible, the jump in here
if (middle || bFitToClient) {
CBrush* pOldBrush = (CBrush*)DC->SelectStockObject(GRAY_BRUSH);
CRect crect;
m_oldRect = CRect((rect.Width()-bm.bmWidth)/2,
(rect.Height()-bm.bmHeight)/2,
(rect.Width()-bm.bmWidth)/2+ bm.bmWidth,
(rect.Height()-bm.bmHeight)/2+ bm.bmHeight);
pDC->GetClipBox(&crect);
DC->PatBlt(crect.left, crect.top, crect.Width(), crect.Height(), PATCOPY);
DC->SelectObject(pOldBrush);
if (middle) { // Just in the middle
DC->BitBlt(m_oldRect.left, m_oldRect.top, bm.bmWidth, bm.bmHeight, &dcImage, 0, 0, SRCCOPY);
}
else { // So, bFitToClient is TRUE ;)
DC->StretchBlt(rect.left, rect.top, rect.Width(), rect.Height(), &dcImage, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
}
}
else {
int i;
int j;
for (i = ((int)floor((double)rect.left/bm.bmWidth)) * bm.bmWidth; i <= rect.right/*rect.Width()*/; i += bm.bmWidth) {
for (j = ((int)floor((double)rect.top/bm.bmHeight))*bm.bmHeight; j <= rect.bottom/*rect.Height()*/;j += bm.bmHeight) {
DC->BitBlt(i, j, bm.bmWidth, bm.bmHeight, &dcImage, 0, 0, SRCCOPY);
}
}
}
dcImage.SelectObject(pOldBitmap);
pDC->SelectPalette(old_palette,FALSE);
pDC->RealizePalette();
}
}
BOOL CBMPHelper::GetBitmapAndPalette(UINT nIDResource, CBitmap &bitmap, CPalette &pal)
{
LPCTSTR lpszResourceName = (LPCTSTR)nIDResource;
HBITMAP hBmp = (HBITMAP)::LoadImage( AfxGetInstanceHandle(),
lpszResourceName, IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION );
if (hBmp == NULL) {
return FALSE;
}
bitmap.Attach( hBmp );
// Create a logical palette for the bitmap
DIBSECTION ds;
BITMAPINFOHEADER &bmInfo = ds.dsBmih;
bitmap.GetObject( sizeof(ds), &ds );
int nColors = bmInfo.biClrUsed ? bmInfo.biClrUsed : 1 << bmInfo.biBitCount;
// Create a halftone palette if colors > 256.
CClientDC dc(NULL); // Desktop DC
if (nColors > 256) {
pal.CreateHalftonePalette( &dc );
}
else {
// Create the palette
RGBQUAD *pRGB = new RGBQUAD[nColors];
CDC memDC;
memDC.CreateCompatibleDC(&dc);
memDC.SelectObject( &bitmap );
::GetDIBColorTable( memDC, 0, nColors, pRGB );
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 = pRGB[i].rgbRed;
pLP->palPalEntry[i].peGreen = pRGB[i].rgbGreen;
pLP->palPalEntry[i].peBlue = pRGB[i].rgbBlue;
pLP->palPalEntry[i].peFlags = 0;
}
pal.CreatePalette( pLP );
delete[] pLP;
delete[] pRGB;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -