Creating a simple Custom Control

Hello, once again I wasted a lot of time today trying to get something supposedly trivial done that was actually supposed to save me some time.

- Put some controls (a textfield, 2 buttons and maybe a static label or picture control) into a small property sheet and layout them within the resource editor.
- Create a subclass of CDialog with variables for these controls and initialize them with the mentioned property sheet.
- Put a dozen of these subclass instances into another dialog and layout them as Custom Controls.

It worked more or less well except the "... and initialize them with the mentioned property sheet" part.

I'm pretty new to MFC and Win32 and assumed that all I need to do is to get the DoDataExchange method invoked from somewhere and this would create and initialize the subcontrols. But I keep getting Assertion failed and various errors when I try to do this in a similar way as seems to be done by the CTabCtrl. The class itself (without it's contents) run's well and instances of it can be placed in a dialog.

I'm sure someone of you can help me to get this done.
LVL 11
Who is Participating?
AndyAinscowConnect With a Mentor Freelance programmer / ConsultantCommented:
Sorry - not with PropertySheet/Propertypage.
Your two cases - I took your first to mean you would be showing/hiding one after another.

I still think your simplest method is to have just one dialog (You can 'group' controls with frames for a visual display).
AndyAinscowFreelance programmer / ConsultantCommented:
First do you want a property sheet (tab control + different page) or just a dialog.

For a dialog.  In resource editor choose addnew / dialog.  Add controls you require.  Select class wizard, it prompts for you to create a new class, choose CDialog as base.  From class wizard go to the second tab - variables - assign variables to the controls you want mapping.

For a property sheet (with VC 6 there is a wizard - component gallery to help) you have more work to do.  The PAGES to be displayed are created as above BUT you require CPropertyPage as the base class.  You then need a class based on CPropertySheet and it is to this you add the pages.

CMyPropertySheet::CMyPropertySheet(CWnd* pWndParent)
       : CPropertySheet(IDS_PROPSHT_CAPTION, pWndParent)
      // Add all of the property pages here.  Note that
      // the order that they appear in here will be
      // the order they appear in on screen.  By default,
      // the first page of the set is the active one.
      // One way to make a different property page the
      // active one is to call SetActivePage().

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

x4uAuthor Commented:
Thank you for your feedback.

AndyAinscow, I tried it this way and it worked well. But how do I place this dialog into another one now? When I add it as a custom control another dialog I run into the following Assert:

Assertion failed in winocc.cpp line 330:

BOOL CWnd::ShowWindow(int nCmdShow)
----->      ASSERT(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL));

      if (m_pCtrlSite == NULL)
            return ::ShowWindow(m_hWnd, nCmdShow);
            return m_pCtrlSite->ShowWindow(nCmdShow);

The debugger says:
m_hWnd = 0x00000000
m_pCtrlSite = 0x00000000

AlexFM, this is the example I started with and it worked well. But now I have the problem how to place other controls into this custom control.

Well, now I have a custom dialog where I can put some controls into and I have a custom control that can itself be put into a dialog. What I want is a custom dialog control that allows me to do both.
It can be difficult to use a dialogbox as a control within another dialogbox.   Before getting into this relatively complex arena, answer this:  

Are you sure that is necessary?  Can't you just put whatever you are putting in the control-dialog directly into the parent dialog?  Or perhaps make a series of property pages (depending upon your ultimate goal).
x4uAuthor Commented:
> Are you sure that is necessary?

Well, I have two cases where this would be helpfull.

First one is a configuration dialog that displays about a dozen very similar options where each needs a text field, two buttons and a readonly text field or an image that displays some state. It is not yet clear whether the customer ultimatly want's a combo box instead of the text field or a slider instead of the buttons. There is also some logic and validating neccessary for each option and the sub controls need to interact with each other. I think think this cries for some kind of encapsulation although I do not necessarily need to be able to layout the sub controls in the visual resource editor.

The second one is is a rather complex dialog which I need only once. But it is not yet decided whether this will become a page in a tab control or should be part of the main window without a tab control around it (maybe even configurable by the user).
AndyAinscowFreelance programmer / ConsultantCommented:
If you mean you want for example 5 sub dialogs all looking the same but displaying different info then I would jst have one dialog and reset the contents depending on what needs to be shown.
To display different sub dialogs dynamically swapped inside another is a description of the PropertySheet - PropertyPage logic.
x4uAuthor Commented:
AndyAinscow, I'm not sure whether I understand you right. I need these similar subdialogs to be visible side by side at the same time inside a larger dialog not just one at a time. Is this possible with PropertySheet - PropertyPage logic? How?
DanRollinsConnect With a Mentor Commented:
I agree.  By the time you do all of the jinking around to make the keyboard (especially the tab key) work the way people expect it to work and add the logic to position the sub-dialogs and the extra work that is normally handled by DDX and a few clicks in the ClassWizard ... you are simply better off not trying to encapulate such trival functionality... just group the controls and handle them normally.

That's not to say that you couldn't or shouldn't write some shared code that would be used by each group if that code got complicated.   When in similar situation, I have used "cut-and-paste encapulation" to just duplicate functionality by adding _2 and _3, etc to the fn names.  But then, I'm the original pragmatic programmer... program purity is pretty low on my list compared to such mandates as "keep it simple" and "if you got to explain it to the maintenance kid, you probably made it too complicated and there goes your lunch hour."

Another consideration might be if there were a variable number of such groups (say, anywhere from 3 ro 20 groups, depending upon some outside parameter).  If that were the case then it might make more sense.  But if there is a fixed number of these groups, it's just not worth it.

-- Dan
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.