⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wzdbtmap.cpp

📁 E:Visual_C__MFC扩展编程实例 例18 动态地抓取应用程序的屏幕图像并将其打印。 上一个实例打印的是文档的报表
💻 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 + -