Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / MFC

How to implement a resizable property sheet class that contains a menu bar in Visual C++ 6.0

5.00/5 (3 votes)
25 Jun 2011CPOL 17.9K  
Link to How to implement a resizable property sheet class that contains a menu bar in Visual C++ 6.0
This linked proved pretty useful to me, so I am just sharing it with the rest of you folks:

http://support.microsoft.com/kb/300606[^]

Following is just a summary in codes:
How to implement a resizable property sheet class that contains a menu bar in Visual C++ 6.0.

// This function must be a STATIC member function.
//Callback to allow us set the default window styles
//    for the property sheet
int CALLBACK CMyPropertySheet::XmnPropSheetCallback(HWND hWnd, UINT message, LPARAM lParam)
{
   extern int CALLBACK AfxPropSheetCallback(HWND, UINT message, LPARAM lParam);
   // XMN: Call MFC's callback
   int nRes = AfxPropSheetCallback(hWnd, message, lParam);

   switch (message)
   {
   case PSCB_PRECREATE:
      // Set our own window styles
      ((LPDLGTEMPLATE)lParam)->style |= (DS_3DLOOK | DS_SETFONT
         | WS_THICKFRAME | WS_SYSMENU | WS_POPUP | WS_VISIBLE | WS_CAPTION);
      break;
   }
   return nRes;
}


// Overriding DoModal() allows us to hook our callback into
//    the prop sheet creation
int CMyPropertySheet::DoModal()
{
   // Hook into property sheet creation code
   AFX_OLDPROPSHEETHEADER* psh = GetPropSheetHeader();
   psh->dwFlags |= PSH_USECALLBACK;
   psh->pfnCallback = XmnPropSheetCallback;
   return CPropertySheet::DoModal();
}


BOOL CMyPropertySheet::OnInitDialog() 
{
   BOOL bResult = CPropertySheet::OnInitDialog();
    
   // Add a new menu
   CMenu *pMenu = new CMenu; pMenu->LoadMenu(IDR_PS_MENU);
   SetMenu(pMenu);
   // Adjust propsheet size to account for the new menu
   CRect r;  GetWindowRect(&r);
   r.bottom += GetSystemMetrics(SM_CYMENU);
   MoveWindow(r);
   return bResult;
}

Add the following data members to the CMyPropertySheet class:
CSS
protected:
   BOOL   m_bNeedInit;
   CRect  m_rCrt;
   int    m_nMinCX;
   int    m_nMinCY


CMyPropertySheet::CMyPropertySheet(CWnd* pWndParent)
     : CPropertySheet(IDS_PROPSHT_CAPTION, pWndParent)
     , m_bNeedInit(TRUE)
     , m_nMinCX(0)
     , m_nMinCY(0)
{
   AddPage(&m_Page1);
   AddPage(&m_Page2);

}


BOOL CMyPropertySheet::OnInitDialog() 
{
   // ...
   // Init m_nMinCX/Y
   m_nMinCX = r.Width();
   m_nMinCY = r.Height();
   // After this point we allow resize code to kick in
   m_bNeedInit = FALSE;
   GetClientRect(&m_rCrt);
   return bResult;
}


// Handle WM_SIZE events by resizing the tab control and by 
//    moving all the buttons on the property sheet.
void CMyPropertySheet::OnSize(UINT nType, int cx, int cy) 
{
   CRect r1; 
   CPropertySheet::OnSize(nType, cx, cy);
   if (m_bNeedInit)
      return;
   CTabCtrl *pTab = GetTabControl();
   ASSERT(NULL != pTab && IsWindow(pTab->m_hWnd));
    
   int dx = cx - m_rCrt.Width();
   int dy = cy - m_rCrt.Height();
   GetClientRect(&m_rCrt);
   HDWP hDWP = ::BeginDeferWindowPos(5);
   pTab->GetClientRect(&r1); 
   r1.right += dx; r1.bottom += dy;
   ::DeferWindowPos(hDWP, pTab->m_hWnd, NULL,
                    0, 0, r1.Width(), r1.Height(),
                    SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
   // Move all buttons with the lower right sides
   for (CWnd *pChild = GetWindow(GW_CHILD);
        pChild != NULL;
        pChild = pChild->GetWindow(GW_HWNDNEXT))
   {
      if (pChild->SendMessage(WM_GETDLGCODE) & DLGC_BUTTON)
      {
         pChild->GetWindowRect(&r1); ScreenToClient(&r1); 
         r1.top += dy; r1.bottom += dy; r1.left+= dx; r1.right += dx;
         ::DeferWindowPos(hDWP, pChild->m_hWnd, NULL,
                          r1.left, r1.top, 0, 0,
                          SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
      }
      // Resize everything else...
      else
      {
         pChild->GetClientRect(&r1); 
	 r1.right += dx; r1.bottom += dy;
	 ::DeferWindowPos(hDWP, pChild->m_hWnd, NULL, 0, 0, 
         r1.Width(), r1.Height(),SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
      }
   }
   ::EndDeferWindowPos(hDWP);
}


C#
void CMyPropertySheet::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
   CPropertySheet::OnGetMinMaxInfo(lpMMI);
   lpMMI->ptMinTrackSize.x = m_nMinCX;
   lpMMI->ptMinTrackSize.y = m_nMinCY;
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)