第一种方式MFC中有一篇专门的文章介绍了它,先把它列出来:
在大多数对话框中,属性表(CPropertySheet)和应用程序之间的数据交互是属性表最重要的功能之一。这篇文章介绍了怎样实现这个任务。
和属性表交互数据实际上是和属性表中的属性页(CPropertyPage)交互数据,和属性页交互数据的过程和和对话框交互数据的过程是一样的,因为一个CPropertyPage对象是一种特殊的CDialog对象。数据交互过程也使用了框架的DDX(Dialog Data Exchange)机制,这种机制实现了在对话框中的控件和对话框的成员变量中交互数据。
和属性表交互数据与和普通的对话框交互数据有一个很大的不同点是属性表经常会含有多个属性页,因此你必须和属性表中的所有属性页交互数据。
下面的例子显示了如何在一个CView对象和含有两个属性页的属性表中交互数据:
void CMyView::DoModalPropertySheet() { CPropertySheet propsheet; CMyFirstPage pageFirst; // derived from CPropertyPage CMySecondPage pageSecond; // derived from CPropertyPage // Move member data from the view (or from the currently // selected object in the view, for example). pageFirst.m_nMember1 = m_nMember1; pageFirst.m_nMember2 = m_nMember2; pageSecond.m_strMember3 = m_strMember3; pageSecond.m_strMember4 = m_strMember4; propsheet.AddPage(&pageFirst); propsheet.AddPage(&pageSecond); if (propsheet.DoModal() == IDOK) { m_nMember1 = pageFirst.m_nMember1; m_nMember2 = pageFirst.m_nMember2; m_strMember3 = pageSecond.m_strMember3; m_strMember4 = pageSecond.m_strMember4; GetDocument()->SetModifiedFlag(); GetDocument()->UpdateAllViews(NULL); } }上面是MFC中对属性表和属性页中数据交互的介绍,DoModalPropertySheet()函数是一个事件响应函数,可能是一个按钮的响应函数,点击这个按钮后会进行响应,这个函数首先创建了含有两个属性页(这两个属性页都定义了各自单独的类而没有使用MFC中提供的CPropertyPage,这是因为属性页中存在需要传递给应用程序的数据)的属性表,这两个属性页和视图类中各自都定义了一些成员变量,分别如下:
m_nMember1 m_nMember2CMySecondPage 类:
m_nMember1 m_nMember2CMyView类:
m_nMember1 m_nMember2 m_strMember3 m_strMember4程序接下来做的事情是将View类中的成员变量的值赋给属性页中成员变量的值,这样最开始显示属性页时属性页中的控件会默认显示View类中定义的值。接下来将属性页添加到属性表中。
propsheet.DoModal() == IDOK这行代码表示当你点击属性表中的确定按钮时会进行接下来的操作,就是将属性页中新的数据传回应用程序。
afx_msg void OnOk(); afx_msg void OnCancel();然后在CMyPropertySheet.cpp的消息映射中添加:
BEGIN_MESSAGE_MAP( CMyPropertySheet, CPropertySheet) ON_BN_CLICKED(IDOK,OnOk) ON_BN_CLICKED(IDCANCEL,OnCancel) END_MESSAGE_MAP()最后在CMyPropertySheet.cpp中实现它:
void CMyPropertySheet::OnOk(){ //write your code here CPropertySheet::EndDialog(IDOK); } void CMyPropertySheet::OnCancel(){ //write your code here CPropertySheet::OnClose(); }
在属性页和属性表中还有一个小问题,就是如果在上面的OnOk函数中如果有从属性页中获取数据的代码但是这个属性表出现时你没有点击这个属性页,那么实际上属性页这个资源是不会创建的,那么就使用了未创建的对话框资源,程序会报错。
解决的办法就是判断这个属性页是否实际创建了,如果它没有创建就不要尝试从这个属性页中获取数据,这时使用到了m_hWnd这个数据成员。
这时OnOk()函数应该是这个样子:
void CMyPropertySheet::OnOk(){ if(m_propertyPage1.m_hWnd!=NULL){ //get the member value for m_propertyPage1 and do something } if(m_propertyPage2.m_hWnd!=NULL){ //get the member value for m_propertyPage2 and do something } CPropertySheet::EndDialog(IDOK); }