Solved

Creating a simple Custom Control

Posted on 2004-09-08
11
1,209 Views
Last Modified: 2013-11-20
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.
0
Comment
Question by:x4u
  • 3
  • 3
  • 2
  • +1
11 Comments
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 12013295
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.
eg.

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().

      AddPage(&m_Page1);
      AddPage(&m_Page2);
}
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 12013362
0
 
LVL 11

Author Comment

by:x4u
ID: 12022550
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);
      else
            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.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 12023212
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).
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 11

Author Comment

by:x4u
ID: 12023666
> 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).
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 12023998
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.
0
 
LVL 11

Author Comment

by:x4u
ID: 12027177
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?
0
 
LVL 44

Accepted Solution

by:
AndyAinscow earned 250 total points
ID: 12027303
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).
0
 
LVL 49

Assisted Solution

by:DanRollins
DanRollins earned 250 total points
ID: 12035580
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
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now