工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛
您的位置:软件 > 开发者网络 > 开发工具 > 开发专栏 > VC > 正文
MFC程序员的WTL指南之高级界面类
[文章信息]
作者:lithe
时间:2005-02-15
出处:blog
责任编辑:方舟
[文章导读]
本文将介绍一些新类实现高级界面特性新类:控件自画和自定外观控件
advertisement
热点推荐
· 禁止QQ登录的方法
· 给你的XML文件做个数字签名
· ImageReady制作“焰火”小动画
· Java加密和数字签名编程快速入门
· 在VB6中用命令行为模式控制GUI动作
[正文]

上一页  1 2 3 4 5  下一页

  对话框中控件的UI Updating

  对话框中的的UI updating控制比MFC中简单得多,在MFC中,你需要响应未公开的WM_KICKIDLE消息,处理这个消息并触发控件的updating,在WTL中,没有这个诡计,不过向导存在一个BUG,需要手工添加一行代码解决这个问题。

  首先需要记住的是对话框必须是无模式的,因为CUpdateUI需要在程序的消息循环控制下工作。如果对话框是模式的,系统处理消息循环,我们程序的空闲处理函数就不会被调用,由于CUpdateUI是在空闲时间工作的,所以没有空闲处理就没有UI updating。

  ControlMania2的对话框是非模式的,类定义的开始部分很像是一个框架窗口类:

class CMainDlg : public CDialogImpl<CMainDlg>, public CUpdateUI<CMainDlg>,
public CMessageFilter, public CIdleHandler
{
 public:
  enum { IDD = IDD_MAINDLG };

  virtual BOOL PreTranslateMessage(MSG* pMsg);
  virtual BOOL OnIdle();

  BEGIN_MSG_MAP_EX(CMainDlg)
   MSG_WM_INITDIALOG(OnInitDialog)
   COMMAND_ID_HANDLER_EX(IDOK, OnOK)
   COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)
   COMMAND_ID_HANDLER_EX(IDC_ALYSON_BTN, OnAlysonODBtn)
  END_MSG_MAP()

  BEGIN_UPDATE_UI_MAP(CMainDlg)
  END_UPDATE_UI_MAP()
 //...
};

  注意CMainDlg类从CUpdateUI派生并含有一个update UI链。OnInitDialog()做了这些工作,这和前面介绍的框架窗口中的代码很相似:

// register object for message filtering and idle updates
CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT(pLoop != NULL);
pLoop->AddMessageFilter(this);
pLoop->AddIdleHandler(this);

UIAddChildWindowContainer(m_hWnd);

  只是这次我们不是调用UIAddToolbar()或UIAddStatusBar(),而是调用UIAddChildWindowContainer(),它告诉CUpdateUI我们的对话框含有需要updating的字窗口,只要看看OnIdle(),你会怀疑少了写什么:

BOOL CMainDlg::OnIdle()
{
 return FALSE;
}

  你可能猜想这里应该调用另一个CUpdateUI的方法做一些实在的updating工作,你是对的,应该是这样的,向导在OnIdle()中漏掉了一行代码,现在加上:

BOOL CMainDlg::OnIdle()
{
 UIUpdateChildWindows();
 return FALSE;
}

  为了演示UI updating,我们设定鼠标点击左边的位图按钮,使得右边的按钮变得可用或禁用。先在update UI链中添加一个消息入口,使用UPDUI_CHILDWINDOW标志表示此入口是子窗口类型:

BEGIN_UPDATE_UI_MAP(CMainDlg)
 UPDATE_ELEMENT(IDC_ALYSON_BMPBTN, UPDUI_CHILDWINDOW)
END_UPDATE_UI_MAP()

  在左边的按钮的单击事件处理中,我们调用UIEnable()来翻转另一个按钮的使能状态:

void CMainDlg::OnAlysonODBtn ( UINT uCode, int nID, HWND hwndCtrl )
{
 static bool s_bBtnEnabled = true;

 s_bBtnEnabled = !s_bBtnEnabled;
 UIEnable ( IDC_ALYSON_BMPBTN, s_bBtnEnabled );
}

  DDV

  WTL的对话框数据验证(DDV)比MFC简单一些,在MFC中你需要分别使用DDX(对话框数据交换)宏和DDV(对话框数据验证)宏,在WTL中只需一个宏就可以了,WTL包含基本的数据验证支持,在DDV链中可以使用三个宏:

  DDX_TEXT_LEN

  和DDX_TEXT一样,只是还要验证字符串的长度(不包含结尾的空字符)小于或等于限制长度。

  DDX_INT_RANGE and DDX_UINT_RANGE

  和DDX_INT,DDX_UINT一样,还加了对数字的最大最小值的验证。

  DDX_FLOAT_RANGE

  除了像DDX_FLOAT一样完成数据交换之外,还验证数字的最大最小值。

  ControlMania2有一个ID是IDC_FAV_SEASON的edit box,它和成员变量m_nSeason相关联。


  由于有效的值是1到7,所以使用这样的数据验证宏:

BEGIN_DDX_MAP(CMainDlg)
 //...
 DDX_INT_RANGE(IDC_FAV_SEASON, m_nSeason, 1, 7)
END_DDX_MAP()

  OnOK()调用DoDataExchange()获得season的数值,并验证是在1到7之间。


上一页  1 2 3 4 5  下一页

发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容焦点新闻
  • Visual C++开发中常见问题的答案
  • MFC程序员的WTL指南之对话框与控件
  • 标准模板库(STL)学习指南之List容器
  • 用VC实现将自绘图形输出为bmp文件
  • DLL“地狱”的原因及其解决方案
  • 民营家电商排队造手机 设备商全面杀入
  • 英特尔澄清杨旭任职传闻 官方没宣布此消息
  • 国资委河北密制联通拆分方案
  • 垃圾邮件害人害企害国 清除垃圾邮件不手软
  • 中兴携手阿尔卡特 全球逐鹿CDMA
  • 用友总裁王文京:誓将ERP变成“大众消费”
  • 香港消费者委员会:数码相机最贵未必最好
  • 外电称中兴正评估西门子手机业务 或能并购
  • Advertisement