科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件MFC程序员的WTL指南之属性页与向导

MFC程序员的WTL指南之属性页与向导

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

向导模式的属性表通常用来引导用户安装软件或完成其他复杂的工作。

作者:LITHE 来源:blog 2007年10月19日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
创建一个更好的属性表类

  在OnOptions()中创建属性表是个好主意,但是在这里使用很多初始化代码却非常糟糕,这不是CMainFrame应该做得事情。更好的方法是从CPropertySheetImpl派生一个新类,在这个类中完成这些任务。

#include "BackgroundOptsPage.h"

class CAppPropertySheet : public CPropertySheetImpl<CAppPropertySheet>
{
 public:
  // Construction
  CAppPropertySheet ( _U_STRINGorID title = (LPCTSTR) NULL,
  UINT uStartPage = 0, HWND hWndParent = NULL );

  // Maps
  BEGIN_MSG_MAP(CAppPropertySheet)
   CHAIN_MSG_MAP(CPropertySheetImpl<CAppPropertySheet>)
  END_MSG_MAP()

  // Property pages
  CBackgroundOptsPage m_pgBackground;
  CPropertyPage<IDD_ABOUTBOX> m_pgAbout;
};

  我们使用这个类封装属性表中各个属性页的细节,将初始化代码移到属性表内部完成,构造函数完成添加页面,并设置其他必需的标志:

CAppPropertySheet::CAppPropertySheet ( _U_STRINGorID title, UINT uStartPage, HWND hWndParent ) :
CPropertySheetImpl<CAppPropertySheet> ( title, uStartPage, hWndParent )
{
 m_psh.dwFlags |= PSH_NOAPPLYNOW;

 AddPage ( m_pgBackground );
 AddPage ( m_pgAbout );
}

  这样一来,OnOptions()处理函数就变得简单了一些:

void CMainFrame::OnOptions ( UINT uCode, int nID, HWND hwndCtrl )
{
 CAppPropertySheet sheet ( _T("PSheets Options"), 0 );

 sheet.m_pgBackground.m_nColor = m_view.m_nColor;
 sheet.m_pgBackground.m_nPicture = m_view.m_nPicture;

 if ( IDOK == sheet.DoModal() )
  m_view.SetBackgroundOptions ( sheet.m_pgBackground.m_nColor,sheet.m_pgBackground.m_nPicture );
}

  创建一个向导样式的属性表

  创建一个向导和创建一个属性表很相似,这并不奇怪,只需稍做修改添加“上一步”和“下一步”按钮就行了。和MFC一样,你需要重载OnSetActive()函数并调用SetWizardButtons()使相应的按钮可用。我们先从一个简单的介绍页面开始,它的ID是IDD_WIZARD_INTRO:

             

  注意这个页面没有标题栏文字,因为向导中的所有的页面通常都有相同的标题,我更愿意在CPropertySheetImpl的构造函数中设置这些文字,然后每个页面使用这个字符串资源。这就是为什么我只需要改变一个字符串就能改变所有页面标题文字的原因。

  关于这个页面的实现代码在CWizIntroPage类中:

class CWizIntroPage : public CPropertyPageImpl<CWizIntroPage>
{
 public:
  enum { IDD = IDD_WIZARD_INTRO };

  // Construction
  CWizIntroPage();

  // Maps
  BEGIN_MSG_MAP(COptionsWizard)
   CHAIN_MSG_MAP(CPropertyPageImpl<CWizIntroPage>)
  END_MSG_MAP()

  // Notification handlers
  int OnSetActive();
};

  构造函数使用(引用)一个字符串资源ID来设置页面的文字:

CWizIntroPage::CWizIntroPage() :
CPropertyPageImpl<CWizIntroPage>( IDS_WIZARD_TITLE )
{}

  当这个页面激活时,字符串IDS_WIZARD_TITLE ("PSheets Options Wizard")将出现在向导的标题栏。OnSetActive()仅仅使“下一步”按钮可用:

int CWizIntroPage::OnSetActive()
{
 SetWizardButtons ( PSWIZB_NEXT );
 return 0;
}

  为了实现一个向导,我们需要创建一个类COptionsWizard,还要在主窗口添加菜单Tools|Wizard。COptionsWizard类的构造函数和CAppPropertySheet类的构造函数一样,只是设置必要的样式标志和添加页面。

class COptionsWizard : public CPropertySheetImpl<COptionsWizard>
{
 public:
  // Construction
  COptionsWizard ( HWND hWndParent = NULL );

  // Maps
  BEGIN_MSG_MAP(COptionsWizard)
   CHAIN_MSG_MAP(CPropertySheetImpl<COptionsWizard>)
  END_MSG_MAP()

  // Property pages
  CWizIntroPage m_pgIntro;
};

COptionsWizard::COptionsWizard ( HWND hWndParent ) :
CPropertySheetImpl<COptionsWizard> ( 0U, 0, hWndParent )
{
 SetWizardMode();

 AddPage ( m_pgIntro );
}

  CMainFrame类的Tools|Wizard菜单处理函数是这个样子:

void CMainFrame::OnOptionsWizard ( UINT uCode, int nID, HWND hwndCtrl )
{
 COptionsWizard wizard;
 wizard.DoModal();
}

  这就是向导的效果:

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章