I have a nested propertysheets (on some propertypages I have another
propertysheet with pages itself). I have also a XML file of general
settings that I read in OnInitDialog()'s form event.
Some pages of this nested propertysheets have settings that depends
from other pages and of general settings from xml file. Like if I
activate a checkbox in a page I change in the xml file the related
value from 0 to 1 and in the same time I enable the controls in
another page.
I know there's a way to communicate between propertypages from the top
(the dialog form) so it can share also xml file object maybe using
DoDataExchange. But how I can do that?... I tried to read the help of
MSDN but it's like messing me a bit so I'm here asking you...
Thanks to all.
Ciao
Luigi
Looks like you want to change an UI element in one page when state of
your UI changes in another (XML text behind or not, does not matter).
Simplest possible way is to just use a common parent, e.g.:
(I presume that Sheet has Page1 and Page2).
class Sheet: public CPropertySheet
{
public:
Page1 m_Page1;
Page2 m_Page2;
};
Page1::OnSomeButonClicked()
{
STATIC_DOWNCAST(Sheet, GetParent())->m_Page2.StateOfDataItemXChanged
(GetButtonState());
}
Page2::StateOfDataItemXChanged(bool bValue)
{
if (m_hWnd)
{ // m_Page2 was created, too!
someWindow.EnableWindow(bValue);
}
else
{ // m_Page2 wasn't created yet (e.g. user didn't click on it yet)
m_bEnableSomeWindowAtPropertyPageCreationTime = bValue;
}
}
If you have this situation for many data items, or if you don't have a
simple parent sheet-child pages situation, this gets complicated
rather quickly, so then you might want to resort to some elaborated
update mechanics. You would have do that if your underlying data can
change without the knowledge of UI elements you have listed here. But
that seems to be another question.
HTH,
Goran.
LRESULT SomeInternalPage::OnSetValue(WPARAM wParam, LPARAM lParam)
{
return GetParent()->SendMessage(wParam, lParam);
}
and only the top-level window (the property sheet in this case) had handlers that fetched
or restored values, e.g.,
LRESULT CMyPropertySheet::OnSetValue(WPARAM wParam, LPARAM lParam)
{
CString * name = (CString *)wParam;
DataDescriptor * desc = FindData(*name);
if(desc == NULL)
{
ASSERT(FALSE);
return (LRESULT) FALSE;
}
switch(desc->type)
{
case DATA_BOOL:
case DATA_INT:
desc->value.scalar = (int)lParam;
return TRUE;
case DATA_STRING:
desc->value.string = *(CString *)lParam;
return TRUE;
default:
ASSERT(FALSE);
return FALSE;
}
}
In the OnSetActive handler, I would do GetValue calls for all the data the page needed,
and popupate the page's controls; then I'd call updateControls() (see my essay on dialog
control management) to deal with all enabling/disabling/showing/hiding/selecting issues.
On the OnKillActive handler, I would gather all the fields and do a series of SetValue
calls (these are the subroutines in the superclass of all the pages that generated the
SendMessage calls). I used string names for the values because the pages were in fact
created based on the names found in the XML-equivalent input description.
Note that this now handles all the cases, such as checking a check box in page 3 means
that certain controls on page 4 are now active, and changing a value on page 5 causes it
to appear as an editable string on page 6, and if it is edited on page 6, when I switch
back to page 5 the edited value appears. Clean and nicely abstracted.
joe
Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm