对话框中有两个编辑框控件,第一个输入号码,第二个输入其他属性。想要实现输入号码后,根据后台数据库确定该号码的合法性,如不合法,弹出另一对话框提示错误。这一点可以实现,问题是:由于必须通过WM_SETFOUCS或WM_KILLFOCUS来确认号码的输入完成,如果号码不合法,弹出提示对话框时,该提示对话框获得焦点,即发出WM_KILLFOCUS消息,而号码编辑框会相应这个消息,号码的合法性效验和弹出错误提示对话框的代码也是在这个相应函数中的,形成了死循环,如何解决?
Cdlg::OnS

解决方案 »

  1.   

    CDlg::OnKillFocusHM()
    {
    .....//效验Hm的合法性
    if(号码不合法)
    messageBox("错误“);
    ...
    }
    当HM编辑控件发出WM_KILLFOCUS时,该函数被调用,而有错误时,弹出错误提示对话框,弹出的同时,又发出WM_KILLFOCUS,而改函数有被调用,象中情况如何处理?
      

  2.   

    不用对话框的killfocus,用编辑框的killfocus行吗?
      

  3.   

    应该是你edit控件的OnKillFocusHM,而不是对话框的。
      

  4.   

    你的问题我没太明白,为什么关闭提示对话框时,会发出对编辑框的killfocus呢?这个过程中你有对它setfocus了吗?
      

  5.   

    CDlg::OnKillFocusHM()就是这个编辑控件的相应函数阿?
      

  6.   

    我试了一下,输入不是a时,弹出一个error,点确定后就完事了,没死循环呀,是我理解错了吗?void CTestDialog::OnKillfocusEdit1() 
    {
    if(m_test != "a")
    {
    this->MessageBox("error");
    }

    }
      

  7.   

    不是关闭提示对话框时发出编辑控件的WM_KILLFOCUS,而是在提示对话框被打开时,肯定是提示对话框要获得焦点,而编辑对话框必然要失去焦点啊,所以回发出编辑对话框的WM_KILLFOCUS.
      

  8.   

    在编辑框的modify事件写不行么
      

  9.   

    MessageBox("error");确定后,焦点会给谁?这是焦点是如何处理的?是再给回之前的焦点对象吗?
      

  10.   

    你用的是WM_KILLFOCUS,如果用WM_SETFOCUS是什么样的情况阿?就是当下一个编辑控件被激活时那?
      

  11.   

    我也试了一下,你说的是对的,用WM_KILLFOCUS和下一个编辑框的WM_SETFOCUS是不同的,用WM_KILLFOCUS没有问题,但用WM_SETFOCUS就会出现死循环的情况阿
      

  12.   

    呵呵,真是有趣,竟然真是死循环,我写成这样
    void CTestDialog::OnSetfocusEdit2() 
    {
    if(m_test != "a")
    {
    this->MessageBox("error");
    this->OnKillfocusEdit2();
    }
    }
    还是不行,有高手旁观吗,给咱讲讲啊
      

  13.   

    是啊,我也百思不得其解,开始用的是WM_KILFOCUS,没有问题,但由于其他的原因,必须要用WM_SETFOCUS,就出现这种情况,我觉得第一个编辑控件WM_KILLFOCUS和第二个编辑控件WM_SETFOCUS应该是一样的,可能是MessageBox("error");的处理上不同,查了MSDN,根本没有任何解释,不明白阿!!!
      

  14.   

    sans(sans) 朋友果然是高手,我也觉得,就算成功了,用户输入完第一个编辑框,刚想输入第二个,蹦,弹出一对话框;没有两个都输入完,点提交后再报错来的友好。
    yangrp(yangrp) ,判断数据合法与否的语句可以加在点检查按钮的响应函数里呀
      

  15.   

    你在第二个控件的OnSetFocus中进行判断,如果不满足条件弹出消息框,这时那个控件失去焦点。等你按完OK以后,焦点不是又回到那个控件上去了吗?这自然会引起一个死循环。你可以试试在CDialog::DoDataExchange中进行输入值的检验,然后在OnSetfocusEdit2中updatedata(true),这时如果输入数据不符要求,就会自动弹出一个消息框,把它关闭后焦点自动移回出问题的那个控件。
      

  16.   

    道理是这样,但我搞不懂是如果在第一个控件失去焦点时进行判断就不会出现死循环的问题,为什么?我想请问你一个问题,就是MessageBox()在返回后把焦点给谁?是给原先的焦点的拥有者吗?
      

  17.   

    MessageBox()在返回后把焦点给谁你试一试不就知道了吗?据我推测应该是原先的焦点的拥有者。至于你说如果在第一个控件失去焦点时进行判断就不会出现死循环的问题,这不是显然的吗?你想想这个过程:焦点移出第一个控件,移到第二个控件-->判断是否合法输入,如为非法弹出对话框,焦点从第二个控件移到对话框-->关闭对话框-->焦点移回第一个控件。这个过程中只有第一步的时候第一个控件收到了WM_KILLFOCUS,怎么会死循环呢?
      

  18.   

    void CTestDialog::OnKillfocusEdit1() 
    {
    if(m_test != "a")
    {
    this->MessageBox("error");
    }
             
             Edit2.SetFocous();
    }
    就拿这个例子说吧,焦点移出第一个控件,在弹出错误对话框时并没有移到第二个控件阿?这时焦点是谁,不知道,但肯定不是EDIT1,我估计是父窗口对话框,这时MessageBox("error"),发出WM_KILLFOCOUS,但目标肯定不是EDIT1,EDIT1的OnKillFocous相应函数不会相应,所以不会有死循环。至于你说Message()把焦点还给原来的拥有者我想也是这样,实践证明的阿!我考虑了一下,采用控件相应WM_KILLFOCUS的办法有很大的缺陷,比如说我激活其他不相关的窗口,焦点发生变化就会进行效验,还容易出现死循环的状况。因此我觉得最好不要采用焦点消息的办法实现。而你说的采用DDV的方式也需要考虑在什么地方进行UPDATEDATA(TRUE),象这样的问题你一般是怎么处理的?又没什么方法可以实现一个控件,原来没有被选中,现在被选中了。但不用焦点的消息的方法
      

  19.   

    UPDATEDATA(TRUE)可以就放在OnSetfocusEdit2里。DDV失败以后焦点会自动移回Edit1,这样不会出现死循环。
      

  20.   

    在你显示提示对话框之前首先将焦点设置在第一个编辑控件上,那么,当提示对话框关闭后,则焦点就会回到第一个编辑控件上!MessageBox()返回时返回到原先拥有焦点的控件!你只要在显示提示对话框之前,将焦点设置好不就行了!
    下面是本人的解决方法,很笨,但还是可行的!
    class CAboutDlg : public CDialog
    {
    .....
    private:
       bool b_flag;
       ...
       };
       
       CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
    {
      b_flag=true;
    //{{AFX_DATA_INIT(CAboutDlg)
    //}}AFX_DATA_INIT
    }
    void CAboutDlg::OnSetfocusEdit2() 
    {
    // TODO: Add your control notification handler code here
      CString str;
      m_Edit1Ctrl.GetWindowText(str);  if(b_flag&&str!="psusong")
      {
    b_flag=false;
    m_Edit1Ctrl.SetFocus();
    MessageBox("The data is error ,please input again!");  }
    }void CAboutDlg::OnSetfocusEdit1() 
    {
    // TODO: Add your control notification handler code here
    b_flag=true;
    }