Double Subclassing--Runtime Form Editor

Environment: Any flavour of MFC (Doc/View) including VC6 and VC7 (demo is VC7)


I had a project in the company where I work that needed different forms for different customers, so the team decided to create a runtime form editor that can enable editing the forms for each customer. To do that, I needed a way to control all the Controls on a formview or on a dialog; I needed to resize the controls, move them, or hide them. I wanted to subclass the Controls on a dialog/formview to control them; however, the major problem was that most controls were already subclassed. I wrote a class, CDblSubclassWnd, that can subclass controls even if they are already subclassed.

It works like this: The messages first go into a function called PreWndProc and then they continue to the original WndProc of the Control. After it is finished, it goes into a function called PostWndProc.

The class is simple to use. The demo in the article contains a very simple form editor that allows you to easily move the controls on the form while you are in edit mode.

Using the Class

You have three methods of the class CDblSubclassWnd that you will work with. All methods are static.

  1. The first thing to do is give to the class two pointers to functions. The CDblSubclassWnd class will call these to pass by the messages of the subclassed controls. The methods signature is:

    static void SetDblSubclassWndProc(DBLSUBCLASS_WNDPROC
           *pPOSTPointer = NULL);

    The first parameter is a pointer to the function, PreWndProc, that will be called prior to passing on the message to the main WndProc of the control (or another Proc if it is subclassed). This function would give you the option of changing messages before they reach their control.

    The second parameter is a pointer to the function that will be called after the control processed the message, PostWndProc. You can use this to inspect the values changed (or returned) by the Control.

    The DBLSUBCLASS_WNDPROC function pointer is defined as such:

                                                 UINT, WPARAM,
                                                 LPARAM, bool &);

    The first parameter is a pointer to the Control Window class that the current message belongs to. The second parameter is the Handle to the Window. The third parameter, UINT, is the Message Number itself, and the following two parameters, WPARAM and LPARAM, are the two parameters that are passed with every Window Message; their meaning depends on the actual message. The last parameter, a reference to a bool, is used to indicate whether you want the DblSubclassed Engine to discontinue routing the message and return the return value returned by one of your two functions, pPREPointer or pPOSTPointer. To explain this point more by an example, if you have a button and you clicked this button, the clicking message BN_CLICKED would first go to the PRE function pointer you assigned. If you do not want this message to continue to the WndProc of the control, you can stop this by setting the the boolean (last parameter of the function DBLSUBCLASS_WNDPROC) to false. This way the message will be dropped and will not reach the control.

  2. Now that you have your PreWndProc and PostWndProc set, it is time to actually call the methods to subclass the Controls.

    void CDblSubclassWnd::SubclassChildsRecurs(HWND hWnd,

    You call this method giving it, for example, the handle to the dialog you are working in. The function will traverse all the Controls on the dialog and for each control will call the function pointer to the second parameter of the function, BLSUBCLASS_RECURSIVECALLBACKPROC. This function will be called by the engine for each control that is going to be subclassed; its job is decide whether the control is to be subclassed or not. For example, if you want to subclass all the Buttons on your dialog and not all the controls, in your RecursiveCallBack function, you would test for the control for being a button or not and you would return true only for the button controls. The RecursiveCallBack simply takes a HWND parameter (to do your testing on the control) and returns a boolean value to indicate whether to subclass the specified control or not.

  3. After you subclass the controls, the messages will start flowing into your PRE and POST WindowProc assigned in the call to SetDblSubclassWndProc (in the first step). When you want to end this effect, you unsubclass the doubly subclassed controls by using UnSubclassChildsRecurs. Its use is straightforward: You give it the Handle to the main window (the dialog in our example) and it will go through the Controls belonging to it and unsubclass all the Controls that were subclassed before.

I hope you will find this article useful.


Download source and demo project - 45 Kb


  • U r the BEST

    Posted by Legacy on 05/15/2003 12:00am

    Originally posted by: Rabih

    No comments whatever u do, u look the best

  • So cool!

    Posted by Legacy on 05/14/2003 12:00am

    Originally posted by: dddang


Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Agile methodologies give development and test teams the ability to build software at a faster rate than ever before. Combining DevOps with hybrid cloud architectures give teams not just the principles, but also the technology necessary to achieve their goals. By combining hybrid cloud and DevOps: IT departments maintain control, visibility, and security Dev/test teams remain agile and collaborative Organizational barriers are broken down Innovation and automation can thrive Download this white paper to …

  • As mobile devices have pushed their way into the enterprise, they have brought cloud apps along with them. This app explosion means account passwords are multiplying, which exposes corporate data and leads to help desk calls from frustrated users. This paper will discover how IT can improve user productivity, gain visibility and control over SaaS and mobile apps, and stop password sprawl. Download this white paper to learn: How you can leverage your existing AD to manage app access. Key capabilities to …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds