1

I have my own WTL derived listcontrol.

CPopupList : public CWindowImpl<CPopupList, WTL::CListViewCtrl>,

It works fine, except one thing: I want to catch the notification when selection changes. Not in the parent window (like this: How to detect a CListCtrl selection change?) , but in the CPopupList itself, and then do some things.

Actually I want a small hint window next to the currently selected item to appear, as an additional info of the current item. Just like VS does during autocomplete, giving more info about the functions/properties.

Has anyone any tip how to do this? Thank you very much.


Update:

Tried:

BEGIN_MSG_MAP(CPopupList)
    REFLECTED_NOTIFY_CODE_HANDLER(LVN_ITEMCHANGED, OnListItemChanged)
    DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()

But OnListItemChanged() is not called. In the parent the

REFLECT_NOTIFICATIONS()

is added.


Update2 - SOLUTION

I found the problem:

The parent's MSG_HANDLER:

BEGIN_MSG_MAP(CEditorCtrl)
    MESSAGE_RANGE_HANDLER(WM_KEYFIRST,WM_KEYLAST,DelegateMessages)
    ...
    MESSAGE_
    ...
    NOTIFY_CODE_HANDLER(LVN_ITEMCHANGED,OnListItemChanged)
    CHAIN_MSG_MAP(parentType)
    ALT_MSG_MAP(11)
    COMMAND_HANDLER(IDC_PRINT_MONOCHROME,BN_CLICKED,OnPrintMonochromeButton)
    REFLECT_NOTIFICATIONS()
END_MSG_MAP()

Moving the REFLECT_NOTIFICATIONS() above the ALT_MSG_MAP(11), and finally the OnListItemChanged is called in the control.

Correct:

    REFLECT_NOTIFICATIONS()
    ALT_MSG_MAP(11)
    COMMAND_HANDLER(IDC_PRINT_MONOCHROME,BN_CLICKED,OnPrintMonochromeButton)
Community
  • 1
  • 1
Zoli
  • 841
  • 8
  • 31

2 Answers2

2

The notification message is sent to parent anyway, you cannot change this. What you normally do is message reflection from parent to the child, so that [improved] child could take care of notification generated by its ancestor.

The parent window will have a reflecting handler on the message map:

#include <atlcrack.h>

BEGIN_MSG_MAP_EX(CMyDialog)
    // ...
    REFLECT_NOTIFICATIONS()
END_MSG_MAP()

And the control will have a handler for WM_NOTIFY notifications reflected by control parent:

BEGIN_MSG_MAP_EX(CPopupList)
    // ...
    //MSG_OCM_CTLCOLORSTATIC(OnReflectedCtlColorStatic) // Reflected WM_CTLCOLORSTATIC
    MSG_OCM_NOTIFY(OnReflectedNotify) // Reflected WM_NOTIFY
    DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()

OnReflectedNotify is where you can handle the control's notifications, but the parent is responsible for forwarding them (with or without its own processing).

See also a word on this on CodeProject in WTL macros for handling reflected messages.

Roman R.
  • 68,205
  • 6
  • 94
  • 158
  • Thanks. My comment, both BEGIN_MSG_MAP_EX and MSG_OCM_NOTIFY give syntax error during compilation. BEGIN_MSG_MAP without _EX works. What I tried: REFLECTED_NOTIFY_CODE_HANDLER(LVN_ITEMCHANGED, OnListItemChanged) I will update the question But does not work – Zoli Mar 14 '13 at 17:12
  • You need to `#include ` (WTL's files) – Roman R. Mar 14 '13 at 17:24
  • `BEGIN_MSG_MAP_EX` is WTL enhancement for ATL's `BEGIN_MSG_MAP` – Roman R. Mar 14 '13 at 17:25
  • Addig the NOTIFY_CODE_HANDLER to the parent, and it is called in the parent. Strange. But not reflected in the child. Updated the question with this – Zoli Mar 14 '13 at 17:39
  • Finally!! I have the solution. As your reply helped me very much, I accept it as answer. Will update the question with the answer – Zoli Mar 14 '13 at 17:50
0

The OP's problem has been solved. But for those of you for which the notify message still doesn't get delivered, read on...

You might have to subclass the window!

Let's assume you have configured all your message maps correctly. And by stepping with the debugger you see that the parent dialog is trying to deliver the message to the control.

In other words, you see it calling SendMessage to deliver the message. If WM_NOTIFY gets reflected by the parent, then OCM_NOTIFY will be sent to the derived control.

Yet, nothing happens in the message handler of your derived control.

If your parent window code only does something like MyDerivedControl.Attach(hwndControl) then you will not receive any messages on your derived control class. Behind the scenes Attach will copy over the window handle (HWND) and that's about it. To be able to handle messages from your derived control the system needs to setup several other things.

In practice it means calling SubclassWindow instead of Attach.

E. van Putten
  • 615
  • 7
  • 17