How do I create one of those neato expanding dialogs?

Here's one technique I've used successfully in the past:

Step 1

Create a static frame, shrunk to a line, where you want the break between the unexpanded and expanded versions of the dialog. I've found that these kind of dialogs look nicer if there's a line between the normal and "extra" bits, but you could always make the divider invisible if it bothers you. Let's call our static IDC_DIVIDER.

Step 2

Declare some variables in the dialog class to hold the sizes for your dialog (the separate X sizes aren't actually required for this example, I only include them for completeness, and to show that the code can be adapted for dialogs which expand in X or Y).

long m_lDlgXSizeLarge;
long m_lDlgYSizeLarge;
long m_lDlgXSizeSmall;
long m_lDlgYSizeSmall;
BOOL m_bExtrasVisible;

Step 3

In the OnInitDialog handler for your dialog, add the following code:

RECT  rectLarge;
RECT rectDivider;

GetWindowRect (&rectLarge);
GetDlgItem (IDC_DIVIDER) -> GetWindowRect (&rectDivider);

m_lDlgXSizeLarge = (rectLarge.right - rectLarge.left) + 1;
m_lDlgYSizeLarge = (rectLarge.bottom - rectLarge.top) + 1;
m_lDlgXSizeSmall = m_lDlgXSizeLarge;
m_lDlgYSizeSmall = m_lDlgYSizeLarge  - (rectLarge.bottom - rectDivider.top);
      
HideExtraBits (TRUE); // sets initial state of extras to HIDDEN.

So you can see the code is effectively saving the expanded and unexpanded sizes for the dialog, based upon the coordinates of the divider static, without saving any absolute screen positions.

Step 4

Add a button which when pressed, toggles the hide state as follows:

void CMyDlg::OnExtras()
{
   HideExtraBits (m_bExtrasVisible);
}

Step 5

And finally, here's the function which does the hiding and showing:

void CMyDlg::HideExtraBits (BOOL bHide)
{
   if (bHide)
   {
      SetWindowPos (NULL,
                    0, 0,
                    m_lDlgXSizeSmall,
                    m_lDlgYSizeSmall,
                    SWP_NOZORDER|SWP_NOMOVE);
      // Add extra code here to change the legend on your
      // show-hide button if wanted.
   }
   else
   {
      SetWindowPos (NULL,       
                    0, 0,
                    m_lDlgXSizeLarge,
                    m_lDlgYSizeLarge,
                    SWP_NOZORDER|SWP_NOMOVE);
      // Add extra code here to change the legend on your
      // show-hide button if wanted.
   }
   m_bExtrasVisible = !bHide;
}

The nice thing about this approach is that it allows you to re-layout the dialog without any changes to the code that does the re-sizing, since it just picks up its coordinates at runtime from the static divider. You may wish to add extra code to ensure that an expanded dialog will always fit entirely on the screen: that's left as an exercise for the reader.

Download