Sliding Dialogs

Introduction

I was fascinated by the motion of dialog box in the Microsoft Windows Media Player 7. When in compact mode, the act of selecting the playlist results in a dialog literally sliding out from behind the main dialog! Therefore, with this code, I present a means for you to include this user interface element in your applications.

Implementing the Code

The key to making this work is the SetTimer and SetWindowPos functions. The following step-by-step demo will illustrate how you can implement this functionality in your own dialog-based applications.
  1. Using the ClassWizard, create a dialog-based application named SlidngDoor
  2. Create a second dialog template resource (the ID is unimportant for this demo)
  3. Using the ClassWizard, create a CDialog-derived class for your new dialog called CChild
  4. Add the following two member variables to your dialog application's class (CSlidingDoorApp)
  5. RECT RectMainWndPos;
    BOOL b_child_hide;
    
  6. Add the following line of code to the application's object's constructor (CSlidingDoorApp::CSlidingDoorApp)
  7. b_child_hide=TRUE;
    
  8. Add the following lines to the main dialog's declaration
  9. CChild Cdlg_child;
    RECT RectMainWndPos;
    
  10. Add an include directive to the top of the dialog's header file (SlidingDoorDlg.h)
  11. Add the following two declarations to the main dialog class (CSlidingDoorDlg)
  12. CChild Cdlg_child;
    RECT RectMainWndPos;
    
  13. Add the following to the CSlidingDoorDlg::OnInitDialog member function
  14. SetWindowPos( NULL,300,300,270,270,SWP_NOZORDER);
    Cdlg_child.Create(IDD_CHILD,this);
    
  15. Using the ClassWizard, add a handler to the CSlidingDoorDlg for the WM_MOVE message and modify it so that when finished the CSlidingDoorDlg::OnMove member function looks like the following. This will take care of repositioning the child dialog in case the user moves the parent dialog.
    void CSlidingDoorDlg::OnMove(int x, int y) 
    {
     CDialog::OnMove(x, y);
    
     // TODO: Add your message handler code here
     ChildWndReposition();
    }
    
  16. Now add the actual repositiong code to the CSlidingDoorDlg class by adding the followingmember function.
  17. void CSlidingDoorDlg::ChildWndReposition()
    {
     CSlidingDoorApp *pApp=(CSlidingDoorApp *)AfxGetApp();
     GetWindowRect(&RectMainWndPos);
     pApp->RectMainWndPos=RectMainWndPos;
    
     if(!pApp->b_child_hide)
     {
      Cdlg_child.SetWindowPos(GetParent(), RectMainWndPos.right, 
      RectMainWndPos.top+20,
      Cdlg_child.m_childwidth,
      Cdlg_child.m_childdepth-2,
      SWP_SHOWWINDOW|SWP_NOOWNERZORDER|SWP_NOACTIVATE );
     }
    }
    
  18. Next, in the CSlidingDoorDlg class add the following call whereever you want the child dialog to slide out from behind the main dialog
  19. Cdlg_child.StartSliding();
    
  20. Add the following member variables to the CChild dialog class
  21. RECT RectMainWndPos;
    
    int m_sizey;
    
    int m_childwidth;
    int m_childdepth;
    
    CSlidingDoorApp *pApp;
    
  22. Add the following initialization code to the CChild::CChild constructor
  23. m_childdepth=248;
    m_childwidth=270;
    
    pApp=(CSlidingDoorApp*)AfxGetApp();
    
  24. Now, you need to implement the Child::StartSliding member function as follows. Note that this function will take care of toggling whether or not it needs to display or hide the child dialog.
    void CChild::StartSliding()
    {
     m_sizey=1;
    
     if(pApp->b_child_hide)
     {	
      pApp->b_child_hide=FALSE;
     }
     else
     {
      pApp->b_child_hide=TRUE;
     }
    
     SetTimer(1,500,NULL);
    }
    
  25. As you saw in the previous CChild member function, a timer is used to "slide" the child dialog out from behind the parent dialog. Using the ClassWizard, add a handler to the CChild dialog class and modify it so that when finished, it looks like the following.
    void CChild::OnTimer(UINT nIDEvent) 
    {
     RectMainWndPos=pApp->RectMainWndPos;
    
     KillTimer(1);
    
     int nWidth=m_childwidth/25;
    
     if(m_childwidth>=m_sizey*nWidth)
     {
      if(!pApp->b_child_hide)
      {	
       SetWindowPos(GetParent() ,RectMainWndPos.left+m_sizey*nWidth,
       RectMainWndPos.top+20,
       m_childwidth,
       m_childdepth-2,
       SWP_SHOWWINDOW|SWP_NOOWNERZORDER|SWP_NOACTIVATE );
      }
      else
      {
       SetWindowPos(GetParent(),RectMainWndPos.left+m_childwidth-m_sizey*nWidth,
       RectMainWndPos.top+20,
       m_childwidth,
       m_childdepth-2,
       SWP_NOOWNERZORDER|SWP_NOACTIVATE);
      }
    
      m_sizey++;
      SetTimer(1,10,NULL);
     }
    
     if(pApp->b_child_hide && m_sizey*nWidth>=m_childwidth)
      ShowWindow(SW_HIDE);
    
     CDialog::OnTimer(nIDEvent);
    }
    

At this point, you should now be enjoying the UI benefits of the sliding dialog! Enjoy!

Downloads

Download demo project - 12 Kb


Comments

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

Top White Papers and Webcasts

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds