[杂项]使用MFC实现向导型动态对话框 |
小工头 发表于 2005/9/20 18:53:08 | 设计用户管理流程的时候心血来潮,想做成象安装向导那样的动态对话框,上一步下一步的多么华丽~Shawn不会做,俺记得之前做过这种东东,便答应给他现编一个例程出来。想不到,这一编就是一整个下午……简直要晕死了。俗话说得好:“拳不离手,曲不离口”,好久没玩MFC了,给别人当老师都没有资格。趁着记忆还没消失,赶紧记录下来。
动态对话框用到的主要是两个MFC类:CPropertySheet和CPropertyPage。前者是动态对话框的外框,而后者就是框里的内容了。
首先,在ResourceView界面插入新的对话框,类型为IDD_PROPPAGE_LARGE( MEDIUM,SMALL可选)。将此对话框作为对话框的底板。用ClassWizzard为此对话框建立一个新类,名为CTestPPInit,基类为CPropertySheet(注:俺不确定是否一定要给这个类建立一个对话框资源,不过建了之后肯定能做成。安全第一,建就建吧,反正多一个对话框也无所谓);
在ResourceView界面插入新的对话框,类型为IDD_PROPPAGE_LARGE(MEDIUM SMALL可选)。将此对话框作为起始页面,加入几个Radio控件,提示用户选择。用ClassWizzard为此对话框建立一个新类,名为CTestPPStart,基类为CPropertyPage。加入与Radio控件绑定的成员变量m_choice;
用相同方式再建立两个新的类。一个名为CTestPPContinue,作为中间页面。为了演示效果,加入一个Edit控件,加入与Edit控件绑定的成员变量m_output;另外一个名为CTestPPEnd,作为结束时的页面,同样拥有Edit控件和与之绑定的成员变量m_str_end;
在类CTestPPInit中新增成员变量:
CTestPPEnd m_end;
CTestPPContinue m_next_2;
CTestPPContinue m_next_1;
CTestPPStart m_start;作为待加载的4个动态页面;(注意引用相应的头文件)
在类CTestPPInit中新增成员函数:
void AddEndPage();
void AddContinueTPage();
void AddContinuePage();
实现添加3个后续页面的功能。代码大同小异:
void CTestPPInit::AddContinuePage()
{
//去掉之前所有的页面
while(GetPageCount() > 1)
RemovePage(1);
//依次加上当前和后续页面
m_next_1.m_output = "您选择了从1开始!";
AddPage(&m_next_1);
m_next_2.m_output = "您经过了1,来到了2!";
AddPage(&m_next_2);
m_end.m_str_end = "您经过1,2,来到了最后!";
AddPage(&m_end);
}
void CTestPPInit::AddContinueTPage()
{
while(GetPageCount() > 1)
RemovePage(1);
m_next_2.m_output = "您跳过了1,来到了2!";
AddPage(&m_next_2);
m_end.m_str_end = "您经过2,来到了最后!";
AddPage(&m_end);
}
void CTestPPInit::AddEndPage()
{
while(GetPageCount() > 1)
RemovePage(1);
m_end.m_str_end = "您直接来到了最后!";
AddPage(&m_end);
}
通过ClassWizzard重载CTestPPStart类的OnSetActive()和OnWizardNext()函数:
BOOL CTestPPStart::OnSetActive() { // TODO: Add your specialized code here and/or call the base class CTestPPInit *pSheet = (CTestPPInit *)GetParent(); pSheet->SetWizardButtons(PSWIZB_NEXT); return CPropertyPage::OnSetActive();}
LRESULT CTestPPStart::OnWizardNext() { // TODO: Add your specialized code here and/or call the base class UpdateData(TRUE); CTestPPInit *pSheet = (CTestPPInit *)GetParent(); if(m_choice == 0) pSheet->AddContinuePage(); else if(m_choice == 1) pSheet->AddContinueTPage(); else pSheet->AddEndPage(); return CPropertyPage::OnWizardNext();}
(注:通过重载OnWizardNext(),实现了动态地给中间页面的成员变量赋值。)
重载CTestPPContinue类和CTestPPEnd类的OnSetActive()函数:
BOOL CTestPPcontinue::OnSetActive() { // TODO: Add your specialized code here and/or call the base class CTestPPInit *pSheet = (CTestPPInit *)GetParent(); pSheet->SetWizardButtons(PSWIZB_NEXT|PSWIZB_BACK); return CPropertyPage::OnSetActive();}
BOOL CTestPPEnd::OnSetActive() { // TODO: Add your specialized code here and/or call the base class CTestPPInit *pSheet = (CTestPPInit *)GetParent(); pSheet->SetWizardButtons(PSWIZB_BACK | PSWIZB_FINISH); return CPropertyPage::OnSetActive();}
(注:如果重载这两个类的OnWizardNext()函数,并且在CTestPPInit类中增加相应的成员变量的话,就可以把中间页面输入的变量值传给CTestPPInit类。)
最终的调用方法是:
void CTest_PropertySheetDlg::OnOK() { // TODO: Add extra validation here CTestPPInit test("test",this); test.AddPage(&test.m_start); test.SetWizardMode(); test.DoModal(); CDialog::OnOK();}
(注:如果用上述的方法把中间页面的变量值传递给了CTestPPInit类,在调用DoModal()之后,就可以象提取普通对话框的成员变量一样提取中间页面变量的值了)
后记:折腾了一下午,终于把这个本以为很初级的东东摆平了,心里很高兴。突然,Kenny问了俺一句:“你做这个准备干什么用呢?”俺一时居然想不起来编这个东东到底是为了什么。晕!
|
|
|

.: 公告
有人的地方就有恩怨 有恩怨的地方就是江湖 人在江湖漂,谁能不挨刀 |
|
« | September 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | | | | | |
|
.: 我的分类(专题)
|

.: 最新日志
.: 最新回复
|

blog名称:少年包工头的工作日记 日志总数:629 评论数量:1458 留言数量:56 访问次数:8980403 建立时间:2004年12月8日 |
|

.: 留言板
|

.: 链接
|

|