📄 wzdbtmap.cpp
字号:
// WzdBtmap.cpp : implementation of the CWzdBitmap class
//
#include "stdafx.h"
#include "WzdBtmap.h"
/////////////////////////////////////////////////////////////////////////////
// CWzdBitmap
IMPLEMENT_DYNAMIC(CWzdBitmap, CBitmap)
CWzdBitmap::CWzdBitmap()
{
m_pPalette=NULL;
}
CWzdBitmap::~CWzdBitmap()
{
if (m_pPalette)
{
delete m_pPalette;
}
}
void CWzdBitmap::Capture(CRect &rect)
{
// cleanup from last capture
if (m_pPalette)
{
delete m_pPalette;
DeleteObject();
}
// save width and height
m_nWidth=rect.Width();
m_nHeight=rect.Height();
////////////////////////////////////////
// copy screen image into a bitmap object
////////////////////////////////////////
// create a device context that accesses the whole screen
CDC dcScreen;
dcScreen.CreateDC("DISPLAY", NULL, NULL, NULL);
// create an empty bitmap in memory
CDC dcMem;
dcMem.CreateCompatibleDC(&dcScreen);
CreateCompatibleBitmap(&dcScreen, m_nWidth, m_nHeight);
dcMem.SelectObject(this);
// copy screen into empty bitmap
dcMem.BitBlt(0,0,m_nWidth,m_nHeight,&dcScreen,rect.left,rect.top,SRCCOPY);
// this bitmap is worthless without the current system palette, so...
///////////////////////////////////////////
// save system palette in this bitmap's palette
///////////////////////////////////////////
// create an empty logical palette that's big enough to hold all the colors
int nColors = (1 << (dcScreen.GetDeviceCaps(BITSPIXEL) *
dcScreen.GetDeviceCaps(PLANES)));
LOGPALETTE *pLogPal = (LOGPALETTE *)new BYTE[
sizeof(LOGPALETTE) + (nColors * sizeof(PALETTEENTRY))];
// initialize this empty palette's header
pLogPal->palVersion = 0x300;
pLogPal->palNumEntries = nColors;
// load this empty palette with the system palette's colors
::GetSystemPaletteEntries(dcScreen.m_hDC, 0, nColors,
(LPPALETTEENTRY)(pLogPal->palPalEntry));
// create the palette with this logical palette
m_pPalette=new CPalette;
m_pPalette->CreatePalette(pLogPal);
// clean up
delete []pLogPal;
dcMem.DeleteDC();
dcScreen.DeleteDC();
}
HANDLE CWzdBitmap::CreateDIB(int *pbmData)
{
///////////////////////////////////////////
// create DIB header from our BITMAP header
///////////////////////////////////////////
BITMAPINFOHEADER bi;
memset(&bi, 0, sizeof(bi));
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biPlanes = 1;
bi.biCompression = BI_RGB;
// get and store dimensions of bitmap
BITMAP bm;
GetObject(sizeof(bm),(LPSTR)&bm);
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
// get number of bits required per pixel
int bits = bm.bmPlanes * bm.bmBitsPixel;
if (bits <= 1)
bi.biBitCount = 1;
else if (bits <= 4)
bi.biBitCount = 4;
else if (bits <= 8)
bi.biBitCount = 8;
else
bi.biBitCount = 24;
// calculate color table size
int biColorSize=0;
if (bi.biBitCount!=24) biColorSize=(1<<bi.biBitCount);
biColorSize*=sizeof(RGBQUAD);
// calculate picture data size
bi.biSizeImage=(DWORD)bm.bmWidth * bi.biBitCount; //bits per row
bi.biSizeImage=(((bi.biSizeImage) + 31) / 32) * 4;//DWORD aligned
bi.biSizeImage*=bm.bmHeight; //bytes required for whole bitmap
// return size to caler in case they want to save to file
if (pbmData)
*pbmData=bi.biSize + biColorSize;
///////////////////////////////////////////
// get DIB color table and picture data
///////////////////////////////////////////
// allocate a hunk of memory to hold header, color table and picture data
HANDLE hDIB = ::GlobalAlloc(GHND, bi.biSize + biColorSize + bi.biSizeImage);
// get a memory pointer to this hunk by locking it
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)::GlobalLock(hDIB);
// copy our header structure into hunk
*lpbi=bi;
// get a device context and select our bitmap's palette into it
CDC dc;
dc.Attach(::GetDC(NULL));
CPalette *pPal = dc.SelectPalette(m_pPalette,FALSE);
dc.RealizePalette();
// load our memory hunk with the color table and picture data
::GetDIBits(dc.m_hDC, (HBITMAP)m_hObject, 0, (UINT)bi.biHeight, (LPSTR)lpbi +
(WORD)lpbi->biSize + biColorSize, (LPBITMAPINFO)lpbi,
DIB_RGB_COLORS);
// clean up
::GlobalUnlock(hDIB);
dc.SelectPalette(pPal,FALSE);
dc.RealizePalette();
// return handle to the DIB
return hDIB;
}
void CWzdBitmap::Print(CDC *pDC)
{
// get DIB version of bitmap
int bmData;
HANDLE hDIB = CreateDIB(&bmData);
// get memory pointers to the DIB's header and data bits
LPBITMAPINFOHEADER lpDIBHdr = (LPBITMAPINFOHEADER)::GlobalLock(hDIB);
LPSTR lpDIBBits = (LPSTR)lpDIBHdr+bmData;
// stretch bitmap to fill printed page with 1/4 inch borders
int cxBorder=pDC->GetDeviceCaps(LOGPIXELSX)/4;
int cyBorder=pDC->GetDeviceCaps(LOGPIXELSY)/4;
int cxPage = pDC->GetDeviceCaps(HORZRES) - (cxBorder*2);
int cyPage=(int)(((double)cxPage/(double)m_nWidth) * (double)m_nHeight);
// stretch the bitmap for the best fit on the printed page
pDC->SetStretchBltMode(COLORONCOLOR);
int i=::StretchDIBits(pDC->m_hDC,
cxBorder,cyBorder,cxPage,cyPage, // destination dimensions
0,0,m_nWidth,m_nHeight, // source bitmap dimensions (use all of bitmap)
lpDIBBits, // bitmap picture data
(LPBITMAPINFO)lpDIBHdr, // bitmap header info
DIB_RGB_COLORS, // specify color table has RGB values
SRCCOPY // simple source to destination copy
);
// cleanup
::GlobalUnlock(hDIB);
::GlobalFree(hDIB);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -