分享
 
 
 

直接控制24位位图的象素(E)

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

Directly Accessing Pixels in a 24-bit Bitmap

This article was contributed by Zvika Ben-Haim.

Environment: VC5/6, Win95+

This article describes how to display 24-bit (TrueColor) bitmaps which are created during run-time by directly accessing the bitmap's bit image.

The code in this article uses the CDib class, developed by David J. Kruglinski in his book Inside Visual C++, 4th edition. The CDib class is copyrighted by Microsoft, and can be used in your programs as long as you mention their name. The CDib class is included at the end of this document.

1. Create a CDib object, and allocate memory.

This will typically be done in CView::OnInitialUpdate, or some such. It's done in the following way:

// Create a compatible DC

CDC* pDC = GetDC();

ASSERT(pDC);

CDC dcCompat;

dcCompat.CreateCompatibleDC(pDC);

ReleaseDC(pDC);

// Allocate memory for the bitmap

m_pDib = new CDib(CSize(XSIZE,YSIZE), // size of the bitmap

24); // bits per pixel

VERIFY(m_pDib->CreateSection(&dcCompat)); // allocate memory for bitmap

2. Fill the bitmap data.

You now have a memory region, allocated by Windows, in which you can write the output information. This memory region is accessed from m_pDib->m_lpImage, and contains a series of three-byte (R,G,B) pixels. As an example, you can get a nice rainbow-color image using the following code:

int x,y;

BYTE* dibits = m_pDib->m_lpImage;

for(x=0; x<XSIZE; x++)

for(y=0; y<YSIZE; y++) {

*(dibits++) = doc(x,y); // red

*(dibits++) = doc(doc.XSize()-x-1,y); // green

*(dibits++) = doc(x,doc.YSize()-y-1); // blue

}

Where we used the function doc, defined as follows (intended for bitmaps of size 512x512 pixels, more or less):

BYTE doc(int x,int y) {

return (BYTE)(sqrt(x*x+y*y)/4);

}

3. Display the bitmap.

From within CView::OnDraw, use the following to display the bitmap:

m_pDib->Draw(pDC,m_rectDraw.TopLeft(),m_rectDraw.Size());

where m_rectDraw is a logical-coordinate rectangle defining the position in which we want to place the bitmap. The bitmap is shrunk or expanded using the StretchDIBits function so that it will fit into this rectangle.

4. Delete the DIB.

Don't forget to deallocate the CDib object when you're done. The constructor deallocates all memory associate with the DIB, including the memory of the actual image.

delete m_pDib;

File: CDib.h -- CDib class header file

// cdib.h declaration for Inside Visual C++ CDib class

#ifndef _INSIDE_VISUAL_CPP_CDIB

#define _INSIDE_VISUAL_CPP_CDIB

class CDib : public CObject

{

enum Alloc {noAlloc, crtAlloc, heapAlloc};

DECLARE_SERIAL(CDib)

public:

LPVOID m_lpvColorTable;

HBITMAP m_hBitmap;

LPBYTE m_lpImage; // starting address of DIB bits

LPBITMAPINFOHEADER m_lpBMIH; // buffer containing the BITMAPINFOHEADER

private:

HGLOBAL m_hGlobal; // For external windows we need to free;

// could be allocated by this class or allocated externally

Alloc m_nBmihAlloc;

Alloc m_nImageAlloc;

DWORD m_dwSizeImage; // of bits -- not BITMAPINFOHEADER or BITMAPFILEHEADER

int m_nColorTableEntries;

HANDLE m_hFile;

HANDLE m_hMap;

LPVOID m_lpvFile;

HPALETTE m_hPalette;

public:

CDib();

CDib(CSize size, int nBitCount);// builds BITMAPINFOHEADER

~CDib();

int GetSizeImage() {return m_dwSizeImage;}

int GetSizeHeader()

{return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries;}

CSize GetDimensions();

BOOL AttachMapFile(const char* strPathname, BOOL bShare = FALSE);

BOOL CopyToMapFile(const char* strPathname);

BOOL AttachMemory(LPVOID lpvMem, BOOL bMustDelete = FALSE, HGLOBAL hGlobal = NULL);

BOOL Draw(CDC* pDC, CPoint origin, CSize size); // until we implemnt CreateDibSection

HBITMAP CreateSection(CDC* pDC = NULL);

UINT UsePalette(CDC* pDC, BOOL bBackground = FALSE);

BOOL MakePalette();

BOOL SetSystemPalette(CDC* pDC);

BOOL Compress(CDC* pDC, BOOL bCompress = TRUE); // FALSE means decompress

HBITMAP CreateBitmap(CDC* pDC);

BOOL Read(CFile* pFile);

BOOL ReadSection(CFile* pFile, CDC* pDC = NULL);

BOOL Write(CFile* pFile);

void Serialize(CArchive& ar);

void Empty();

private:

void DetachMapFile();

void ComputePaletteSize(int nBitCount);

void ComputeMetrics();

};

#endif // _INSIDE_VISUAL_CPP_CDIB

File: CDib.cpp -- CDib class definitions

// cdib.cpp

// new version for WIN32

#include "stdafx.h"

#include "cdib.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

IMPLEMENT_SERIAL(CDib, CObject, 0);

CDib::CDib()

{

m_hFile = NULL;

m_hBitmap = NULL;

m_hPalette = NULL;

m_nBmihAlloc = m_nImageAlloc = noAlloc;

Empty();

}

CDib::CDib(CSize size, int nBitCount)

{

m_hFile = NULL;

m_hBitmap = NULL;

m_hPalette = NULL;

m_nBmihAlloc = m_nImageAlloc = noAlloc;

Empty();

ComputePaletteSize(nBitCount);

m_lpBMIH = (LPBITMAPINFOHEADER) new

char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries];

m_nBmihAlloc = crtAlloc;

m_lpBMIH->biSize = sizeof(BITMAPINFOHEADER);

m_lpBMIH->biWidth = size.cx;

m_lpBMIH->biHeight = size.cy;

m_lpBMIH->biPlanes = 1;

m_lpBMIH->biBitCount = nBitCount;

m_lpBMIH->biCompression = BI_RGB;

m_lpBMIH->biSizeImage = 0;

m_lpBMIH->biXPelsPerMeter = 0;

m_lpBMIH->biYPelsPerMeter = 0;

m_lpBMIH->biClrUsed = m_nColorTableEntries;

m_lpBMIH->biClrImportant = m_nColorTableEntries;

ComputeMetrics();

memset(m_lpvColorTable, 0, sizeof(RGBQUAD) * m_nColorTableEntries);

m_lpImage = NULL; // no data yet

}

CDib::~CDib()

{

Empty();

}

CSize CDib::GetDimensions()

{

if(m_lpBMIH == NULL) return CSize(0, 0);

return CSize((int) m_lpBMIH->biWidth, (int) m_lpBMIH->biHeight);

}

BOOL CDib::AttachMapFile(const char* strPathname, BOOL bShare) // for reading

{

// if we open the same file twice, Windows treats it as 2 separate files

// doesn't work with rare BMP files where # palette entries > biClrUsed

HANDLE hFile = ::CreateFile(strPathname, GENERIC_WRITE | GENERIC_READ,

bShare ? FILE_SHARE_READ : 0,

NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

ASSERT(hFile != INVALID_HANDLE_VALUE);

DWORD dwFileSize = ::GetFileSize(hFile, NULL);

HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);

DWORD dwErr = ::GetLastError();

if(hMap == NULL) {

AfxMessageBox("Empty bitmap file");

return FALSE;

}

LPVOID lpvFile = ::MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0); // map whole file

ASSERT(lpvFile != NULL);

if(((LPBITMAPFILEHEADER) lpvFile)->bfType != 0x4d42) {

AfxMessageBox("Invalid bitmap file");

DetachMapFile();

return FALSE;

}

AttachMemory((LPBYTE) lpvFile + sizeof(BITMAPFILEHEADER));

m_lpvFile = lpvFile;

m_hFile = hFile;

m_hMap = hMap;

return TRUE;

}

BOOL CDib::CopyToMapFile(const char* strPathname)

{

// copies DIB to a new file, releases prior pointers

// if you previously used CreateSection, the HBITMAP will be NULL (and unusable)

BITMAPFILEHEADER bmfh;

bmfh.bfType = 0x4d42; // 'BM'

bmfh.bfSize = m_dwSizeImage + sizeof(BITMAPINFOHEADER) +

sizeof(RGBQUAD) * m_nColorTableEntries + sizeof(BITMAPFILEHEADER);

// meaning of bfSize open to interpretation

bmfh.bfReserved1 = bmfh.bfReserved2 = 0;

bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +

sizeof(RGBQUAD) * m_nColorTableEntries;

HANDLE hFile = ::CreateFile(strPathname, GENERIC_WRITE | GENERIC_READ, 0, NULL,

CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

ASSERT(hFile != INVALID_HANDLE_VALUE);

int nSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +

sizeof(RGBQUAD) * m_nColorTableEntries + m_dwSizeImage;

HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, nSize, NULL);

DWORD dwErr = ::GetLastError();

ASSERT(hMap != NULL);

LPVOID lpvFile = ::MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0); // map whole file

ASSERT(lpvFile != NULL);

LPBYTE lpbCurrent = (LPBYTE) lpvFile;

memcpy(lpbCurrent, &bmfh, sizeof(BITMAPFILEHEADER)); // file header

lpbCurrent += sizeof(BITMAPFILEHEADER);

LPBITMAPINFOHEADER lpBMIH = (LPBITMAPINFOHEADER) lpbCurrent;

memcpy(lpbCurrent, m_lpBMIH,

sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries); // info

lpbCurrent += sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries;

memcpy(lpbCurrent, m_lpImage, m_dwSizeImage); // bit image

DWORD dwSizeImage = m_dwSizeImage;

Empty();

m_dwSizeImage = dwSizeImage;

m_nBmihAlloc = m_nImageAlloc = noAlloc;

m_lpBMIH = lpBMIH;

m_lpImage = lpbCurrent;

m_hFile = hFile;

m_hMap = hMap;

m_lpvFile = lpvFile;

ComputePaletteSize(m_lpBMIH->biBitCount);

ComputeMetrics();

MakePalette();

return TRUE;

}

BOOL CDib::AttachMemory(LPVOID lpvMem, BOOL bMustDelete, HGLOBAL hGlobal)

{

// assumes contiguous BITMAPINFOHEADER, color table, image

// color table could be zero length

Empty();

m_hGlobal = hGlobal;

if(bMustDelete == FALSE) {

m_nBmihAlloc = noAlloc;

}

else {

m_nBmihAlloc = ((hGlobal == NULL) ? crtAlloc : heapAlloc);

}

try {

m_lpBMIH = (LPBITMAPINFOHEADER) lpvMem;

ComputeMetrics();

ComputePaletteSize(m_lpBMIH->biBitCount);

m_lpImage = (LPBYTE) m_lpvColorTable + sizeof(RGBQUAD) * m_nColorTableEntries;

MakePalette();

}

catch(CException* pe) {

AfxMessageBox("AttachMemory error");

pe->Delete();

return FALSE;

}

return TRUE;

}

UINT CDib::UsePalette(CDC* pDC, BOOL bBackground /* = FALSE */)

{

if(m_hPalette == NULL) return 0;

HDC hdc = pDC->GetSafeHdc();

::SelectPalette(hdc, m_hPalette, bBackground);

return ::RealizePalette(hdc);

}

BOOL CDib::Draw(CDC* pDC, CPoint origin, CSize size)

{

if(m_lpBMIH == NULL) return FALSE;

if(m_hPalette != NULL) {

::SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);

}

pDC->SetStretchBltMode(COLORONCOLOR);

::StretchDIBits(pDC->GetSafeHdc(), origin.x, origin.y, size.cx, size.cy,

0, 0, m_lpBMIH->biWidth, m_lpBMIH->biHeight,

m_lpImage, (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS, SRCCOPY);

return TRUE;

}

HBITMAP CDib::CreateSection(CDC* pDC /* = NULL */)

{

if(m_lpBMIH == NULL) return NULL;

if(m_lpImage != NULL) return NULL; // can only do this if image doesn't exist

m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(), (LPBITMAPINFO) m_lpBMIH,

DIB_RGB_COLORS,(LPVOID*) &m_lpImage, NULL, 0);

ASSERT(m_lpImage != NULL);

return m_hBitmap;

}

BOOL CDib::MakePalette()

{

// makes a logical palette (m_hPalette) from the DIB's color table

// this palette will be selected and realized prior to drawing the DIB

if(m_nColorTableEntries == 0) return FALSE;

if(m_hPalette != NULL) ::DeleteObject(m_hPalette);

TRACE("CDib::MakePalette -- m_nColorTableEntries = %d\n", m_nColorTableEntries);

LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2 * sizeof(WORD) +

m_nColorTableEntries * sizeof(PALETTEENTRY)];

pLogPal->palVersion = 0x300;

pLogPal->palNumEntries = m_nColorTableEntries;

LPRGBQUAD pDibQuad = (LPRGBQUAD) m_lpvColorTable;

for(int i = 0; i < m_nColorTableEntries; i++) {

pLogPal->palPalEntry[i].peRed = pDibQuad->rgbRed;

pLogPal->palPalEntry[i].peGreen = pDibQuad->rgbGreen;

pLogPal->palPalEntry[i].peBlue = pDibQuad->rgbBlue;

pLogPal->palPalEntry[i].peFlags = 0;

pDibQuad++;

}

m_hPalette = ::CreatePalette(pLogPal);

delete pLogPal;

return TRUE;

}

BOOL CDib::SetSystemPalette(CDC* pDC)

{

// if the DIB doesn't have a color table, we can use the system's halftone palette

if(m_nColorTableEntries != 0) return FALSE;

m_hPalette = ::CreateHalftonePalette(pDC->GetSafeHdc());

return TRUE;

}

HBITMAP CDib::CreateBitmap(CDC* pDC)

{

if (m_dwSizeImage == 0) return NULL;

HBITMAP hBitmap = ::CreateDIBitmap(pDC->GetSafeHdc(), m_lpBMIH,

CBM_INIT, m_lpImage, (LPBITMAPINFO) m_lpBMIH, DIB_RGB_COLORS);

ASSERT(hBitmap != NULL);

return hBitmap;

}

BOOL CDib::Compress(CDC* pDC, BOOL bCompress /* = TRUE */)

{

// 1. makes GDI bitmap from existing DIB

// 2. makes a new DIB from GDI bitmap with compression

// 3. cleans up the original DIB

// 4. puts the new DIB in the object

if((m_lpBMIH->biBitCount != 4) && (m_lpBMIH->biBitCount != 8)) return FALSE;

// compression supported only for 4 bpp and 8 bpp DIBs

if(m_hBitmap) return FALSE; // can't compress a DIB Section!

TRACE("Compress: original palette size = %d\n", m_nColorTableEntries);

HDC hdc = pDC->GetSafeHdc();

HPALETTE hOldPalette = ::SelectPalette(hdc, m_hPalette, FALSE);

HBITMAP hBitmap; // temporary

if((hBitmap = CreateBitmap(pDC)) == NULL) return FALSE;

int nSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries;

LPBITMAPINFOHEADER lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];

memcpy(lpBMIH, m_lpBMIH, nSize); // new header

if(bCompress) {

switch (lpBMIH->biBitCount) {

case 4:

lpBMIH->biCompression = BI_RLE4;

break;

case 8:

lpBMIH->biCompression = BI_RLE8;

break;

default:

ASSERT(FALSE);

}

// calls GetDIBits with null data pointer to get size of compressed DIB

if(!::GetDIBits(pDC->GetSafeHdc(), hBitmap, 0, (UINT) lpBMIH->biHeight,

NULL, (LPBITMAPINFO) lpBMIH, DIB_RGB_COLORS)) {

AfxMessageBox("Unable to compress this DIB");

// probably a problem with the color table

::DeleteObject(hBitmap);

delete [] lpBMIH;

::SelectPalette(hdc, hOldPalette, FALSE);

return FALSE;

}

if (lpBMIH->biSizeImage == 0) {

AfxMessageBox("Driver can't do compression");

::DeleteObject(hBitmap);

delete [] lpBMIH;

::SelectPalette(hdc, hOldPalette, FALSE);

return FALSE;

}

else {

m_dwSizeImage = lpBMIH->biSizeImage;

}

}

else {

lpBMIH->biCompression = BI_RGB; // decompress

// figure the image size from the bitmap width and height

DWORD dwBytes = ((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) / 32;

if(((DWORD) lpBMIH->biWidth * lpBMIH->biBitCount) % 32) {

dwBytes++;

}

dwBytes *= 4;

m_dwSizeImage = dwBytes * lpBMIH->biHeight; // no compression

lpBMIH->biSizeImage = m_dwSizeImage;

}

// second GetDIBits call to make DIB

LPBYTE lpImage = (LPBYTE) new char[m_dwSizeImage];

VERIFY(::GetDIBits(pDC->GetSafeHdc(), hBitmap, 0, (UINT) lpBMIH->biHeight,

lpImage, (LPBITMAPINFO) lpBMIH, DIB_RGB_COLORS));

TRACE("dib successfully created - height = %d\n", lpBMIH->biHeight);

::DeleteObject(hBitmap);

Empty();

m_nBmihAlloc = m_nImageAlloc = crtAlloc;

m_lpBMIH = lpBMIH;

m_lpImage = lpImage;

ComputeMetrics();

ComputePaletteSize(m_lpBMIH->biBitCount);

MakePalette();

::SelectPalette(hdc, hOldPalette, FALSE);

TRACE("Compress: new palette size = %d\n", m_nColorTableEntries);

return TRUE;

}

BOOL CDib::Read(CFile* pFile)

{

// 1. read file header to get size of info hdr + color table

// 2. read info hdr (to get image size) and color table

// 3. read image

// can't use bfSize in file header

Empty();

int nCount, nSize;

BITMAPFILEHEADER bmfh;

try {

nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));

if(nCount != sizeof(BITMAPFILEHEADER)) {

throw new CException;

}

if(bmfh.bfType != 0x4d42) {

throw new CException;

}

nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);

m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];

m_nBmihAlloc = m_nImageAlloc = crtAlloc;

nCount = pFile->Read(m_lpBMIH, nSize); // info hdr & color table

ComputeMetrics();

ComputePaletteSize(m_lpBMIH->biBitCount);

MakePalette();

m_lpImage = (LPBYTE) new char[m_dwSizeImage];

nCount = pFile->Read(m_lpImage, m_dwSizeImage); // image only

}

catch(CException* pe) {

AfxMessageBox("Read error");

pe->Delete();

return FALSE;

}

return TRUE;

}

BOOL CDib::ReadSection(CFile* pFile, CDC* pDC /* = NULL */)

{

// new function reads BMP from disk and creates a DIB section

// allows modification of bitmaps from disk

// 1. read file header to get size of info hdr + color table

// 2. read info hdr (to get image size) and color table

// 3. create DIB section based on header parms

// 4. read image into memory that CreateDibSection allocates

Empty();

int nCount, nSize;

BITMAPFILEHEADER bmfh;

try {

nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));

if(nCount != sizeof(BITMAPFILEHEADER)) {

throw new CException;

}

if(bmfh.bfType != 0x4d42) {

throw new CException;

}

nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);

m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize];

m_nBmihAlloc = crtAlloc;

m_nImageAlloc = noAlloc;

nCount = pFile->Read(m_lpBMIH, nSize); // info hdr & color table

if(m_lpBMIH->biCompression != BI_RGB) {

throw new CException;

}

ComputeMetrics();

ComputePaletteSize(m_lpBMIH->biBitCount);

MakePalette();

UsePalette(pDC);

m_hBitmap = ::CreateDIBSection(pDC->GetSafeHdc(), (LPBITMAPINFO) m_lpBMIH,

DIB_RGB_COLORS,(LPVOID*) &m_lpImage, NULL, 0);

ASSERT(m_lpImage != NULL);

nCount = pFile->Read(m_lpImage, m_dwSizeImage); // image only

}

catch(CException* pe) {

AfxMessageBox("ReadSection error");

pe->Delete();

return FALSE;

}

return TRUE;

}

BOOL CDib::Write(CFile* pFile)

{

BITMAPFILEHEADER bmfh;

bmfh.bfType = 0x4d42; // 'BM'

int nSizeHdr = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries;

bmfh.bfSize = 0;

//bmfh.bfSize = sizeof(BITMAPFILEHEADER) + nSizeHdr + m_dwSizeImage;

// meaning of bfSize open to interpretation (bytes, words, dwords?) -- we won't use it

bmfh.bfReserved1 = bmfh.bfReserved2 = 0;

bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +

sizeof(RGBQUAD) * m_nColorTableEntries;

try {

pFile->Write((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER));

pFile->Write((LPVOID) m_lpBMIH, nSizeHdr);

pFile->Write((LPVOID) m_lpImage, m_dwSizeImage);

}

catch(CException* pe) {

pe->Delete();

AfxMessageBox("write error");

return FALSE;

}

return TRUE;

}

void CDib::Serialize(CArchive& ar)

{

DWORD dwPos;

dwPos = ar.GetFile()->GetPosition();

TRACE("CDib::Serialize -- pos = %d\n", dwPos);

ar.Flush();

dwPos = ar.GetFile()->GetPosition();

TRACE("CDib::Serialize -- pos = %d\n", dwPos);

if(ar.IsStoring()) {

Write(ar.GetFile());

}

else {

Read(ar.GetFile());

}

}

// helper functions

void CDib::ComputePaletteSize(int nBitCount)

{

if((m_lpBMIH == NULL) || (m_lpBMIH->biClrUsed == 0)) {

switch(nBitCount) {

case 1:

m_nColorTableEntries = 2;

break;

case 4:

m_nColorTableEntries = 16;

break;

case 8:

m_nColorTableEntries = 256;

break;

case 16:

case 24:

case 32:

m_nColorTableEntries = 0;

break;

default:

ASSERT(FALSE);

}

}

else {

m_nColorTableEntries = m_lpBMIH->biClrUsed;

}

ASSERT((m_nColorTableEntries >= 0) && (m_nColorTableEntries <= 256));

}

void CDib::ComputeMetrics()

{

if(m_lpBMIH->biSize != sizeof(BITMAPINFOHEADER)) {

TRACE("Not a valid Windows bitmap -- probably an OS/2 bitmap\n");

throw new CException;

}

m_dwSizeImage = m_lpBMIH->biSizeImage;

if(m_dwSizeImage == 0) {

DWORD dwBytes = ((DWORD) m_lpBMIH->biWidth * m_lpBMIH->biBitCount) / 32;

if(((DWORD) m_lpBMIH->biWidth * m_lpBMIH->biBitCount) % 32) {

dwBytes++;

}

dwBytes *= 4;

m_dwSizeImage = dwBytes * m_lpBMIH->biHeight; // no compression

}

m_lpvColorTable = (LPBYTE) m_lpBMIH + sizeof(BITMAPINFOHEADER);

}

void CDib::Empty()

{

// this is supposed to clean up whatever is in the DIB

DetachMapFile();

if(m_nBmihAlloc == crtAlloc) {

delete [] m_lpBMIH;

}

else if(m_nBmihAlloc == heapAlloc) {

::GlobalUnlock(m_hGlobal);

::GlobalFree(m_hGlobal);

}

if(m_nImageAlloc == crtAlloc) delete [] m_lpImage;

if(m_hPalette != NULL) ::DeleteObject(m_hPalette);

if(m_hBitmap != NULL) ::DeleteObject(m_hBitmap);

m_nBmihAlloc = m_nImageAlloc = noAlloc;

m_hGlobal = NULL;

m_lpBMIH = NULL;

m_lpImage = NULL;

m_lpvColorTable = NULL;

m_nColorTableEntries = 0;

m_dwSizeImage = 0;

m_lpvFile = NULL;

m_hMap = NULL;

m_hFile = NULL;

m_hBitmap = NULL;

m_hPalette = NULL;

}

void CDib::DetachMapFile()

{

if(m_hFile == NULL) return;

::UnmapViewOfFile(m_lpvFile);

::CloseHandle(m_hMap);

::CloseHandle(m_hFile);

m_hFile = NULL;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有