用于将指定DC保存为BMP位图,适用于暴露自身表面的动态程序情况捕捉。
// hdctobmpX.h : ChdctobmpX 的声明
#pragma once #include "resource.h" // 主符号
// IhdctobmpX [ object, uuid("7C3141C9-A96E-4775-93C7-FEE42C738B94"), dual, helpstring("IhdctobmpX 接口"), pointer_default(unique) ] __interface IhdctobmpX : IDispatch { [propput, id(1), helpstring("属性 HWND")] HRESULT HWND([in] ULONG newVal); [propput, id(2), helpstring("属性 savepath")] HRESULT savepath([in] BSTR newVal); [id(3), helpstring("方法savetobmp")] HRESULT savetobmp(void); [propput, id(4), helpstring("属性 bwidth")] HRESULT bwidth([in] DOUBLE newVal); [propput, id(5), helpstring("属性 bheight")] HRESULT bheight([in] DOUBLE newVal); [id(6), helpstring("方法savetobmp2")] HRESULT savetobmp2(void); };
// ChdctobmpX
[ coclass, threading("apartment"), vi_progid("HDCtoBMP.hdctobmpX"), progid("HDCtoBMP.hdctobmpX.1"), version(1.0), uuid("F4A2F19D-AF6B-434A-A104-C4AA013E7B37"), helpstring("hdctobmpX Class") ]
class ATL_NO_VTABLE ChdctobmpX : public IhdctobmpX {
protected:
//保存路径 _bstr_t m_path; //传入句柄 HWND m_hwnd;
//位图宽 DOUBLE m_Width; //位图高 DOUBLE m_Height;
public: //构造 ChdctobmpX(){}
DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct(){return S_OK;} //系构 void FinalRelease(){}
public:
//属性设置 STDMETHOD(put_HWND)(ULONG newVal); STDMETHOD(put_savepath)(BSTR newVal);
//拷贝位图 STDMETHOD(savetobmp)(void);
STDMETHOD(put_bwidth)(DOUBLE newVal); STDMETHOD(put_bheight)(DOUBLE newVal);
private: PBITMAPINFO ChdctobmpX::CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp); void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi,HBITMAP hBMP, HDC hDC); void Error( TCHAR * pText );
public: STDMETHOD(savetobmp2)(void); };
---------------------------------------------------------------------------------------------------------
// hdctobmpX.cpp : ChdctobmpX 的实现
#include "stdafx.h" #include "hdctobmpX.h"
// ChdctobmpX
//存BMP STDMETHODIMP ChdctobmpX::savetobmp(void) { // 设置图象保存位置加上.BMP扩展名 TCHAR m_ShortName[MAX_PATH];
wsprintf( m_ShortName, TEXT("%s.bmp\0"),(LPCTSTR)m_path);
//获取输入当前DC HDC hdc=GetDC(this->m_hwnd); //由当前DC转化创建一完备DC HDC hdccmp = CreateCompatibleDC(hdc); //由当前DC创建位图DC HBITMAP hbmp = CreateCompatibleBitmap(hdc,m_Width, m_Height); if (hbmp == 0) {return 0;}
//完备DC选择位图DC if(!SelectObject(hdccmp, hbmp)){return 0;}
//当前DC拷贝到完备DC BitBlt(hdccmp,0,0,m_Width, m_Height,hdc,0,0,SRCCOPY);
PBITMAPINFO pbi=CreateBitmapInfoStruct(this->m_hwnd ,hbmp);
CreateBMPFile(this->m_hwnd, m_ShortName,pbi,hbmp,hdccmp) ;
return S_OK; }
STDMETHODIMP ChdctobmpX::savetobmp2(void) { // 设置图象保存位置加上.BMP扩展名 TCHAR m_ShortName[MAX_PATH];
wsprintf( m_ShortName, TEXT("%s.bmp\0"),(LPCTSTR)m_path);
//获取输入当前DC HDC hdc=GetWindowDC(this->m_hwnd); //由当前DC转化创建一完备DC HDC hdccmp = CreateCompatibleDC(hdc); //由当前DC创建位图DC HBITMAP hbmp = CreateCompatibleBitmap(hdc,m_Width, m_Height); if (hbmp == 0) {return 0;}
//完备DC选择位图DC if(!SelectObject(hdccmp, hbmp)){return 0;}
//当前DC拷贝到完备DC BitBlt(hdccmp,0,0,m_Width, m_Height,hdc,0,0,SRCCOPY);
PBITMAPINFO pbi=CreateBitmapInfoStruct(this->m_hwnd ,hbmp);
CreateBMPFile(this->m_hwnd, m_ShortName,pbi,hbmp,hdccmp) ;
return S_OK;
}
/////////////////////////////属性/////////////////////////// STDMETHODIMP ChdctobmpX::put_bwidth(DOUBLE newVal) { // TODO: 在此添加实现代码 this->m_Width=newVal; return S_OK; }
STDMETHODIMP ChdctobmpX::put_bheight(DOUBLE newVal) { // TODO: 在此添加实现代码 this->m_Height=newVal; return S_OK; }
STDMETHODIMP ChdctobmpX::put_savepath(BSTR newVal) { // TODO: 在此添加实现代码 this->m_path= newVal; SysFreeString(newVal); return S_OK; } STDMETHODIMP ChdctobmpX::put_HWND(ULONG newVal) { this->m_hwnd=(HWND)newVal; return S_OK; }
////////////////////////私有成员//////////////////////// //获取位图信息 PBITMAPINFO ChdctobmpX::CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp) { BITMAP bmp; PBITMAPINFO pbmi; WORD cClrBits;
// Retrieve the bitmap color format, width, and height. if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp)) Error("GetObject");
// Convert the color format to a count of bits. cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); if (cClrBits == 1) cClrBits = 1; else if (cClrBits <= 4) cClrBits = 4; else if (cClrBits <= 8) cClrBits = 8; else if (cClrBits <= 16) cClrBits = 16; else if (cClrBits <= 24) cClrBits = 24; else cClrBits = 32;
// Allocate memory for the BITMAPINFO structure. (This structure // contains a BITMAPINFOHEADER structure and an array of RGBQUAD // data structures.)
if (cClrBits != 24) pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1<< cClrBits));
// There is no RGBQUAD array for the 24-bit-per-pixel format.
else pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER));
// Initialize the fields in the BITMAPINFO structure.
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = bmp.bmWidth; pbmi->bmiHeader.biHeight = bmp.bmHeight; pbmi->bmiHeader.biPlanes = bmp.bmPlanes; pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel; if (cClrBits < 24) pbmi->bmiHeader.biClrUsed = (1<<cClrBits);
// If the bitmap is not compressed, set the BI_RGB flag. pbmi->bmiHeader.biCompression = BI_RGB;
// Compute the number of bytes in the array of color // indices and store the result in biSizeImage. // For Windows NT, the width must be DWORD aligned unless // the bitmap is RLE compressed. This example shows this. // For Windows 95/98/Me, the width must be WORD aligned unless the // bitmap is RLE compressed. pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8 * pbmi->bmiHeader.biHeight; // Set biClrImportant to 0, indicating that all of the // device colors are important. pbmi->bmiHeader.biClrImportant = 0; return pbmi; }
//写BMP文件 void ChdctobmpX::CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi,HBITMAP hBMP, HDC hDC) { HANDLE hf; // file handle BITMAPFILEHEADER hdr; // bitmap file-header PBITMAPINFOHEADER pbih; // bitmap info-header LPBYTE lpBits; // memory pointer DWORD dwTotal; // total count of bytes DWORD cb; // incremental count of bytes BYTE *hp; // byte pointer DWORD dwTmp;
pbih = (PBITMAPINFOHEADER) pbi; lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
if (!lpBits) Error("GlobalAlloc");
// Retrieve the color table (RGBQUAD array) and the bits // (array of palette indices) from the DIB. if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi, DIB_RGB_COLORS)) { Error("GetDIBits"); }
// Create the .BMP file. hf = CreateFile(pszFile, GENERIC_READ | GENERIC_WRITE, (DWORD) 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); if (hf == INVALID_HANDLE_VALUE) Error("CreateFile"); hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M" // Compute the size of the entire file. hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof(RGBQUAD) + pbih->biSizeImage); hdr.bfReserved1 = 0; hdr.bfReserved2 = 0;
// Compute the offset to the array of color indices. hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof (RGBQUAD);
// Copy the BITMAPFILEHEADER into the .BMP file. if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), (LPDWORD) &dwTmp, NULL)) { Error("WriteFile"); }
// Copy the BITMAPINFOHEADER and RGBQUAD array into the file. if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) + pbih->biClrUsed * sizeof (RGBQUAD), (LPDWORD) &dwTmp, ( NULL))) { Error("WriteFile"); }
// Copy the array of color indices into the .BMP file. dwTotal = cb = pbih->biSizeImage; hp = lpBits; if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) Error("WriteFile");
// Close the .BMP file. if (!CloseHandle(hf)) Error("CloseHandle");
// Free memory. GlobalFree((HGLOBAL)lpBits); }
//错误显示 void ChdctobmpX::Error( TCHAR * pText ) { ::MessageBox( NULL, pText, TEXT("Error!"), MB_OK | MB_TASKMODAL | MB_SETFOREGROUND ); } 
|