Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Card Dialog

0.00/5 (No votes)
19 Jan 2000 1  
An auto-sizing dialog used to store and display smaller child dialogs.

In a recent project that uses a visual framework, I needed an overlapped dialog that is always present and whose contents (child controls and their layout) are changing depending on the currently selected view or a tab. Instead of creating several independent dialogs and choosing which one will be visible, I designed a so-called card dialog.

Card dialog is an empty standard dialog box. It contains a list of cards (child dialogs). Depending on the application, one of the cards is visible and enabled. In addition, card dialog will resize itself to the size of the card. Several virtual functions enable the programmer to initialize the card when it is created / destroyed or when it is (de)activated.

Step 1:

Create an empty dialog resource (this will be a card dialog). The size is not important. It should be empty (no controls) since its client area will be covered with one of the cards. Create a corresponding class using ClassWizard. If you intend to use it as a modal dialog then create OnInitDialog handler.

Step 2:

Create a separate dialog resource for each card. Dialog resource should have the following styles:

  • Child dialog
  • No border
  • No caption
  • Disabled
  • Not visible

Place any controls that you need on each dialog. Using ClassWizard, create a corresponding class. This class must be derived from TCard. TCard class does not have any special implementation. Its only intention is to prevent closing of the card when the user presses Enter or Escape (TCard::OnOK() and TCard::OnCancel() have empty implementation).

Step 3:

Initialize the card dialog by adding the cards. Here is the sample (for a modeless card dialog):

// Create a modeless card dialog

m_CardDialog.Create(IDD_CARD_DIALOG, this);

// Add cards

m_CardDialog.AddCard(IDD_CARD_ONE);
m_CardDialog.AddCard(IDD_CARD_TWO);
m_CardDialog.AddCard(IDD_CARD_THREE);

// Show third card

m_CardDialog.ShowCard(IDD_CARD_THREE);

// Show card dialog

m_CardDialog.ShowWindow(SW_SHOW);

If TCardDialog::ShowCard() is not called, card dialog will display the first card.

Previous sample uses TCardDialog::AddCard(UINT nId) to add a card (nId is a card resource ID). In this case, AddCard() will call a virtual function TCardDialog::CreateCard(UINT nId) that ASSERTs. So, m_CardDialog must be an instance of a class derived from TCardDialog that implements the function CreateCard() in the following manner:

CDialog *CCardDialog::CreateCard(UINT nId)
{
  switch (nId) {
    case IDD_CARD_ONE: return new CCardOne; // CCardOne is derived from TCard

    case IDD_CARD_TWO: return new CCardTwo; // CCArdTwo is derived from TCard

    ....
  }
      return NULL;
}

The alternative solution is to use TCardDialog::AddCard(UINT nId, TCard *pDialog) where pDialog is an instance of a class derived from TCard and created with new. Actual dialog should not be created. Sample:

// Create a modeless card dialog

m_CardDialog.Create(IDD_CARD_DIALOG, this);

// Add cards

m_CardDialog.AddCard(IDD_CARD_ONE, new CCardOne);
m_CardDialog.AddCard(IDD_CARD_TWO, new CCardTwo);
m_CardDialog.AddCard(IDD_CARD_THREE, new CCardThree);

// Show third card

m_CardDialog.ShowCard(IDD_CARD_THREE);

// Show card dialog

m_CardDialog.ShowWindow(SW_SHOW);

In this case, m_CardDialog can be an instance of TCardDialog since virtual function CreateCard() will not be called.

When a card (dialog) is created, TCardDialog will call virtual function TCardDialog::OnCardCreated(). Before the card is destroyed, TCardDialog will call virtual function TCardDialog::OnCardDestroyed(). These 2 virtual functions enable the derived class to perform initialization of the cards.

Step 4:

In order to switch the active card, call the following function:

m_CardDialog.ShowCard(IDD_CARD_TWO);

You can obtain a pointer to the currently active card with:

CDialog *pDialog = m_CardDialog.GetCard();

TCardDialog::ShowCard() will call virtual function TCardDialog::CanShowCard() to check whether it is allowed to change the active card. Once the active card is changed, TCardDialog will call virtual function TCardDialog::OnShowCard() first for deactivated card and then for activated one. These 2 virtual functions enable a derived class to perform additional tasks related to cards.

I hope that you will find this class useful.

Latest version may be downloaded from http://www.scasoftware.com/.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here