正文

UpdateData 探索2006-12-03 13:44:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/yuqiexing/21217.html

分享到:

早就想写这篇文章了,一直苦于没有时间。这么好的周末我自然不会浪费,于是上来侃2句了,希望对初学者有益。

 

UpdateData这个函数相信大家已经了解。带有1个参数。如果参数为TRUE,表示将控件中的内容“输入”给它的关联变量。如果是FALSE,表示将关联变量的内容输入到控件中。

一     UpdateData(FALSE)

假设现在已经有一个编辑框了,并且设置了一个关联变量m_stredit。好,现在我想初始化它,让对话框一运行的时候,编辑框中就有字符了。常见的做法如下:

BOOL Cmydlg::OnInitDialog()

{

    CDialog::OnInitDialog();

     ........

   m_stredit="hello,world!";

  UpdateData(FALSE);

.............

}

结果自然正确。后来还见过这种写法,在构造函数中初始化关联变量:

Cmydlg::Cmydlg(CWnd* pParent /*=NULL*/)
 : CDialog(Cmydlg::IDD, pParent)
{
 //{{AFX_DATA_INIT(CJianyanDlg)
  // NOTE: the ClassWizard will add member initialization here
 //}}AFX_DATA_INIT
 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32


m_stredit="hello,world!";


}

其他什么代码也没写。奇怪,也能运行。我并没有调用UpdateData(FALSE)啊?在哪儿调用了?一行行的检查自然让我把注意力集中在了:

CDialog::OnInitDialog();

这个基类的函数到底干了些什么勾当?我要搞明白。方法是这样的:

菜单栏,编辑,在文件中查找,输入这个函数(CDialog::OnInitDialog()),还要注意设置一下查找的路径,结果如下:

BOOL CDialog::OnInitDialog()
{
 // execute dialog RT_DLGINIT resource
 BOOL bDlgInit;
 if (m_lpDialogInit != NULL)
  bDlgInit = ExecuteDlgInit(m_lpDialogInit);
 else
  bDlgInit = ExecuteDlgInit(m_lpszTemplateName);

 if (!bDlgInit)
 {
  TRACE0("Warning: ExecuteDlgInit failed during dialog init.\n");
  EndDialog(-1);
  return FALSE;
 }

 // transfer data into the dialog from member variables
 if (!UpdateData(FALSE))
 {
  TRACE0("Warning: UpdateData failed during dialog init.\n");
  EndDialog(-1);
  return FALSE;
 }

 // enable/disable help button automatically
 CWnd* pHelpButton = GetDlgItem(ID_HELP);
 if (pHelpButton != NULL)
  pHelpButton->ShowWindow(AfxHelpEnabled() ? SW_SHOW : SW_HIDE);

 return TRUE;    // set focus to first one
}

捡最重要的看了。确实调用了UpdateData(FALSE),猜对了!

知道了这些,那么我显然也可以把这样初始化:

BOOL Cmydlg::OnInitDialog()

{

    m_stredit="hello,world!";

    CDialog::OnInitDialog();

     ........

  // m_stredit="hello,world!";

  //UpdateData(FALSE);

.............

}

果然成功!

 

二    UpdateData(TRUE)

再来假设一个这样的程序。现在有一个SDI和对话框,单击一个菜单项弹出对话框。在编辑框输入字符串,然后“确定”结束,要求在视图中显示。很简单:

 void CMyView::Onrange() //响应菜单消息
{

Cmydlg dlg;

if(dlg.DoModal()==IDOK)

{

    m_str=dlg.m_stredit;//m_str是视类中的成员变量

     Invalidate(); //调用OnDraw函数显示,略去

}
}

此时你可能有这种疑问,要不要UpdateData(TRUE) 啊,在哪里调用啊?

我们知道模太对话框用DoModal来显示,直到窗口结束,也就是调用了CDialog::EndDialog(),得到它的返回值,IDOK或者是IDCANCEL。此时DoModal()返回值如果是IDOK,表示执行了CDialog::OnOK(),也就是单击了“确定”按钮。那你自然会想到:

void Cmydlg ::OnOK()

{

  UpdateData(TRUE);

CDialog::OnOK();

}

这样当然没有错误。但是很可惜这是错误的,我们来查看一下CDialog::OnOK的源代码:

void CDialog::OnOK()
{
 if (!UpdateData(TRUE))
 {
  TRACE0("UpdateData failed during dialog termination.\n");
  // the UpdateData routine will set focus to correct item
  return;
 }
 EndDialog(IDOK);
}

啊,原来CDialog::OnOK自身就会调用UpdateData,我们又多此一举了!实际上这就是有些书上所写的:“确定”,它会保存信息,而“取消”则不会,其实奥秘在这里啊!

三   .DoModal();

如二的例子,现在弹出对话框后,我想初始化,当然可以像实例1一样在OnInitDialog中去做或者是在构造函数中,不过还有另一种方法哦:

 void CMyView::Onrange() //响应菜单消息
{

Cmydlg dlg;

dlg.m_stredit="hehe!";

if(dlg.DoModal()==IDOK)

{

    m_str=dlg.m_stredit;//m_str是视类中的成员变量

     Invalidate(); //调用OnDraw函数显示,略去

}
}

运行一下,确实可以,为什么只有一句dlg.m_stredit="hehe!";就可以了呢?在哪里莫非又调用了UpdateData了?

原因在于调用了domodal以后,程序就去调用对话框的派生类中的OnInitDialog,然后又调用基类的,又回到实例1了,呵呵!

原来一切尽在其中!

阅读(7407) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册