11.04.2014 Views

Advanced MFC Programming

Advanced MFC Programming

Advanced MFC Programming

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Chapter 4. Button<br />

using bit-wise AND operation, the foreground area of the target device will become black. This means on<br />

the target device, every pixel in the foreground area is zero now. Since we use bit-wise XOR mode to<br />

output normal image in the last step, and XORing anything with zero will not change the source, the<br />

foreground area on the target device will finally contain the pattern of the source image. For mask area, the<br />

second ANDing operation doesn’t make any change to it because ANDing a pixel with white color (all 1s)<br />

doesn’t change that pixel. So the overall operations on the mask region is equivalent to two consecutive<br />

XOR operations, which will resume all the pixels in this region to their original colors.<br />

However there is still a slight problem here: if we draw the source and mask bitmaps directly to the<br />

target device using the method mentioned above, we will see a quick flicker on the mask area of the target<br />

device. Although it lasts only for a very short period, it is an undesirable effect. To overcome this, we can<br />

prepare a bitmap in the memory, copy the target image pattern to this bitmap, do the transparent painting on<br />

the memory bitmap, and copy the final result back to the target. Since the background area of the memory<br />

bitmap has the same pattern with the background area of the target device, this final copy will not cause<br />

any flicker.<br />

To customize the drawing behavior of bitmap button, we need to override function<br />

CBitmapButton::OnDrawItem(…). For an owner-draw button, this function will be called when a button<br />

needs to be updated. Actually, menu and combo box also use similar functions. We can create an owner<br />

draw menu or combo box by overriding the member functions with the same name. For these functions,<br />

their parameters are all pointers to DRAWITEMSTRUCT type object. This structure stores information such as<br />

button’s current state (i.e. focused, disabled), the device context that can be used to implement drawing,<br />

and the rectangle indicating where we can output the image pattern.<br />

New Class<br />

Sample 4.5\Btn is based on sample 4.4\Btn, it demonstrates how to create bitmap buttons with<br />

transparent background. In this sample, a new class MCBitmapButton is derived from CBitmapButton.<br />

Besides the default properties inherited from base class, the following new features are added to this class:<br />

1) The new class handles transparent background drawing automatically. Programmer can prepare a<br />

black-and-white mask bitmap and associate it with the bitmap button together with other required<br />

bitmaps. The drawing will be taken care in the member function of the class. Programmer doesn’t need<br />

to add extra code.<br />

2) The mask bitmap can be loaded along with other images by calling either AutoLoad(…) or<br />

LoadBitmaps(…).<br />

2) Function AutoLoad(…) is overridden to load the mask image automatically. In this case, the mask<br />

bitmap must have a string ID that is created by suffixing an ‘M’ character to button’s caption text. For<br />

example, if we want to create mask bitmap for a button whose caption text is “PLAY”, the ID of the<br />

mask bitmap must be “PLAYM”. If we load the mask bitmap using automatic method, there is no<br />

difference between using the new class and CBitmapButton.<br />

2) Mask bitmap could also be loaded by calling function LoadBitmaps(…). The overridden function has<br />

five parameters, the last of which is the ID of the mask bitmap.<br />

2) If the mask bitmap is not present, the bitmap will be output directly to the target device using the<br />

default implementation.<br />

In the sample, a mask bitmap “PLAYM” is added to the application. It will be used to draw button<br />

IDC_PLAY with transparent background.<br />

The new class derived from CBitmapButton is MCBitmapButton. In this class, a new CBitmap type<br />

variable m_bitmapMask is added to load the mask bitmap, also, functions AutoLoad(…) and LoadBitmaps(…)<br />

are overridden. The following code fragment shows this new class:<br />

class MCBitmapButton : public CBitmapButton<br />

{<br />

public:<br />

MCBitmapButton();<br />

BOOL LoadBitmaps<br />

(<br />

LPCTSTR lpszBitmapResource,<br />

LPCTSTR lpszBitmapResourceSel=NULL,<br />

79

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

Saved successfully!

Ooh no, something went wrong!