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.Get Data());
}
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
BEGIN_MESSAGE_MAP()
ON_WM_CLOSE();
END_MESSAGE_MAP()
void CMyPropertySheet::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.Get
}
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
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(uDialogResou rce)
{
//{{AFX_DATA_INIT(CBasePag e)
// 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(U M_CANCEL_R ECEIVED, 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(W PARAM /*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(CNewShee t, CPropertySheet)
//{{AFX_MSG_MAP(CNewSheet)
ON_WM_CLOSE()
//}}AFX_MSG_MAP
ON_MESSAGE(UM_CANCEL_RECEI VED, 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
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(uDialogResou
{
//{{AFX_DATA_INIT(CBasePag
// 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(U
}
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(W
{
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(CNewShee
//{{AFX_MSG_MAP(CNewSheet)
ON_WM_CLOSE()
//}}AFX_MSG_MAP
ON_MESSAGE(UM_CANCEL_RECEI
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
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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(U
}
...
...
//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_RECEI
LRESULT CNewSheet::MyHandler(WPARA
{
LRESULT lRet = 0;
if(AfxMessageBox("Sure you wanna cancel ?", MB_YESNO | MB_ICONQUESTION) == IDYES)
{
DestroyWindow();
}
return lRet;
}
Thanks,
Khalid Omar