views:

499

answers:

2

For reference I'm using the window superclass method outlined in this article. The specific issue occurs if I want to handle WM_NOTIFY messages (i.e. for custom drawing) from the base control in the superclass I either need to reflect them back from the parent window or set my own window as the parent (passed inside CREATESTRUCT for WM_(NC)CREATE to the base class). This method works fine if I have a single superclass. If I superclass my superclass then I run into a problem. Now 3 WindowProcs are operating in the same HWND, and when I reflect WM_NOTIFY messages (or have them sent to myself from the parent trick above) they always go to the outermost (most derived) WindowProc. I have no way to tell if they're messages intended for the inner superclass (base messages are supposed to go to the first superclass) or messages intended for the outer superclass (messages from the inner superclass are intended for the outer superclass). These messages are indistinguishable because they all come from the same HWND with the same control ID. Is there any way to resolve this without creating a new window to encapsulate each level of inheritance?

Sorry about the wall of text. It's a difficult concept to explain. Here's a diagram.

single superclass:

SuperA::WindowProc() -> Base::WindowProc()---\
             ^--------WM_NOTIFY(Base)--------/

superclass of a superclass:

SuperB::WindowProc() -> SuperA::WindowProc() -> Base::WindowProc()---\
             ^--------WM_NOTIFY(Base)--------+-----------------------/
             ^--------WM_NOTIFY(A)-----------/

The WM_NOTIFY messages in the second case all come from the same HWND and control ID, so I cannot distinguish between the messages intended for SuperA (from Base) and messages intended for SuperB (from SuperA). Any ideas?

A: 

Naturally, the control (the original?) is sending messages to the PARENT. Presumably, you are intercepting these and posting them back to the original control. The outer layer of course would see these first (and then could just pass them on if it didn't want to handle them).

You haven't said what sort of NOTIFY messages you want to intercept or why. But, since you now have control over them in the parent proc to send them back in, why not just change the message. Roll your own NMHDR struct, embedded the message and data, and add some identification for the level of the super class. In your superclass, peel off the ones you want, reformat the ones you don't, and send them on.

It does sounds a tad messy. At that level I would be inclined to go right back to basics and build my own own common control (depending on, of course, what you are actually trying to do).

David L Morris
A: 

Borland got around this in the VCL by changing the message ID at the parent level. When a parent window receives a WM_NOTIFY message, the message ID is incremented by a defined offset (CN_BASE), and then the message is passed directly to the child window that the message specifies. The child window procedure (and any subclasses of the child) can then look for (CN_BASE + WM_NOTIFY) messages and have access the original WM_NOTIFY data. The same technique applies for WM_COMMAND messages as well. Try doing something similar in your code.

Remy Lebeau - TeamB