1

I'm trying to understand how message routing works in MFC, and I have some questions regarding it. Imagine a control that extends CWnd. My first question is: are all messages in that control passed on to the parent control?

I know that doesn't happen with CStatic which only passes specific messages when you set the SS_NOTIFY style. What I'm trying to understand if that's specific to CStatic or happens with all the controls. Specifically I'm trying to make a control that has several child controls with the sole purpose of defining their layout. I wanted all messages of the child controls to be handled by the parent of this intermmediate control. For example if this layout control has a child button, when the button is clicked the message would be sent to the parent to be treated.

However I don't intend to treat all messages manually. So, if I extend my control from CWnd instead of CStatic will the message be passed on? Is FORWARD_NOTIFICATIONS() available in MFC? If not I'd rather extend my intermmediate classes to handle messages as needed. Any other solutions you know off?

webdreamer
  • 2,359
  • 3
  • 23
  • 30

2 Answers2

1

Messages are sent to a window itself.

Some windows send messages to their parents, usually in the form of WM_NOTIFY messages, or (like for buttons) in 'special' message like BN_CLICKED.

MFC has a system (the 'reflection' system) to let windows send those messages back to the window itself, so that you can deal with messages in the control rather than involving the parent control.

This is roughly how it work in the abstract. What you want (have a parent control handle all messages send to all child controls) is not generally how you 'should' do it. For example, you don't want all WM_PAINT for child windows to be send to the parents.

What you want to do (handling button clicks) is different. Button clicks are 'emitted' by the button in the form of BN_CLICKED. Those would be handled by the parent anyway.

If you're still determined, you can take over the WndProc of the child windows to do some 'filtering'. Generally this is done using the PreTranslateMessage() virtual function.

Roel
  • 19,338
  • 6
  • 61
  • 90
  • What I wanted was for the messages that are going to be handled by the parent to be handled by the grandparent. The messages that were to be handled by the control would be kept so. What I wanted my container to be transparent to the messages that are sent to the parent. – webdreamer Dec 21 '11 at 10:45
  • OK I understand now. This cannot be done 'easily', where 'easily' means having to use only ohe macro or so. You'd have to catch messages in the parent (the container) and manually re-send them to the container's parent. Much of this can be automated though, like by intercepting all BN_CLICKED messages to one function, and have that one function re-send them to the parent. That way you wouldn't have to update the container each time you add a button. – Roel Dec 21 '11 at 12:35
  • Can I handle the BN_CLICKED message and send the message to the parent? How? Or do I have to send the general Notifty and tell the messages apart in the parent? – webdreamer Dec 23 '11 at 18:15
0

You need to be using notifications, that means sending a WM_NOTIFY message with your own code specified in the attached structure. Your parent controls can then handle the messages with ON_NOTIFY, or you can get the owner class to handle the message itself with ON_NOTIFY_REFLECT.

You could always avoid the Windows\MFC messaging architecture and use an event based system instead. Something like Boost.Signals2. In our applications we use a mixture of WM_NOTIFY messages and Boost.Signals2.

Mark Ingram
  • 71,849
  • 51
  • 176
  • 230