Click here to Skip to main content
15,897,187 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
GeneralTextOut Problem Pin
Raza568024-Jul-05 22:24
Raza568024-Jul-05 22:24 
GeneralRe: TextOut Problem Pin
khan++24-Jul-05 23:28
khan++24-Jul-05 23:28 
QuestionHow to exchange data between property pages? Pin
greenwyx24-Jul-05 22:07
greenwyx24-Jul-05 22:07 
AnswerRe: How to exchange data between property pages? Pin
Marc Soleda24-Jul-05 22:29
Marc Soleda24-Jul-05 22:29 
GeneralRe: How to exchange data between property pages? Pin
greenwyx24-Jul-05 23:12
greenwyx24-Jul-05 23:12 
GeneralRe: How to exchange data between property pages? Pin
Marc Soleda24-Jul-05 23:27
Marc Soleda24-Jul-05 23:27 
GeneralRe: How to exchange data between property pages? Pin
greenwyx24-Jul-05 23:53
greenwyx24-Jul-05 23:53 
AnswerRe: How to exchange data between property pages? Pin
Jose Lamas Rios25-Jul-05 19:00
Jose Lamas Rios25-Jul-05 19:00 
greenwyx wrote:
I want to know how can I exchange data between property pages. For example, suppose I have two property pages. I need to use an edit box named m_edit1 in property page1 to store the value, and read and show it in property page2
How can I tackle the problem?


The best way to make one page access a control in another page is not do it at all.

Pages which are loaded in the same sheet are normally used to display/edit different aspects or parts of a common object. But sometimes one of the pages needs to read or modify something in the object which is shown or edited in another. In my opinion, the best approach in terms of good design is the following:

Suppose you have an instance of some class MyObj with the following public members:
class MyObj
{
public:
   CString m_sA;
   CString m_sB;
   CString m_sC;
 
   // Whatever else you need in the class
   [...]
};

Suppose you have the following classes, each derived from CPropertyPage, named PageA, PageB and PageC, each displaying/editing m_sA, m_sB, and m_sC, respectively. But at some points, PageB needs to read the data in m_sA and PageC needs to modify the data in m_sB.

The solution consists of the following:

In each page:

- The constructor receives a pointer to the instance of MyObj it's being edited and stores it in a member variable of its own (say m_Obj) for later use.
//////////////////////////////////////////////////////
// In the header file
 
class PageA : public CPropertyPage
{
protected:
   MyObj*  m_pObj;
 
   // Here are the variables associated
   // with controls in this page
   // which you normally create through
   // the Class Wizard
   CString m_sA;
 
public:
    PageA(MyObj* pObj);
 
   // Whatever else you need in the class
   [...]
};
 
//////////////////////////////////////////////////////
// In the implementation file
 
PageA::PageA(MyObj* pObj)
: m_pObj(pObj), CPropertyPage(PageA::IDD)
{
}
 
// Whatever else you need in the implementation file
[...].

- OnInitDialog() makes those initializations needed only the first time the page is activated (e.g.: loading options in combos). It doesn't need to set any data into its variables or controls. In this example, in which only a string will be edited through a edit box, there's no need to even override OnInitDialog().
- OnSetActive() loads data from MyObj into the page member variables and controls as needed
BOOL PageA::OnSetActive()
{
   m_sA = m_pObj->m_sA;
   return CPropertyPage::OnSetActive();
}

- OnKillActive() stores the data edited through the page to the object, thus making it available to all other pages:
BOOL PageA::OnKillActive()
{
   if (!CPropertyPage::OnKillActive())
      return FALSE;
   m_pObj->m_sA = m_sA;
}

- If at some point one of the pages needs to read or modify data that is displayed/edited in another page, it just uses the object pointer.
void PageB::OnSomeButtonClicked()
{
   // Let's read m_sA
   if (!m_pObj->m_sA.IsEmpty())
   {
      m_sB = m_pObj->m_sA;
      m_sB += "(came from m_sA)";
   }
}
 
void PageC::OnSomeButtonClicked()
{
   // Let's modify m_sB
   m_pObj->m_sB = "Modified at PageC";
}

As you can see, all the pages have access to all the data (the pointer to the object, which is the same for all the pages) at any point, and are free to read and modiy it as much as they want. Also, since every page reloads its variables and controls each time its activated, and updates the common object with any change that might have occurred in the page each time it gets deactivated, all page are able to keep in sync.

Now, to edit an instance of MyObj you just need something like this (the example shows that you might omit some page[s] based on some condition):
void EditObj(MyObj& obj, BOOL bEditB, BOOL bEditC)
{
   // Make a copy to be edited
   MyObj objCopy = obj;
 
   // Prepare the pages
    PageA(&objCopy);
    PageB(&objCopy);
    PageC(&objCopy);
 
   // Add the pages needed to a sheet
   CPropertySheet sheet(AfxGetMainWnd());
   sheet.AddPage(&PageA);
 
   if (bEditB)
      sheet.AddPage(&PageB);
 
   if (bEditC)
      sheet.AddPage(&PageC);
 
   // Run the dialog
   if (sheet.DoModal() == IDOK)
   {
      // Update object from changes
      // made in dialog
      obj = objCopy;
   }
}

Of course, this can be done in many other ways (e.g.: deriving CPropertySheet and making the pages access its variables or functions, sending or posting messages, etc.), but keep in mind that the approach I'm suggesting offers the following beneficial characteristics:
- You don't need to create a specialized property sheet.
- Your pages don't need to know about any specialized property sheet, and don't depend on the property sheet being of any specific class (they can be used with any sheet.)
- Your pages don't need to know about any of the other pages, and they don't depend on the other pages being present or being of any specific class.
- You can modify any page without affecting anything else.
- You can incorporate more pages without affecting anything else.
- The pattern is simple to understand and easy to maintain.

This pattern can be used in any situation involving property pages, even if you don't need to read or modify data being edited in other pages. However, if that weren't the case, I'd suggest each page received exactly what it needs to access and nothing else. For example, PageA could just receive a pointer or reference to the string it's intended to edit, instead of a pointer to a complete object. This would only affect the creation of that page but you wouldn't need to modify the other pages or the way they are used:
void EditObj(MyObj& obj, BOOL bEditB, BOOL bEditC)
{
   // Make a copy to be edited
   MyObj objCopy = obj;
 
   // Prepare the pages
    PageA(&objCopy.m_sA); // this is the only change needed
    PageB(&objCopy);
    PageC(&objCopy);
 
   // Add the pages needed to a sheet
   CPropertySheet sheet(AfxGetMainWnd());
   sheet.AddPage(&PageA);
 
   if (bEditB)
      sheet.AddPage(&PageB);
 
   if (bEditC)
      sheet.AddPage(&PageC);
 
   // Run the dialog
   if (sheet.DoModal() == IDOK)
   {
      // Update object from changes
      // made in dialog
      obj = objCopy;
   }

In fact, once you've done that, your PageA, which was designed to edit some kind of string (say a filepath, a telephone number, an e-mail address, or whatever m_sA in the example represented), can be used anywhere you need that kind of page for any object, with any CPropertySheet, and in conjunction with any other property page. That's what a loosely-coupled design means.


--
jlr
http://jlamas.blogspot.com/[^]
GeneralRe: How to exchange data between property pages? Pin
greenwyx28-Jul-05 3:22
greenwyx28-Jul-05 3:22 
GeneralRe: How to exchange data between property pages? Pin
Jose Lamas Rios28-Jul-05 3:38
Jose Lamas Rios28-Jul-05 3:38 
GeneralHiding Maximize Button Pin
jinbabaj24-Jul-05 21:30
jinbabaj24-Jul-05 21:30 
GeneralRe: Hiding Maximize Button Pin
Marc Soleda24-Jul-05 21:49
Marc Soleda24-Jul-05 21:49 
GeneralRe: Hiding Maximize Button Pin
Jose Lamas Rios24-Jul-05 21:52
Jose Lamas Rios24-Jul-05 21:52 
QuestionShowing bitmap in picture control? Pin
Member 341989124-Jul-05 20:08
Member 341989124-Jul-05 20:08 
AnswerRe: Showing bitmap in picture control? Pin
Andrew Kirillov24-Jul-05 20:32
Andrew Kirillov24-Jul-05 20:32 
GeneralRe: Showing bitmap in picture control? Pin
Member 341989124-Jul-05 21:14
Member 341989124-Jul-05 21:14 
GeneralRe: Showing bitmap in picture control? Pin
Andrew Kirillov24-Jul-05 21:21
Andrew Kirillov24-Jul-05 21:21 
GeneralRe: Showing bitmap in picture control? Pin
Member 341989124-Jul-05 22:18
Member 341989124-Jul-05 22:18 
GeneralSpyware Detection Pin
Adeel68824-Jul-05 20:01
Adeel68824-Jul-05 20:01 
GeneralRe: Spyware Detection Pin
Alexander M.,25-Jul-05 9:00
Alexander M.,25-Jul-05 9:00 
GeneralShellExecute Pin
Usman Tasleem Akshaf24-Jul-05 18:50
Usman Tasleem Akshaf24-Jul-05 18:50 
GeneralRe: ShellExecute Pin
Jose Lamas Rios24-Jul-05 20:08
Jose Lamas Rios24-Jul-05 20:08 
GeneralRe: ShellExecute Pin
Jose Lamas Rios24-Jul-05 20:32
Jose Lamas Rios24-Jul-05 20:32 
GeneralRe: ShellExecute Pin
Usman Tasleem Akshaf24-Jul-05 22:11
Usman Tasleem Akshaf24-Jul-05 22:11 
GeneralRe: ShellExecute Pin
khan++25-Jul-05 0:41
khan++25-Jul-05 0:41 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.