Click here to Skip to main content
15,036,145 members
Articles / Desktop Programming / MFC
Posted 7 Jun 2000


228 bookmarked

Windows Message Handling - Part 4

Rate me:
Please Sign up or sign in to vote.
4.91/5 (41 votes)
25 Apr 2003
Reflected Messages, MFC and SDK Subclassing


Subclassing is a technique that allows an application to intercept and process messages sent or posted to a particular window before the window has a chance to process them. This is typically done by replacing the Window Procedure for a window with application-defined window procedure. I will divide this article into three:

  1. Subclassing in SDK programs
  2. Subclassing in MFC programs
  3. Reflected messages

Why Subclass?

Sometimes, you want to take the functionality of a control and modify it slightly. One example is replacing the menu in an edit control, Another is adding a context menu when you press on a button. One of the most common questions I encounter is "How do I screen out characters from an edit control?". I will show the solution to this from an MFC approach and from an SDK approach, while I try to explain Subclassing.

The need for subclassing comes from the fact that the code for the Windows controls is within Windows, meaning you cannot edit the code. Although you cannot edit the code of the control itself, you intercept the messages sent to it, and handle them yourself. You do so by subclassing the control. Subclassing involves replacing the Message Handlers of the control, and passing any unprocessed message to the controls' Message Handler.

SDK Subclassing

Although the Message Procedure for the control is located within windows, you can retrieve a pointer to it by using the GetWindowLong function with the GWL_WNDPROC identifier. Likewise, you can call SetWindowLong and specify a new Window Procedure for the control. This process is called Subclassing, and allows you to hook into a window/control and intercept any message it gets. Subclassing is the Windows term for replacing the Window Procedure of a window with a different Window Procedure and calling the old Window Procedure for default (superclass) functionality. Remember DefWindowProc()? instead of calling DefWindowProc for default Message Handling you use the old Window Procedure as the default Message Handler.

Implementing SDK Subclassing

So, let's try to solve the classic question "How do I screen out characters from an edit control?", or "How do I create a letter-only edit control?"

First Let's Analyze How an Edit Control Works

An edit control is a window. It's window procedure lies within windows. Among other things, whenever it gets a WM_CHAR message, it adds the character to the text it contains. Now that we know that, we can simply subclass the edit control, and intercept the WM_CHAR messages. Whenever the WM_CHAR message is a letter or a key like space bar or backspace, we'll pass the message to the edit control. If it isn't one of the above, we'll just "Swallow" the message, blocking it from reaching the Edit Control.

The first step to subclassing is to add a global/static WNDPROC variable that will store the address of the edit control's Window Procedure.

WNDPROC g_OldEdit;

The second step is to create a new Window Procedure for the edit control:

LRESULT CALLBACK NewEditProc (HWND hwnd, UINT message, 
                             WPARAM wParam, LPARAM lParam)
	TCHAR chCharCode;
	switch (message)
	case WM_CHAR:
		chCharCode = (TCHAR) wParam;
		if(chCharCode > 0x20 && !IsCharAlpha(chCharCode))
			return 0;
	return CallWindowProc (g_OldEdit, hwnd, message, wParam, lParam);

The IsCharAlpha function determines whether a character is an alphabetic character. This determination is based on the semantics of the language selected by the user during setup or by using Control Panel.

More interesting is the CallWindowProc function. The CallWindowProc function passes message information to the specified Window Procedure. A call to CallWindowProc will allow you to call the old Window Procedure with any message you receive, thus providing default message handling

The third step is to replace the Window Procedure for the edit control, and to store the old one in g_OldEdit. For example, if you want to subclass an edit control that resides in a dialog (hDlg) and has the ID of IDC_EDIT1, you would use the following code:

hwnd hWndEdit = GetDlgItem(hDlg, IDC_EDIT1);
//Replace the Window Procedure and Store the Old Window Procedure
g_OldEdit = (WNDPROC)SetWindowLong(hWndEdit, GWL_WNDPROC, (LONG)NewEditProc);

The control is now subclassed. Any message to the edit control will first go through the NewEditProc Window Procedure, which will decide if the message should go to the edit control's Window Procedure.

MFC Subclassing

Subclassing in both MFC and SDK programs is done by replacing the message handlers of a control. It is rather easy to subclass in a MFC program. First, you inherit your class from a class that encapsulates the functionality of a the control. In ClassWizard, click on "Add Class", then "New". For the base class, choose the MFC Control class you are deriving from, in our case, CEdit.

Image 1

Using MFC relieves you from having to call the old Message Handlers, since MFC will take care of it for you.
The second step is to add Message Handlers to your new class. If you handle a message and you want the control's message handler to get a shot at it, you should call the base class member function that corresponds with the message. This is the subclassed WM_CHAR handler:

void CLetterEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
	if(nChar <= 0x20 || IsCharAlpha((TCHAR)nChar))
          //Call base class member, which will call 
          //the control's message handler
	      CEdit::OnChar(nChar, nRepCnt, nFlags);
	      //If not, the message is blocked

The third and final stage is to associate the window with an instance of our new class. In a dialog, this is done simply by using ClassWizard to create a control member variable of your class in the window's parent, and associate it with the control.

Image 2

In a non-dialog parent, you should add a member variable instance of your control to it, and call one of the two CWnd Subclassing functions: CWnd::SubclassWindow or CWnd::SubclassDlgItem. Both routines attach a CWnd object to an existing Windows HWND. SubclassWindow takes the HWND directly, and SubclassDlgItem is a helper that takes a control ID and the parent window (usually a dialog). SubclassDlgItem is designed for attaching C++ objects to dialog controls created from a dialog template.

Further Reading

For a more in depth treatment of MFC subclassing, see Chris Maunder's article: "Create your own controls - the art of subclassing".

Reflected Messages - MFC 4.0+

When you subclass a control, besides handling the message it receives, in MFC, you can also handle the notifications it sends to its parent window. This technique is called Message Reflecting. Windows controls often send notifications to their parents, for example, a Button will send a WM_COMMAND message telling its parent it has been clicked. Usually it is the parent's job to handle these messages, but MFC will also allow you to handle them in the control itself. In ClassWizard, these messages appear with an "=" sign before them, indicating they are Reflected Messages. You handle them just like any other message. The macros for these messages are similar to the regular messages, but have _REFLECT added to the end of the macro. For example, ON_NOTIFY() becomes ON_NOTIFY_REFLECT().

Further Reading

For a more in depth treatment of MFC reflected messages, see the MFC technical notes:

  • TN014: Custom Controls
  • TN062: Message Reflection for Windows Controls


  • 26th April, 2003: Initial version


This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below. A list of licenses authors might use can be found here.


About the Author

Daniel Kopitchinski
Web Developer
Israel Israel
No Biography provided

Comments and Discussions

QuestionNice explanation Pin
ydramkumar20-Jan-12 6:22
Memberydramkumar20-Jan-12 6:22 
GeneralMy vote of 5 Pin
PrinceSinghMukul29-Nov-11 0:51
MemberPrinceSinghMukul29-Nov-11 0:51 
QuestionDialog and Enter Button Pin
zumba zumba22-Aug-08 4:11
Memberzumba zumba22-Aug-08 4:11 
AnswerRe: Dialog and Enter Button Pin
Paul Ong30-Aug-08 1:47
MemberPaul Ong30-Aug-08 1:47 
QuestionHow can I put the subclass proc in one class? Pin
Neviton19-Sep-07 11:37
MemberNeviton19-Sep-07 11:37 
Generalgood Pin
helehop13-Sep-07 17:51
Memberhelehop13-Sep-07 17:51 
GeneralGOOD Pin
wzh1983122112-Dec-06 3:41
Memberwzh1983122112-Dec-06 3:41 
Questionhow to subclass a non MFC control Like Flash ActiveX control in a MFC dialoge? Pin
Haitham Khedre9-Jun-06 11:47
MemberHaitham Khedre9-Jun-06 11:47 
Generalgood ,, and time consuming ... Pin
yooooooooooooo5-Jun-06 21:54
Memberyooooooooooooo5-Jun-06 21:54 
GeneralWM_MOUSEWHEEL in subclassed Pin
mikepc25-Feb-06 8:01
Membermikepc25-Feb-06 8:01 
GeneralFinding the name of the subclass Pin
Alex Evans19-Feb-05 18:14
MemberAlex Evans19-Feb-05 18:14 
GeneralNotify Messages Pin
John Ulvr26-Nov-04 7:57
MemberJohn Ulvr26-Nov-04 7:57 
Generalconsole app messaging ... Pin
dharani6-Sep-04 3:08
Memberdharani6-Sep-04 3:08 
QuestionHow to Dynamically subclass Controls in a dialog whose code i cannot change. Pin
verinder_bindra18-May-04 10:19
Memberverinder_bindra18-May-04 10:19 
GeneralGreat Article Pin
ZeroEpoch17-May-04 8:11
MemberZeroEpoch17-May-04 8:11 
Generalintercept the wm_char message Pin
percyvimal21-Oct-03 22:07
Memberpercyvimal21-Oct-03 22:07 
GeneralSubClassing CBitmapButton in SDK Pin
Vikas Mishra21-Sep-03 21:59
MemberVikas Mishra21-Sep-03 21:59 
GeneralGood explanation of Message reflection Pin
Snakebyte9-Aug-03 8:19
MemberSnakebyte9-Aug-03 8:19 
GeneralAdding controls to a CView Pin
Dave_B20-Jul-03 17:36
MemberDave_B20-Jul-03 17:36 
Questioncan u give this samples in c# Pin
hejun28-Dec-02 1:04
Memberhejun28-Dec-02 1:04 
Generalvery good Pin
yary19-Dec-02 2:00
Memberyary19-Dec-02 2:00 
GeneralGood articles Pin
clio18-Jul-02 8:54
Memberclio18-Jul-02 8:54 
Questionhow 2 link 2 dialoge in sdi Pin
29-Apr-02 10:50
suss29-Apr-02 10:50 
AnswerRe: how 2 link 2 dialoge in sdi Pin
V.Sen...9-Aug-07 2:41
MemberV.Sen...9-Aug-07 2:41 
GeneralThis doesn't work Pin
13-Mar-02 11:26
suss13-Mar-02 11:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.