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 />

Implementing Subclass<br />

Class CBitmapButton gives us another member function that can be used to associate bitmaps with an<br />

owner-draw button: CBitmapButton::LoadBitmaps(…). This function has two versions, the first version<br />

allows us to load bitmaps with string IDs, the second version allows us to load bitmaps with integer IDs.<br />

To use this function, we must first implement subclass for the owner-draw button. “Subclass” is a very<br />

powerful technique in Windows programming. It allows us to write a procedure, attach it to a window,<br />

and use it to intercept messages sent to this window then process it. By doing this, we are able to customize<br />

the window’s behavior within the procedure.<br />

Subclass is supported by class CWnd, so theoretically all windows (including client window, dialog box,<br />

dialog common controls...) can be “subclassed”. There are two functions to implement subclass, one is<br />

CWnd::SubclassWindow(…), which allows us to customize the normal behavior of a window. Here we will<br />

use the other one: CWnd::SubclassDlgItem(…), which is specially designed to implement subclass for the<br />

common controls contained in a dialog box.<br />

In <strong>MFC</strong>, implementing subclass is very simple. We don’t need to write a special procedure to handle<br />

the intercepted messages. All we need to do is designing a class as usual, adding message handlers for the<br />

messages we want to process, and implementing the message handlers. Then we can declare a variable<br />

using the newly designed class, and call function CWnd::SubclassDlgItem(…) to implement subclass.<br />

Function CWnd::SubclassDlgItem(…) has two parameters:<br />

BOOL CWnd::SubclassDlgItem(UINT nID, CWnd *pParent);<br />

Parameter nID indicates which control we are dealing with, and pParent is the pointer to the control’s<br />

parent window.<br />

Class CBitmapButton uses subclass to change the default behavior of a button. If we use automatic<br />

method to load the bitmaps, the subclass procedure is transparent to the programmer. However, if we want<br />

to load the bitmaps by ourselves, we must implement subclass first.<br />

Bitmap Button<br />

Sample 4.3\Btn demonstrates how to associate bitmaps with an owner draw button by calling function<br />

CBitmapButton::LoadBitmaps(…). It is based on sample 4.2\Btn. There is nothing new in this sample,<br />

except that button IDC_PLAY is implemented differently.<br />

In the previous samples, variable CBtnDlg::m_btnPlay is declared as a CBitmapButton type variable.<br />

In the new sample, instead of using automatic method to load the bitmaps, we first implement the subclass<br />

then load the bitmaps manually in function CBitmapButton::LoadBitmaps(…):<br />

……<br />

……<br />

BOOL CBtnDlg::OnInitDialog()<br />

{<br />

CDialog::OnInitDialog();<br />

}<br />

m_btnPlay.SubclassDlgItem(IDC_PLAY, this);<br />

m_btnPlay.LoadBitmaps<br />

(<br />

“PLAYU”,<br />

“PLAYD”,<br />

NULL,<br />

NULL<br />

);<br />

m_btnPlay.SizeToContent();<br />

return TRUE;<br />

Here, function CBitmapButton::AutoLoad(…) is replaced by three new functions. The first function<br />

added is CWnd::SubclassDlgItem(…). The second function is CBitmapButton::LoadBitmaps(…). This<br />

function has four parameters, which are the bitmap IDs corresponding to button’s “Up”, “Down”,<br />

“Focused” and “Disabled” states respectively. They could be either string IDs or integer IDs. The last<br />

function is CBitmap::SizeToContent(), which allows us to set bitmap button’s size to the size of the<br />

associated bitmaps. If we don’t call this function, the bitmaps may not fit well into the button.<br />

74

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

Saved successfully!

Ooh no, something went wrong!