高手进来看一下啦

valentine_sc 2002-05-15 01:12:42
我想把当前屏幕上显示的东西保存成BMP图,请问该怎么做???
...全文
24 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
cadinfo 2002-05-17
  • 打赏
  • 举报
回复
这个问题我来回答,使用屏幕拷贝的方法,
再根据位图格式生成位图文件,以下给出源代码:

//=>
#ifndef PRINTBITMAP_H
#define PRINTBITMAP_H

class CPrintBitmap : public CBitmap
{
public:
DECLARE_DYNAMIC(CPrintBitmap)

// Constructors
CPrintBitmap();

void Capture(CRect &rect);
CPalette *GetPalette(){return m_pPalette;};
HANDLE CreateDIB(int *pbmData=NULL);
void Print(CDC *pDC);

// Implementation
public:
virtual ~CPrintBitmap();

// Attributes
int m_nWidth;
int m_nHeight;
// Operations

private:
CPalette *m_pPalette;
};
#endif


//=>
// PrintBtmap.cpp : implementation of the CPrintBitmap class
//

#include "stdafx.h"
#include "PrintBtmap.h"

/////////////////////////////////////////////////////////////////////////////
// CPrintBitmap

IMPLEMENT_DYNAMIC(CPrintBitmap, CBitmap)


CPrintBitmap::CPrintBitmap()
{
m_pPalette=NULL;
}

CPrintBitmap::~CPrintBitmap()
{
if (m_pPalette)
{
delete m_pPalette;
}
}

void CPrintBitmap::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 CPrintBitmap::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 CPrintBitmap::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;
}

给出的.h和.cpp仅仅用于在内存生成BMP(DIBSection),而后根据内容就可以
写文件存盘了
nktylm 2002-05-17
  • 打赏
  • 举报
回复
点机键盘上的Print键即可抓取当前屏幕,然后打开一个绘图软件,新建一个文件然后ctrl+v拷贝一下即可.
storein 2002-05-17
  • 打赏
  • 举报
回复
有几个截屏的函数
我不记的了
你在文档中心找一下
bigdoors 2002-05-17
  • 打赏
  • 举报
回复
接分
KevinListening 2002-05-15
  • 打赏
  • 举报
回复
屏幕保存!

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧