Page 1 of 1
What is the subclassing good for?
Posted: 04 Mar 2009, 02:22
by TickTick
Hello!
You always write
' this is required to make the control work as expected
along with the subclassing code for your controls.
I don't notice any difference if I dare to comment the subclassing out. Could you please explain it?
Thank you!
Re: What is the subclassing good for?
Posted: 04 Mar 2009, 12:34
by TiKu
It's required for several things:
1) Are you familiar with the WM_NOTIFYFORMAT message and message reflection? It is sent by the common controls to the parent window (usually the form) so that the parent window can decide whether it wants the control to send Unicode notification messages (WM_NOTIFY) or ANSI notification messages. Since a VB6 form is an ANSI window, it responds to WM_NOTIFYFORMAT with NFR_ANSI, meaning "send ANSI notifications". Now this is how message handling is done:
The control itself (i. e. Microsoft code inside comctl32.dll) sends WM_NOTIFYFORMAT to its parent window. Depending on the response it sets a flag whether to send Unicode or ANSI notifications. Whenever the control (Microsoft code again) sends a notification to its parent window, the parent window sends it back to the control. This message reflection of WM_NOTIFY already is done without the subclassing, in case you wonder. Now my code (inside the control) is able to handle this notification. Usually it translates it into an event.
WM_NOTIFYFORMAT is a message, that is not reflected back to the sender by default. But since my Unicode control on a VB6 form would receive reflected ANSI (instead of Unicode) notifications and lose some of its Unicode support, the VB6 program should reflect WM_NOTIFYFORMAT back to the control (which will respond with NFR_UNICODE) and that's what the subclassing is for.
Now where's the difference between reflecting WM_NOTIFYFORMAT and not reflecting it? The reflection is required for full Unicode support. Without reflection events like GetDisplayInfo won't support Unicode strings. So if you decide to not reflect this message and detect that the control somewhere displays question marks instead of Unicode characters, try adding the reflection.
2) The ContextMenu event is based on the WM_CONTEXTMENU message. Some controls seem to not receive this message, but their parent window receives it. If this is the case, WM_CONTEXTMENU must be reflected back to the control to make the ContextMenu event work. NOTE: Displaying context menus on right mouse button click is very bad practise.
3) The subclassing is needed to make keyboard cues work (the underlining of mnemonics). This has not really to do with the controls, but with the VB6 form itself.
I think I've covered all cases.
Re: What is the subclassing good for?
Posted: 04 Mar 2009, 14:03
by TickTick
Thanks for the explanations. But I have never ever seen a questionmark. So I'm wondering how come that this, as you describe it, something happens and something not.
And my next question would be why this is not done inside your control but within the form's code.
Hans
Re: What is the subclassing good for?
Posted: 05 Mar 2009, 02:36
by TiKu
TickTick wrote:Thanks for the explanations. But I have never ever seen a questionmark. So I'm wondering how come that this, as you describe it, something happens and something not.
You'll see question marks only if the string is transfered to the control (I mean the code inside comctl32.dll) via a notification. Most strings are not transfered this way.
TickTick wrote:And my next question would be why this is not done inside your control but within the form's code.
You mean subclass the parent window from inside the control? I had done this years ago and got many crashes if more than 1 control was placed on the same form. The problem is, that you can't predict the order in which the controls get created and destroyed, so the following may happen:
- Form gets created, its message handler is called WndProcForm.
- Control A gets created, subclasses the form (new message handler: WndProcA). Messages for the form are sent to WndProcA now. WndProcA forwards them to WndProcForm.
- Control B gets created, subclasses the form (new message handler: WndProcB). Messages for the form are sent to WndProcB now. WndProcB forwards them to WndProcA. WndProcA forwards them to WndProcForm.
- Control A gets destroyed, unsubclasses the form (new message handler: WndProcForm). Messages for the form are sent to WndProcForm now. WndProcB would still forward messages to WndProcA, which doesn't exist anymore.
- Control B gets destroyed, unsubclasses the form (new message handler: WndProcA). Messages for the form are sent to WndProcA now!! Here the program will crash of course.
It would be rather complicated to solve this problem. Also if you place 20 controls on a form, the form will be subclassed 20 times, i. e. 99,9% of all messages will be forwarded 20 times before they get handled.