11.04.2014 Views

Advanced MFC Programming

Advanced MFC Programming

Advanced MFC Programming

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Chapter 11. Sample: Simple Paint<br />

We need to calculate the values of the following members for the new bitmap information header:<br />

biWidth, biHeight and biImageSize. Here the dimension of the new image (biWidth, biHeight) can be<br />

decided from the size of the tracker, and the image size can be calculated from member biBitCout along<br />

with the new image dimension. In the sample, function CGDIDoc::CreateCopyCutDIB()creates a DIB that<br />

is exactly the same with the image contained in the selected area. The following portion of this function<br />

shows how the buffers are allocated and how the bitmap information header is created:<br />

……<br />

……<br />

dwDIBSize=<br />

(<br />

sizeof(BITMAPINFOHEADER)+<br />

GetColorTableSize(bi.biBitCount)*sizeof(RGBQUAD)+<br />

WIDTHBYTES(rect.Width()*bi.biBitCount)*rect.Height()<br />

);<br />

hDIB=::GlobalAlloc(GHND | GMEM_SHARE, dwDIBSize);<br />

ASSERT(hDIB != NULL);<br />

lpBi=(LPBITMAPINFO)::GlobalLock(hDIB);<br />

ASSERT(lpBi != NULL);<br />

lpBi->bmiHeader=bi;<br />

lpBi->bmiHeader.biWidth=rect.Width();<br />

lpBi->bmiHeader.biHeight=rect.Height();<br />

lpBi->bmiHeader.biSizeImage=WIDTHBYTES<br />

(<br />

bi.biBitCount*rect.Width()<br />

)*rect.Height();<br />

The buffer size of new DIB data is calculated and stored in variable dwDIBSize. Here rect stores the<br />

normalized dimension of the current tracker. The current image’s bitmap information header is stored in<br />

variable bi. After copying it into the new buffers, we change members biWidth, biHeight and<br />

biImageSize to new values.<br />

Then, we need to copy the current color table to the newly allocated buffers. Although we could<br />

retrieve the palette from the original DIB data, it may not be up-to-date because the user may change any<br />

entry of the palette by double clicking on the color bar. In the sample, function<br />

CPalette::GetPaletteEntries(…) is called to retrieve the current palette, and is used to create the new<br />

image:<br />

……<br />

……<br />

nPalSize=GetColorTableSize(lpBi->bmiHeader.biBitCount);<br />

lpPalEntry=(LPPALETTEENTRY)new BYTE[nPalSize*sizeof(PALETTEENTRY)];<br />

m_palDraw.GetPaletteEntries(0, nPalSize, lpPalEntry);<br />

for(i=0; ibmiColors[i].rgbRed=lpPalEntry[i].peRed;<br />

lpBi->bmiColors[i].rgbGreen=lpPalEntry[i].peGreen;<br />

lpBi->bmiColors[i].rgbBlue=lpPalEntry[i].peBlue;<br />

lpBi->bmiColors[i].rgbReserved=NULL;<br />

}<br />

delete []lpPalEntry;<br />

Because there is no restriction on the dimension of the tracker, the user can actually select an area that<br />

some portion of it is outside the current image. In order to copy only the valid image, we need to adjust the<br />

rectangle before doing the copy. In the sample, only the intersection between the tracker and the image is<br />

copied, and the rest part of the target image will be filled with the current background color. In function<br />

CGDIDoc::CreateCopyCutDIB(…), the actual rectangle that will be used to obtain the image bit values from<br />

the source bitmap is stored in variable rectSrc, and sizeTgtOffset is used to specify the position where<br />

the image will be copied to the target image. This variable is necessary because the tracker’s upper-left<br />

corner may resides outside the image. The whole image is copied using a loop. Within each loop, one raster<br />

line is copied to the target bitmap. In the function, two pointers are used to implement this copy: before<br />

copying the actual pixels, lpRowSrc is pointed to the source image buffers and lpRowTgt is pointed to the<br />

target image buffers. Their addresses are calculated by adding the bitmap information header size and the<br />

362

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!