Hi Peter,
The code below shows how we are populating controls on a dialog builder dialog by loading and saving settings to and from an XML file. It should work with the resource files in the v75SR5 OriginPro\Samples\Programming\User Interface Development\Dialog Builder\Tabs subfolder. As you will see we rely on node IDs for two reasons:
1. Tree structure may change over time but IDs can remain same.
2. At least for GetN dialogs, a direct load/save from an xml file by node name causes complications when dialog event handler's exist. See last post in http://beta.originlab.com/forum/topic.asp?TOPIC_ID=1402 for GetN example.
In v75 you must set the node ID using the TreeNode class SetAttribute member function but in v8 this has been simplified.
This is fairly new stuff and will be in v8 documentation.
Gary
OriginLab
/*------------------------------------------------------------------------------*
* File Name: Tabs.cpp *
* Creation: GJL 11/11/03 *
* Purpose: OriginC Source CPP file containing sample code for the Tabs Dialog *
* Builder example. *
* Copyright (c) OriginLab Corp. 2003, 2004, 2005, 2006, 2007 *
* *
* Modification Log: *
* EJP 2005-03-03 ADD_DATA_TREE *
*------------------------------------------------------------------------------*/
#include <Origin.h>
#include <Dialog.h>
#include "TabsRes.h"
class TabSheet;
// Base Tab class
class Tab : public PropertyPage
{
public:
// Constructor for base Tab class
Tab(int nID) : PropertyPage(nID) {}
// Event handler when Tab becomes active (inherited by all Tab derived classes)
BOOL OnActiveTab()
{
int iTabNum = GetID() - IDD_FIRSTTAB + 1;
printf("Tab%d Active\n", iTabNum);
return TRUE;
}
/// EJP 2005-03-03 ADD_DATA_TREE
BOOL InitTab(int nID, TabSheet *pSheet)
{
SetID(nID);
m_pSheet = pSheet;
return TRUE;
}
TabSheet *m_pSheet;
/// end ADD_DATA_TREE
};
// Derived Tab class for Tab1
class Tab1 : public Tab
{
public:
// Constructor for Tab1 class
Tab1(int nID) : Tab(nID) { }
// InitMsgMap function setting up event handler map for Tab1
EVENTS_BEGIN
PAGE_ON_INIT(OnInitTab)
PAGE_ON_ACTIVE(OnActiveTab)
ON_BN_CLICKED(IDC_BUTTON1, OnClickToggleButton)
EVENTS_END
// Event handlers for Tab1
BOOL OnInitTab()
{
out_str("Tab1 Init");
m_btnCheckBox = GetItem(IDC_CHECK1);
m_btnCheckBox.Check = 1;
/// EJP 2005-03-03 ADD_DATA_TREE
UpdateData(FALSE); // FALSE = data to dialog
/// end ADD_DATA_TREE
return TRUE;
}
BOOL OnClickToggleButton(Control ctrl)
{
out_str("Click Toggle Button");
m_btnCheckBox.Check = mod(m_btnCheckBox.Check + 1, 2);
return TRUE;
}
/// EJP 2005-03-03 ADD_DATA_TREE
BOOL UpdateData(BOOL bDialogToData=TRUE)
{
if( bDialogToData )
{
if( m_btnCheckBox )
m_pSheet->m_tnData.Tab1.CheckBox.nVal = m_btnCheckBox.Check;
}
else // data to dialog
{
int n;
if( m_btnCheckBox )
{
if( m_pSheet->m_tnData.Tab1.CheckBox )
n = m_pSheet->m_tnData.Tab1.CheckBox.nVal;
else
n = 0; // lets have our internal default be off
m_btnCheckBox.Check = n;
}
}
return TRUE;
}
/// end ADD_DATA_TREE
// Data member controls on Tab1
Button m_btnCheckBox;
};
// Derived Tab class for Tab2
class Tab2 : public Tab
{
public:
// Constructor for Tab2 class
Tab2(int nID) : Tab(nID) {}
// InitMsgMap function setting up event handler map for Tab2
EVENTS_BEGIN
PAGE_ON_INIT(OnInitTab)
PAGE_ON_ACTIVE(OnActiveTab)
ON_BN_CLICKED(IDC_BUTTON2, OnClickUpperCaseButton)
EVENTS_END
// Event handlers for Tab2
BOOL OnInitTab()
{
out_str("Tab2 Init");
m_ebxText = GetItem(IDC_EDIT1);
/// EJP 2005-03-03 ADD_DATA_TREE
UpdateData(FALSE); // FALSE = data to dialog
/// end ADD_DATA_TREE
return TRUE;
}
BOOL OnClickUpperCaseButton(Control ctrl)
{
out_str("Click Upper Case Button");
m_ebxText.Text.MakeUpper();
return TRUE;
}
/// EJP 2005-03-03 ADD_DATA_TREE
BOOL UpdateData(BOOL bDialogToData=TRUE)
{
if( bDialogToData )
{
if( m_ebxText )
m_pSheet->m_tnData.Tab2.EditBox.strVal = m_ebxText.Text;
}
else // data to dialog
{
string str;
if( m_ebxText )
{
if( m_pSheet->m_tnData.Tab2.EditBox )
str = m_pSheet->m_tnData.Tab2.EditBox.strVal;
m_ebxText.Text = str;
}
}
return TRUE;
}
/// end ADD_DATA_TREE
// Data member controls on Tab2
Edit m_ebxText;
};
// Derived Tab class for Tab3
class Tab3 : public Tab
{
public:
// Constructor for Tab3 class
Tab3(int nID) : Tab(nID) { }
// InitMsgMap function setting up event handler map for Tab3
EVENTS_BEGIN
PAGE_ON_INIT(OnInitTab)
PAGE_ON_ACTIVE(OnActiveTab)
ON_BN_CLICKED(IDC_BUTTON3, OnClickOutputButton)
EVENTS_END
// Event handlers for Tab3
BOOL OnInitTab()
{
out_str("Tab3 Init");
m_cmbxStooges = GetItem(IDC_COMBO1);
m_cmbxStooges.SetCurSel(0);
/// EJP 2005-03-03 ADD_DATA_TREE
UpdateData(FALSE); // FALSE = data to dialog
/// end ADD_DATA_TREE
return TRUE;
}
BOOL OnClickOutputButton(Control ctrl)
{
out_str("Click Output Button");
string str;
m_cmbxStooges.GetLBText(m_cmbxStooges.GetCurSel() ,str);
str.Format("You selected %s.",str);
str.Write(WRITE_MESSAGE_BOX);
return TRUE;
}
/// EJP 2005-03-03 ADD_DATA_TREE
BOOL UpdateData(BOOL bDialogToData=TRUE)
{
if( bDialogToData )
{
if( m_cmbxStooges )
m_pSheet->m_tnData.Tab3.ComboBoxSel.nVal = m_cmbxStooges.GetCurSel();
}
else // data to dialog
{
int n;
if( m_cmbxStooges )
{
if( m_pSheet->m_tnData.Tab3.ComboBoxSel )
n = m_pSheet->m_tnData.Tab3.ComboBoxSel.nVal;
m_cmbxStooges.SetCurSel(n);
}
}
return TRUE;
}
/// end ADD_DATA_TREE
// Data member controls on Tab3
ComboBox m_cmbxStooges;
};
// Tab place holder class
class TabSheet : public PropertySheet
{
public:
// Constructor for PropertySheet class
TabSheet()
{
/// EJP 2005-03-03 ADD_DATA_TREE
///m_Tab1.SetID(IDD_FIRSTTAB);
///m_Tab2.SetID(IDD_SECONDTAB);
///m_Tab3.SetID(IDD_THIRDTAB);
m_Tab1.InitTab(IDD_FIRSTTAB, this);
m_Tab2.InitTab(IDD_SECONDTAB, this);
m_Tab3.InitTab(IDD_THIRDTAB, this);
/// end ADD_DATA_TREE
AddPage(m_Tab1);
AddPage(m_Tab2);
AddPage(m_Tab3);
}
// Initialize message maps for each Tab
void InitMaps()
{
m_Tab1.InitMsgMap();
m_Tab2.InitMsgMap();
m_Tab3.InitMsgMap();
}
/// EJP 2005-03-03 ADD_DATA_TREE
BOOL UpdateData()
{
m_Tab1.UpdateData();
m_Tab2.UpdateData();
m_Tab3.UpdateData();
return TRUE;
}
// The data used to init and get the settings from each tab
// will be kept in a tree node.
TreeNode m_tnData;
/// end ADD_DATA_TREE
// Data members of PropertySheet are Tab objects
Tab1 m_Tab1;
Tab2 m_Tab2;
Tab3 m_Tab3;
};
// Main dialog class
class TabbedDialog : public Dialog
{
public:
// Constructor for main Dialog
TabbedDialog(int ID) : Dialog(ID, "Tabs.DLL")
{
SetResizingStyle(RESIZE_DEPENDENCY_DOMINANT_DIALOG);
}
// Function to launch main Dialog
int TabsDoModal(HWND hWnd)
{
InitMsgMap();
return DoModal(hWnd, DLG_MODAL_WITH_KEY);
}
// InitMsgMap function setting up event handlers for main Dialog
EVENTS_BEGIN
PAGE_ON_INIT(Init)
PAGE_ON_OK(OnClickOk)
PAGE_ON_CANCEL(OnClickCancel)
EVENTS_END
// Event handlers for main Dialog
BOOL Init()
{
out_str("Tabbed Dialog Init");
m_Sheet.Create(IDC_TAB_PLACEHOLDER, *this);
m_Sheet.InitMaps();
return TRUE;
}
BOOL OnClickOk()
{
out_str("Click OK Button");
m_Sheet.UpdateData();
return TRUE;
}
BOOL OnClickCancel()
{
out_str("Click Cancel Button");
return TRUE;
}
/// EJP 2005-03-03 ADD_DATA_TREE
BOOL SetData(TreeNode &tnData)
{
m_Sheet.m_tnData = tnData;
return TRUE;
}
/// end ADD_DATA_TREE
// Data member of main Dialog is PropertySheet (place holder)
TabSheet m_Sheet;
};
// The following IDs are used for the tree nodes that will hold
// our dialog settings.
#define ID_TAB1_CHECKBOX 100
#define ID_TAB2_EDITBOX 200
#define ID_TAB3_COMBOBOXSEL 300
// Function to launch main Tabs dialog
void Tabs()
{
/// EJP 2005-03-03 ADD_DATA_TREE
Tree trData;
TreeNode tnTab;
tnTab = trData.AddNode("Tab1");
tnTab.AddNumericNode(0, "CheckBox");
tnTab.CheckBox.SetAttribute("DataID", ID_TAB1_CHECKBOX);
tnTab = trData.AddNode("Tab2");
tnTab.AddTextNode("Enter Text to Upper Case", "EditBox");
tnTab.EditBox.SetAttribute("DataID", ID_TAB2_EDITBOX);
tnTab = trData.AddNode("Tab3");
tnTab.AddNumericNode(0, "ComboBoxSel");
tnTab.ComboBoxSel.SetAttribute("DataID", ID_TAB3_COMBOBOXSEL);
// Save and load the dialog settings from a file in the user's path.
string strDlgSettingsFileName;
strDlgSettingsFileName = GetAppPath() + "SampleTabDlgSettings.xml";
// When you save and load tree settings by ID you can make changes to node names
// in the future and still be able to load older setting files.
vector<int> vnIDs;
vector<string> vsValues;
if( tree_read_values_with_ids(strDlgSettingsFileName, vnIDs, vsValues) )
tree_set_values_by_ids(trData, vnIDs, vsValues);
// Show tree contents before dialog
out_tree(trData);
/// end ADD_DATA_TREE
TabbedDialog tdlg(IDD_TABS);
tdlg.SetData(trData);
tdlg.TabsDoModal(GetWindow());
/// EJP 2005-03-03 ADD_DATA_TREE
// Show tree contents after dialog
out_tree(trData);
tree_get_values_with_ids(trData, vnIDs, vsValues);
tree_save_values_with_ids(strDlgSettingsFileName, vnIDs, vsValues);
/// end ADD_DATA_TREE
}
Edited by - Gary Lane on 04/13/2005 08:58:56 AM