Expanding/Contracting Dialog Box

In a moderately complex application, the user is presented with the task of learning the features of the software. It is useful, in some cases, to limit the features that a beginning user has access to; also, an advanced user will appreciate not being inundated with a large number of controls on a dialog, but only the ones that are used most frequently. Hence the need for an expanding and contracting dialog.

The premise of the expanding/contracting dialog is to present a set of controls on a dialog to the user, and then allow access to the rest of the "advanced" controls if the user clicks the appropriate button to expand the dialog. A sample of this is as follows:

The class presented here fits between your dialog class and CDialog, so that the expanding/contracting actions can be automatically managed. There is minimal change to be made to your existing dialog class code, so it is easy to add and remove this expanding/contracting feature to your dialogs.

This code should be UNICODE correct (it has not been tested), and compiles warning free under VC++5 using MFC 4.2.

Instructions

  1. add the ExpandingDialog.h and ExpandingDialog.cpp files to your project.
  2. add a static frame to your dialog (in VC++, this is the "picture control") for the default box, and give it a unique resource ID.
  3. add a button to your dialog which will be the "Advanced" button (the one that expands and contracts the dialog), and give it a unique resource ID.
  4. in your dialog's .h and .cpp files, replace all occurrences of CDialog with CExpandingDialog.
  5. in your dialog's .h file, put a "#include ExpandingDialog.h" above your dialog's class declaration.
  6. modify the constructor of your dialog in your dialog's cpp file, to look something like the following:
    
    CMyDialog1::CMyDialog1(CWnd* pParent) : CExpandingDialog(CMyDialog::IDD,
    pParent,IDC_DEFAULTBOX,IDC_ADVANCEDBUTTON, _T("Advanced >>"),
    _T("Advanced <<"))
    
    (In this example, IDC_DEFAULTBOX was the ID given for the static frame in step 2, and IDC_ADVANCEDBUTTON was the ID given for the button in step 3.)

That is all that needs to be done; recompile and run your application, and the expanding/contracting dialog should work correctly. For extended capabilities, please read the documentation for the utility and virtual functions listed below.


Class Members

Constructor:

CExpandingDialog(
   UINT nIDTemplate,
   CWnd* pParent, 
   int nIDFrame,
   int nIDButton,
   LPCTSTR strExpand = _T("Advanced >>"), 
   LPCTSTR strContract = _T("Advanced <<"),
   BOOL bAllowContract = TRUE)

Normally, the constructor is called from the implementation of your dialog's constructor. The first two parameters are the same as those taken by CDialog. The rest are specific to CExpandingDialog, are are as follows:


int nIDFrame 

the resource ID of the static frame that defines the boundaries of the contracted state of the dialog.


int nIDButton 

the resource ID of the button that will be used to expand and contract the dialog


LPCTSTR strExpand and LPCTSTR strContract 

the strings that will be put on the button identified by nIDButton, when the dialog is in its contracted and expanded state, respectively.


BOOL bAllowContract

if TRUE, the dialog will allow the user to both expand and contract the dialog. If FALSE, the user may expand the dialog, but may not ever contract it again. This flag does *not* affect the operation of the Expand() function; in other words, you may still programatically expand and contract the dialog.

Utility Functions:

BOOL IsExpanded() const

Use this function to query the current expanded or contracted state of the dialog. TRUE denotes an expanded dialog, and FALSE denotes a contracted dialog.


BOOL Expand(BOOL bExpand)

Call this function to expand or contract the dialog manually. This function returns whether the new state matches the state passed in the "bExpand" parameter. In other words, TRUE on success, and FALSE on failure.

If the state passed into this function matches the current state of the dialog, this function returns TRUE immediately without calling any of the virtual notification functions OnDialogExpanding and OnDialogExpanded.

 

Overridables:

BOOL OnDialogExpanding(BOOL bExpand) const

This function is called when the dialog is about to expand or contract. The parameter "bExpand" tells whether we are about to expand or contract the dialog. Return TRUE to allow the operation to continue, and FALSE to keep the dialog from expanding or contracting.

The default implementation of this function simply returns TRUE to allow the dialog to change state.


void OnDialogExpanded(BOOL bExpand) const

This function is called after the dialog has expanded. The parameter "bExpand" tells whether the dialog is now in the expanded or contracted state. This is the appropriate place to do things like set the focus to a particular control, change text in controls on the dialog, etc.

The default implementation of this function does nothing.


Final notes:

If needed, is it possible to handle the message generated by the click of the "Advanced" button, simply by adding the appropriate message handler to your dialog's message map. Handling this message does not affect the operation of the expanding/contracting dialog. If you do choose to handle this message, be aware that this implementation of the expanding/contracting dialog guarantees that the dialog will have fully changed state before you receive the message from the Advanced button that it has been clicked. This is very useful, because you can assume that the dialog is (again) in a static state, with the appropriate controls enabled/disabled, before you receive the message.

Credits: the code in the ExpandBox() member function is based on code by Jeffery Richter in "Windows 95: A Developer's Guide"

Download demo project - 49 KB

Download source - 5 KB



Comments

  • clarisonic mia selling in the ebay is merit to pull someone's leg

    Posted by iouwanzi on 06/07/2013 12:21am

    [url=http://www.miaclarisonicaustralia.org/clarisonic-pro]clarisonic pro[/url] Elle devait examiner un individu ghd IV Styler avant vers le bas les avantages de l’utilisation de lisseur ghd pas cher dans Vous pouvez aussi le plus souvent de prêt-à-utiliser de l’huile durcit à intégrer les huiles végétales avec de l’huile de sésame, l’huile d’olive et de noix de coco.ghd lisseur est énorme à l’intérieur du Questionnaire, votre défrisants impliquant dela crème de la crème. L’idée n’est pas si énorme qu’aux États-Unis, qui à son tour, j’ai trouvé étrange, néanmoins je pense de la nation pour la raison que de toutes les quelques autres marques qui ont été si grands qui peut être à ce point moins décent. [url=http://www.miaclarisonicaustralia.org/clarisonic-classic]clarisonic classic[/url] Ce redressement en termes de fer relèvent de 4 modèles. Pour que vous choisissiez telle qu’énoncée par ceux type de cheveux bouclés, mais aussi les coiffures que vous souhaitez atteindre. Par le biais de processus un peu, c’est très simple aussi obtenir de belles boucles. Et même le type est parfait pour le lissage de la frange ainsi que pour les individus.Espagne, GHD annonce une promotion très utile. Dans les cas où la plupart des gens portent votre propre fer plat âgé dans un point de vente de cette marque, une certainement se verront faible coût à l’achat d’un fer à lisser ghd pas cher. Il est généralement valable jusqu’au 6 mai 2011. En fait, vous ne pouvez généralement décider de votre propre blog officiel de fer plat. Certaines personnes offrent le monde entier !Comme que je quitterai les gens avec la finale de vente spot qui est vraiment très beau. Une Cendrillon moderne important ! [url=http://www.australiaclarisonic.com/]clarisonic australia[/url] Ghd IV styler lisseur où acheter défrisants ghd aux questions économiques? Seulement il suffit de suivre le lien ci-dessous et vous devriez maintenant commencer à frapper votre corps!Sa solution de traitement en profondeur de traitement est certainement pourrait combiner quelque chose d’autre dans l’eau pendant une gammes de prix ghd lisseur. Pouce romanciers possibilité réelle ne pense pas que le bureau à domicile types package peut sembler la route vers le site world-wide-web pour la marque d’avoir toutes les opportunités uniques trouvés dans le site Web de kilométrage publicité en général. Ghd lisseur donner 5 eux-mêmes, vous pouvez habiller la manière Quelqu’un veut jouer ce que viennent généralement environs Pour ceux qui connaissent les poils indésirables, pour vous inscrire à votre communauté cheveux doivent être prêts à vous aider à obtenir le genre de perte de cheveux inattendu est habituellement causée par une maladie auto-immune grave, et aussi de temps en temps, une sorte négatif de réaction à des médicaments sûrs que vous avez travaillé, effectuez l’heure suivante plupart d’entre nous sur le fait que sans douleur que vous bénéficiez que 100% de tous les médias vidéo gratuit en ligne principalement parce que la plupart d’entre nous ne veulent pas quelqu’un qui cherche à d’innombrables heures à consacrer à le faire!

    Reply
  • Shorter guide exposes the proven facts about chloe and the way it could influence on users.

    Posted by emeseesip on 05/06/2013 01:56pm

    1 Of The Most Detailed nike Handbook You Ever Witnessed Otherwise Your Cash Back [url=http://www.guccija.biz/]gucci 財布[/url] Ok, amazing product. Your organization got to view adidas right now whilst it is still in stock ! ! ! [url=http://www.guccija.biz/]グッチ 長財布[/url] adidas can help all of us by including a number of unique features and options. Its a unvaluable item for every enthusiast of nike. [url=http://www.guccija.biz/]グッチ 財布 新作[/url] Honest essay presents you with Six brand new stuff concerning nike that none is bringing up. [url=http://www.chanelja.biz/]シャネル マトラッセ[/url] Explanation why no one is chatting about adidas and due to this fact the actions you ought to execute immediately. [url=http://www.chanelja.biz/]chanel バッグ[/url] Advanced questions on adidas replied to and the reasons why you should study every single phrase in this report. [url=http://www.chanelja.biz/]財布 chanel[/url] The fundamentals of the adidas it is possible to profit by beginning today.[url=http://www.nikeja.biz/]ナイキスニーカー[/url] Tips on how to understand all things there is to understand surrounding adidas in 4 basic steps.

    Reply
  • burberry femme pas cher

    Posted by Wrinalertiece on 04/30/2013 12:10am

    burberry femme pas cher sac burberry pas cher Burberry Pas Cher burberry homme [url=http://burberryhomme2.webnode.fr/]burberryhomme2.webnode.fr[/url] , burberry homme pas cher [url=http://chemiseburberry6.webnode.fr/]chemiseburberry6.webnode.fr[/url] , burberry homme

    Reply
  • Fantastic Job!

    Posted by Legacy on 06/18/2002 12:00am

    Originally posted by: Trent

    Thanks a lot, it's flawless!

    Well done!

    Reply
  • Better fix for your expand/contract sizing issue

    Posted by Legacy on 06/14/2002 12:00am

    Originally posted by: J.D. Bertron

    The earlier fix given by Shane Triem works only if you expand/contract vertically.
    You're better off keeping the original code the same and fix the size of the default box in the resource file.

    Just add 3 units to the dialog box's dimension and use the result for the default box dimension. (269 -> 271)

    IDD_MYDIALOG DIALOG DISCARDABLE 0, 0, 269, 202 ...

    CONTROL "",IDC_DEFAULT_BOX,"Static",SS_BLACKFRAME | NOT WS_VISIBLE,0,0,271,136 ...

    J.D.

    Reply
  • Howto easy create an app and my experience with size bug

    Posted by Legacy on 10/30/2001 12:00am

    Originally posted by: Robin Holenweger

    Hi
    First of all: many thanks to Daniel G. Hyams for the great class!

    I'd like to tell here how it seems to be very easy to create an app an what experience I have with solving the size bug. I use Win2k SP2 with DevStudio 6.0 SP5

    The easiest way to create an app:
    - Use AppWizard to create a new dialog project (e.g. MyTest)
    - Add the CExpandingDialog class to the project
    - include "ExpandingDialog.h" in MyTestDlg.h
    - Replace all CDialog by CExpandingDialog the app's default dialog's files (e.g. in class CMyTestDlg, MyTestDlg.h and MyTestDlg.cpp) except the ones used in class CAboutDlg (which are in the same file)
    - complete the CMyTestDlg's constructor with ",IDC_DEFAULTBOX,IDC_ADVANCEDBUTTON,_T("Advanced >>"),_T("Advanced <<")" in MyTestDlg.cpp
    - Add a button/checkbox whatever with ID IDC_ADVANCEDBUTTON and a frame with ID IDC_DEFAULTBOX in the MyTestDlg dialog
    That's it (compile and start). This way you still have the icon, about box and so on in the title bar. Also Message Map and so on are derieved from CExpandingDialog.

    Size bug:
    The easiest way I found out is to exactly size the frame. Actually there are 3 points to take into account:
    - justify the bottom of the frame
    - justify the right edge of the frame
    - make the frame large enough so all controls are in it that should be enabled when contracted
    Note: It doesn't matter, where the top and left edges of the border are. Only make sure that the necessary controls are in it and if you want e.g. expanding down only, that in this case the right border edge is aligned with the border of the dialog (use ALT key to do this, see comment "No horizontal resizing problem here! (Read this)" of Chris Montgomery).

    Cheers

    Robin

    Reply
  • Expanding Dialog

    Posted by Legacy on 05/03/1999 12:00am

    Originally posted by: Franz Klein

    Can't get the Dialog to expand to the left or upwards. Anybody got any ideas.

    Reply
  • Problems with reusing Dialog

    Posted by Legacy on 03/15/1999 12:00am

    Originally posted by: Roland Frank

    I had a problem with the CExpandingDialog class when I reuse
    
    a dialog.

    In some situations I want to do the following:

    CMyDialog dlg;

    dlg.DoModal();
    // do something with the dialog data
    dlg.DoModal();


    On the second call to DoModal() the dialog appears expanded, the frame
    that denotes the collapsed size is visible and the "expand button" does
    still have the text of the dialog template.

    as a quick an dirty solution I changed the OnInitDialog as follows:

    BOOL CExpandingDialog::OnInitDialog()
    {
    CDialog::OnInitDialog();
    m_bExpanded = TRUE; // CDialog::OnInitDialog leaves the dialog expanded!
    ExpandBox(FALSE);
    return TRUE;
    }

    The only problem here is, that if the user leaves the dialog expanded
    and it is then later shown again, it will be collapsed.
    For my current project this isn't a problem but it could be in later
    projects, so I'm still looking to solve this.

    Another little annoyance is, that during the collapse procedure all
    controlls get disabled and then later when the dialog expands again
    all controlls get enabled.
    In all but the most simplest dialog good user interaction means
    enabling and disabling dialog control depending on context.
    I solved this by packing all enabling/disabling logic into a single
    function I also call from OnDialogExpanded.

    Thanks for the class!
    Roland Frank

    Reply
  • keeping the horizontal edges the same as the dlg solution

    Posted by Legacy on 01/27/1999 12:00am

    Originally posted by: Shane Lim

    Well I have difficulty trying to align the static frame control
    size with the dlg edges when I want to edges of the dlg remaind
    the same when expanding and contracting. None of the methods
    suggested so far can effectively achieve this.

    here is my solution - even though it's involve a bit more coding.
    This method allow you to simply drop the static frame control
    and resizing it to inlcude the button with ID of IDC_ADVANCEDBUTTON.
    Of course you have to resizing the vertical size as before.

    in ExpandingDialog.h add
    public:
    void AlignToDlgHorzEdge(BOOL bAligned);

    private:
    BOOL m_bAligned;

    in ExpandingDialog.cpp add
    - initialize this in the constructor
    m_bAligned = FALSE;

    - add this method
    void CExpandingDialog::AlignToDlgHorzEdge(BOOL bAligned)
    {
    m_bAligned = bAligned;
    }

    - add/modified this section of code

    void CExpandingDialog::ExpandBox(BOOL fExpand)
    {
    ...
    if (m_bAligned) {
    _ASSERT(m_pSize != NULL);
    SetWindowPos(NULL,0,0,m_pSize->cx,rcDefaultBox.bottom - rcWnd.top,SWP_NOZORDER|SWP_NOMOVE);
    } else {
    // Note: this bit is the original code and I it seem to be fine to me
    // shrink the dialog box so that it encompasses everything from the top,
    // left up to and including the default box.
    SetWindowPos(NULL,0,0,
    rcDefaultBox.right - rcWnd.left,
    rcDefaultBox.bottom - rcWnd.top,
    SWP_NOZORDER|SWP_NOMOVE);
    }
    ...
    }

    in the MyDialog1.cpp in the contructor add
    AlignToDlgHorzEdge(TRUE);

    Bye 4 now !


    Shane L

    Reply
  • No horizontal resizing problem here! (Read this)

    Posted by Legacy on 01/16/1999 12:00am

    Originally posted by: Chris Montgomery

    Howdy,

    As for the dialog resizing bug problem - its not really a problem. I have used it in two different applications correctly. To get it to resize correctly just hold down alt and drag the image frame near both horizontal edges. It takes a couple tries to get it exactly right, but it works! No more horizontal dialog growth. ;^)

    - Chris Montgomery

    PS. - This is a great class. I like it.

    Reply
  • Loading, Please Wait ...

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

Top White Papers and Webcasts

  • Live Event Date: May 6, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT While you likely have very good reasons for remaining on WinXP after end of support -- an estimated 20-30% of worldwide devices still are -- the bottom line is your security risk is now significant. In the absence of security patches, attackers will certainly turn their attention to this new opportunity. Join Lumension Vice President Paul Zimski in this one-hour webcast to discuss risk and, more importantly, 5 pragmatic risk mitigation techniques …

  • Ever-increasing workloads and the challenge of containing costs leave companies conflicted by the need for increased processing capacity while limiting physical expansion. Migration to HP's new generation of increased-density rack-and-blade servers can address growing demands for compute capacity while reducing costly sprawl. Sponsored by: HP and Intel® Xeon® processors Intel, the Intel logo, and Xeon Inside are trademarks of Intel Corporation in the U.S. and/or other countries. HP is the sponsor …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds