1:在对话框资源里插入 PropertyPage_Large, 对应生成的类的基类 是 CPropertyPage;按照需要在对话框资源里建立几个page,并生成相应的类!
2, 建立容纳各个属性页的表单, 即CPropertySheet。 这个新类的加入可以从 插入新类-》MFC class,基类为 CPropertySheet。
3,在 CPropertySheet 里添加 所有 page类的成员变量,比如 CPropage1 m_page1; CPropage2 m_page2;
在此类的构造函数里 添加 AddPage(&m_page1); AddPage(&m_page2)。
-------------------如果出现无法读取内存的情况时,请特别注意,CPropertySheet类有3个构造函数,每一个里面都需要加上AddPage(&m_page1); AddPage(&m_page2)的代码!!
----------------------当然也可以不在这一步添加属性页的add函数,如果不是在第四步就用的话,可以在第五步的视图类里面去加,比如第五步贴的这些代码!
4,如果是把属性表单作为对话框弹出来或者是向导型的,那么在视图类里的菜单响应函数里添加一下代码:
CPropSheet propSheet("属性表单窗口");
propSheet.DoModal();
即可!
5. 如果是要把属性表单的对话框嵌入到FormView 里去,就必须添加一个新的基于对话框的FormView类,然后在该类的OnCreat)和OnSIze里添加函数:
class CFormviewPropertyView: public CFormView。
方法一:(此 FormView 具有 enum { IDD = IDD_FORMVIEW1 })
int CFormviewPropertyView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFormView::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here CRect rect; GetWindowRect(&rect); m_sheet.AddPage(&m_page1); m_sheet.AddPage(&m_page2); m_sheet.Create(this,WS_CHILD|WS_VISIBLE,0); m_sheet.ModifyStyleEx(0,WS_TABSTOP); m_sheet.SetWindowPos(NULL,0,0,rect.right-rect.left,rect.bottom-rect.top,SWP_NOACTIVATE); CTabCtrl* m_tabctrl=m_sheet.GetTabControl( ); m_tabctrl->SetWindowPos(NULL,0,0,rect.right-rect.left,rect.bottom-rect.top,SWP_NOACTIVATE); return 0; }
你在OnSize也中加上 m_sheet.SetWindowPos(NULL,0,0,cx,cy,SWP_NOACTIVATE); CTabCtrl* m_tabctrl=m_sheet.GetTabControl( );// m_tabctrl->SetWindowPos(NULL,0,0,cx,cy,SWP_NOACTIVATE);//注意这种方法里的 m_page1和m_page2的作为成员变量的定义是 CPropage1 m_page1; CPropage2 m_page2;表单作为成员变量的定义是 CProSheet m_sheet; 这里面还使用了额外的控件 CTabCtrl。
上面的代码链接是:http://bbs.csdn.net/topics/10186019
///////////////////////////////////////////////////////////////////////////////////////////////////////////
方法二:(此 FormView 没有 enum { IDD = IDD_FORMVIEW1 },我觉得是将原来的此句删掉而得到的)
如果是要把属性表单的对话框嵌入到一个窗口视图里面去(class CSnapView : public CFormView),请参见 http://msdn.microsoft.com/en-us/5177d4dw(v=vs.71),即SnapVW的情况。需要在视图类的creat()和Onsize里面添加一下的代码:
BOOL CSnapView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) { //ENSURE(pParentWnd != NULL); ASSERT_KINDOF(CFrameWnd, pParentWnd); if (!CWnd::Create(lpszClassName, lpszWindowName, dwStyle | WS_CLIPCHILDREN, rect, pParentWnd, nID, pContext)) { return FALSE; } // add your pages here! m_pPageBkfst = new CBkfstPage; //注意是在这里new了一下! m_pPageLunch = new CLunchPage; m_pPageDinner = new CDinnerPage; // create the window object m_pPropSheet = new CSnapPropertySheet; m_pPropSheet->AddPage(m_pPageBkfst); m_pPropSheet->AddPage(m_pPageLunch); m_pPropSheet->AddPage(m_pPageDinner); // create a modeless property page if (!m_pPropSheet->Create(this, DS_CONTEXTHELP | DS_SETFONT | WS_CHILD | WS_VISIBLE)) { DestroyWindow(); return FALSE; } m_pPropSheet->SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE); // we use the style from the template - but make sure that // the WS_BORDER bit is correct. // the WS_BORDER bit will be whatever is in dwRequestedStyle m_pPropSheet->ModifyStyle(WS_BORDER|WS_CAPTION, dwStyle & (WS_BORDER|WS_CAPTION)); // Force the size requested. // Fake a call to OnSize()--it would have been called automatically // if this were using the base class implementation of Create(). CFrameWnd* pParentFrame = GetParentFrame(); CRect rectSize; m_pPropSheet->GetWindowRect(rectSize); pParentFrame->CalcWindowRect(rectSize); OnSize(SIZE_RESTORED, rectSize.Width(), rectSize.Height()); return TRUE; }
void CSnapView::OnSize(UINT nType, int cx, int cy) { if (nType != SIZE_MINIMIZED && cx != 0 && cy != 0 && m_pPropSheet != NULL) { if (m_bSizedBefore == FALSE) { m_bSizedBefore = TRUE; // get the size of the property sheet CRect rectSized; m_pPropSheet->GetWindowRect(rectSized); // calculate the size of the frame CFrameWnd* pFrame = GetParentFrame(); if (pFrame != NULL) { pFrame->CalcWindowRect(rectSized); CWnd* pParent = pFrame->GetParent(); if (pParent != NULL) pParent->ScreenToClient(rectSized); // resize and reposition the frame pFrame->MoveWindow(rectSized); } } } }
CPropertySheet* m_pPropSheet; 定义指针时就需要自己new 来分配空间!
方法一经过了实验,是可行的!
方法二没有实验,需要验证!
6,程序编译后,发现出现了 所谓的“标签”的名字无法辨认,原因是属性页对话框默认是支持英文的。所以需要在左侧资源视图选择属性页,在右键菜单里选择语言-》中文,然后在对话框的属性里字体选择宋体。就可以了。参见http://bbs.csdn.net/topics/10287621
PS:
其他方法也可以考虑:
http://www.codeguru.com/cpp/controls/propertysheet/article.php/c591/Creating-a-Property-Sheet-Inside-a-Form-View.htm
另外 属性页的方式 与 标签Tab的方式 之间的比较有待学习,以及这2者在数据交互时的差别值得注意。