Link to home
Start Free TrialLog in
Avatar of win32
win32

asked on

Closing a CPropertySheet

I have created a CPropertySheet with some pages, when I press "Cancel", I wan to have a AfxMessageBox("Not all data saved, still cancel ?"), So this is what I've done

BEGIN_MESSAGE_MAP()
ON_WM_CLOSE();
END_MESSAGE_MAP()

void CMyPropertySheet::OnClose() //Overload OnClose
{
 AfxMessageBox("Sure you wanna cancel ?");
}

... Then I implement it in my program
void CMyProgram::ShowSheet()
{
CMyPropertySheet test;
if(test.DoModal() == ID_OK)
{
 Container.SetData(test.GetData());
}

Problem is, I never get the WM_CLOSE in my CPropertySheet ??,,, I don't want to put the OnClose in my CPropertyPages, if I can avoid it.

I can use the OnOk, and OnCancel.. but what do I do with the |X| in the top of the window, I somemone push it, you will leave the sheet, withaout the warning messagebox .. that is the problem
Avatar of Khalid Omar
Khalid Omar
Flag of Jordan image

Hi,

You do not need to override CPropertySheet::OnClose() to implement the requirement. Instead you should override OnCancel() (and OnOK() if needed) member of each CPropertyPage.

I understand that you don't want to put handlers in each CPropertyPage object that you create, this can be avoided by deriving a class from CPropertyPage (call it CBasePage) to override the OnCancel() member to notify the parent property sheet. Then derive all your property pages from the new class. Also, derive a class from CPropertySheet (call it CNewSheet) to provide required handling.

Below are some code snippets of what i'm talking about:

      // BasePage.h
      
      #define UM_CANCEL_RECEIVED            ((UINT)(WM_USER + 0x0101))
      class CBasePage : public CPropertyPage
      {
            ...
            ...
            virtual void OnOK() { }
            virtual void OnCancel();
            ...
            ...
      };
      
      // BasePage.cpp
      
            ...
            ...
      void CBasePage::OnCancel()
      {
            //Notify the parent about the event
            GetParent()->PostMessage(UM_CANCEL_RECEIVED, 0, 0);
      }
            ...
            ...
      
      //NewSheet.h
      class CNewSheet : public CpropertySheet
      {
            afx_msg LRESULT MyHandler(WPARAM wParam, LPARAM lPARAM);
      };
      
      //NewSheet.cpp
      #include "BasePage.h"
      
      //Put this       line in the message map
      ON_MESSAGE(UM_CANCEL_RECEIVED, MyHandler)

      LRESULT CNewSheet::MyHandler(WPARAM /*wParam*/, LPARAM /*lPARAM*/)
      {
            LRESULT lRet = 0;
      
            if(AfxMessageBox("Sure you wanna cancel ?", MB_YESNO | MB_ICONQUESTION) == IDYES)
            {
                  DestroyWindow();
            }
      
            return lRet;
      }

Thanks,
Khalid Omar
Avatar of win32
win32

ASKER

But that does not solve the problem if the user press the |X| in the upper right corner ??
Hi again,

This time I created a test project to test my solution in the first comment. Here is what I did:
  1. Create a class called CNewSheet derived from CPropertySheet.
  2. Create a class called CBasePage derived from CPropertyPage.
  3. I modified the constructor created by class wizard of the CBasePage so that it looks like:
   In the .h file
      CBasePage(UINT uDialogResource = -1);

   In the .cpp file
      CBasePage::CBasePage(UINT uDialogResource) : CPropertyPage(uDialogResource)
      {
            //{{AFX_DATA_INIT(CBasePage)
                  // NOTE: the ClassWizard will add member initialization here
            //}}AFX_DATA_INIT
      }

  4. In class view, right click the CBasePage class and select "Add Virtual function". In the window that pops-up select OnCancel and hit the "Add and Edit" button.
  5. Modify CBasePage::OnCancel() as follows:
      void CBasePage::OnCancel()
      {
            GetParent()->SendMessage(UM_CANCEL_RECEIVED, 0, 0);
      }
  6. Add a definition for UM_CANCEL_RECEIVED to the top of BasePage.h header file as follows:
      #define UM_CANCEL_RECEIVED          ((UINT)(WM_USER + 0x0101))

  7. Goto NewSheet.h and add an include to BasePage.h so that the value of UM_CANCEL_RECEIVED can be seen by all CNewSheet objects.
  8. In class view, right-click the CNewSheet class and select "Add Windows Message Handler ...", in the window that pops-up select WM_CLOSE and hit "Add and Edit"
  9. Modify the CNewSheet::OnClose() function to look lioke the following:
      void CNewSheet::OnClose()
      {
            CancelHandler(0, 0);
      }
  10. Open the NewSheet.h file and add the definition of the CancelHandler function ass follows:
      ...
      ...
      //}}AFX_MSG
      afx_msg LRESULT CancelHandler(WPARAM wParam, LPARAM lPARAM); //This line is new
      DECLARE_MESSAGE_MAP()
      ...
      ...

  11. Open NewSheet.cpp and add the following to the end of the file
      LRESULT CNewSheet::CancelHandler(WPARAM /*wParam*/, LPARAM /*lPARAM*/)
      {
             LRESULT lRet = 0;

             if(AfxMessageBox("Sure you wanna cancel ?", MB_YESNO | MB_ICONQUESTION) == IDYES)
             {
                        EndDialog(IDCANCEL);
             }

             return lRet;
      }
  12. Modify the message map of CNewSheet so that it looks like:
      BEGIN_MESSAGE_MAP(CNewSheet, CPropertySheet)
            //{{AFX_MSG_MAP(CNewSheet)
            ON_WM_CLOSE()
            //}}AFX_MSG_MAP
            ON_MESSAGE(UM_CANCEL_RECEIVED, CancelHandler)
      END_MESSAGE_MAP()

According to the above, I was able to capture all events when the user hits cancel button or hits the |x| button on the title bar.
I can send you the project I was working on to test my comment. Email me if you are interested, my email is <removed>

Thanks,
Khalid Omar
Avatar of win32

ASKER

Ok please mail me the project to cb_priv@hotmail.com I cannot get this to wore, Sure I can debug into the OnCancel in the pages, but the sheet closes anyway, nomatter what I do.
ASKER CERTIFIED SOLUTION
Avatar of Khalid Omar
Khalid Omar
Flag of Jordan image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial