找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 566|回复: 0

[教学]:自定义向导的实现(通过NEXT按纽实现对话框的递进)

[复制链接]
发表于 2003-11-24 15:49:09 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
这个方法很不错,拿来共享!!!!!
可以用来实现由于用户选择不同而用户界面也不同的对话框
/////////////////////////

1. 工程的建立与基本界面的生成
生成一个MFC APPWIZARD 新工程,命名为CustomWizard,在Step1 中选择基于Dialog Based样式。
在自动生成的Dialog 资源中加入一个按钮IDC_BENGINWIZ 用来启动向导。
新建一个对话框 资源,命名为IDC_WIZARD,用来显示自定义向导界面,如图

依次创建向导的每页 的对话框资源,命名为IDD_STEP1,IDD_STEP2,IDD_STEP3,

(图4)
2. 生成所需要的类
为了方便叙述,表1将所用的类进行了归纳
(表1)


类名 基类 说明
CWizard CDialog 向导的框架
CStep1 CDialog 向导的第一步
CStep2 CDialog 向导的第二步
CStep3 CDialog 向导的第三步
CCustomWizardDlg CDialog 启动向导

3. 在CWizard添加要使用的数据结构
为了方便描述,表2列出了使用到的成员变量
(表2)


成员变量 类型 说明
rectPage CRect 每页显示的范围
nPageCount UINT 页的总数
nCurrentPage UINT 正在显示的页
nPageLink PAGELINK* 用来链接所有的页
typedef struct PAGELINK{
UINT nNum;
CDialog* pDialog;
struct PAGELINK* Next;}; nNum为页的编号
pDialog为页所对应的对话框的指针  


4. CWizard所使用到的函数 添加一个新页到Wizard框架,入口参数为要添加的对话框ID

void CWizard::AddPage(UINT nID)
{
struct PAGELINK* pTemp=pPageLink;
//插入新生成的节点
struct PAGELINK* pNewPage=new struct PAGELINK;
pNewPage->pDialog=new CDialog;
ASSERT(pNewPage->pDialog->Create(nID,this)); // 以无模式创建窗口
ASSERT(::IsWindow(pNewPage->pDialog->m_hWnd));
// 检查每页的样式
DWORD dwStyle = pNewPage->pDialog->GetStyle();
ASSERT((dwStyle & WS_CHILD) != 0); // 子窗口
ASSERT((dwStyle & WS_BORDER) == 0); // 无边界
// 显示
pNewPage->pDialog->ShowWindow(SW_HIDE); //先隐藏,需要时再显示
pNewPage->pDialog->MoveWindow(rectPage);
//移动对话框到制定位置,rectPage已经初始化了
pNewPage->Next=NULL;
pNewPage->nNum=++nPageCount; //计数器加1
if (pTemp) //插入到链表
{ //如果不是空链表
        while (pTemp->Next) pTemp=pTemp->Next; // 移动链表末尾
        pTemp->Next=pNewPage;
}
else // 空链表
        pPageLink=pNewPage; //若是第一个节点
}

显示的页,入口参数为要显示的某特定页的编码
void CWizard::ShowPage(UINT nPos)
{
struct PAGELINK* pTemp=pPageLink;
        while(pTemp)
        {
        if(pTemp->nNum==nPos)
        {
                pTemp->pDialog->ShowWindow(SW_SHOW);
        }
else
                //不显示
                pTemp->pDialog->ShowWindow(SW_HIDE);
pTemp=pTemp->Next;
}
if (nPos>=nPageCount) //最后一页
{
        nCurrentPage=nPageCount;
        SetWizButton(2);
        return;
}
if (nPos<=1) //首页
{
        nCurrentPage=1;
        SetWizButton(0);
        return;
}
//如果是中间步
SetWizButton(1);
}

为了与显示统一,需要相应的设置按钮
void CWizard::SetWizButton(UINT uFlag)
{
GetDlgItem(IDC_CANCEL)->EnableWindow(TRUE);
GetDlgItem(IDC_PREV)->EnableWindow(TRUE);
GetDlgItem(IDC_NEXT)->EnableWindow(TRUE);
GetDlgItem(IDC_FINISH)->EnableWindow(TRUE);
switch(uFlag)
{
case 0: //第一步
        GetDlgItem(IDC_PREV)->EnableWindow(FALSE);
        break;
case 1: //中间步
        break;
case 2: //最后一步
        GetDlgItem(IDC_NEXT)->EnableWindow(FALSE);
        break;
}
}

点击“上一步”、“下一步”、“完成”、“取消”代码
void CWizard::OnPrev()
{
// TODO: Add your control notification handler code here
ShowPage(--nCurrentPage);
}
void CWizard::OnNext()
{
// TODO: Add your control notification handler code here
ShowPage(++nCurrentPage);
}
void CWizard::OnFinish()
{
// TODO: Add your control notification handler code here
AfxMessageBox("采用默认值完成向导");
CDialog::OnOK();
}
void CWizard::OnCancel()
{
// TODO: Add your control notification handler code here
if (AfxMessageBox(IDS_QUIT,MB_OKCANCEL|MB_ICONQUESTION)==IDCANCEL)
        return;
CDialog::OnCancel();
}

5. 辅助代码,如初始化等
BOOL CWizard::OnInitDialog()
{
CDialog::OnInitDialog();
//获得每页显示的范围
CRect Rect1;
GetWindowRect(&Rect1); // 获得主窗口的位置
int nCaption = ::GetSystemMetrics(SM_CYCAPTION); // 系统Title高度
int nXEdge = ::GetSystemMetrics(SM_CXEDGE);
int nYEdge = ::GetSystemMetrics(SM_CYEDGE);
CRect Rect2;
GetDlgItem(IDC_POS)->GetWindowRect(&Rect2); // 获得框架的位置
Rect1.top=Rect1.top+nCaption+nYEdge; // 相对坐标
Rect1.left=Rect1.left+2*nXEdge;
//计算机位置
rectPage.top=Rect2.top-Rect1.top;
rectPage.left=Rect2.left-Rect1.left;
rectPage.bottom=Rect2.bottom-Rect1.top;
rectPage.right=Rect2.right-Rect1.left;

//页示的添加要显
AddPage(IDD_STEP1);
AddPage(IDD_STEP2);
AddPage(IDD_STEP3);

//显示第一页
ShowPage(1);

return TRUE;// return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}

因为是无模式窗体,所以要自己销毁窗体
void CWizard::OnDestroy()
{
CDialog::OnDestroy();
// TODO: Add your message handler code here
//每页依次消除
struct PAGELINK* pTemp=pPageLink;
while(pTemp)
{
        pTemp->pDialog->DestroyWindow();
        pTemp=pTemp->Next;
}
}

6. 启动向导需要在IDC_BEGINWIZ 按钮的Click事件中加入下列代码:
CWizard MyWiz; //显示向导
MyWiz.DoModal();
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-9-20 22:48 , Processed in 0.402399 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表