关闭后,从模态MFC对话框中获取编辑框文本

时间:2011-05-10 05:24:46

标签: visual-c++ mfc modal-dialog

从模态MFC对话框中,我想在关闭对话框后从编辑框中提取文本。我试过这个:

CPreparationDlg Dlg;
CString m_str;

m_pMainWnd = &Dlg;
Dlg.DoModal();
CWnd *pMyDialog=AfxGetMainWnd();
CWnd *pWnd=pMyDialog->GetDlgItem(IDC_EDIT1);
pWnd->SetWindowText("huha max");
return TRUE;

它不起作用。

5 个答案:

答案 0 :(得分:21)

在调用DoModal()之前,不会创建对话框及其控件,并且已经指出,在DoModal()返回时已经销毁了该对话框及其控件。因此,您无法在DoModal()之前或之后调用GetDlgItem()。将数据传递或检索到控件的解决方案是使用类中的变量。您可以在调用DoModal()之前在创建类实例时进行设置。在OnInitDialog()中,您将控件的值放入控件中。然后,当窗口被销毁时,您将从控件获取值并将其放入变量中。然后从调用上下文中读取变量。

像这样的东西(注意我直接在浏览器中输入它,所以可能有错误):

class CMyDialog : CDialog
{
  CString m_value;
public:  
  CString GetValue() const {return m_value;}
  void SetValue(const CString& value) {m_value = value;}

  virtual BOOL OnInitDialog();
  virtual BOOL DestroyWindow( );
}

BOOL CMyDialog::OnInitDialog()
{
  CDialog::OnInitDialog();

  SetDlgItemText(IDC_EDIT1, m_value);

  return TRUE;
}

BOOL CMyDialog::DestroyWindow()
{
  GetDlgItemText(IDC_EDIT1, m_value);

  return CDialog::DestroyWindow();
}

然后你可以像这样使用它:

CMyDialog dlg;

dlg.SetValue("stackoverflow");

dlg.DoModal();

CString response = dlg.GetValue();

答案 1 :(得分:2)

  1. 打开对话框资源,右键单击文本框并选择“添加变量”,选择值类型和CString
  2. 在对话框类中:关闭前,请致电UpdateData(TRUE)
  3. 在对话框外:

    CPreparationDlg dlg(AfxGetMainWnd());
    
    dlg.m_myVariableName = "my Value"; 
    
    dlg.DoModal();
    

    //新值仍在dlg.m_myVariableName

答案 2 :(得分:0)

DoModal()在返回之前销毁对话框,因此该值不再可用。

很难说出为什么要将m_pMainWnd设置到对话框中。说实话,我不确定你在那里做什么。这必然会导致问题,因为现在AfxGetMainWnd()被打破了。

无论哪种方式,在对话框被销毁后都无法获得对话框的控制值。

答案 3 :(得分:0)

我经常使用

D_SOHINH dsohinh = new D_SOHINH();
    dsohinh.vd_kichthuoc=v_kichthuocDOC;
    dsohinh.vd_sohinh=v_soluongDOC;
    if(dsohinh.DoModal()==IDOK)
    {
        v_soluongDOC=dsohinh.vd_sohinh;
        v_kichthuocDOC=dsohinh.vd_kichthuoc;
    }
    SetModifiedFlag(true);
    UpdateAllViews(NULL);

使用dsohinh是Dialog表单,您希望将数据提供给mainform。 获取数据后,调用SetModifiedFlag(true)以设置更新的视图数据。 调用UpdateAllViews(NULL)将数据设置为mainform

答案 4 :(得分:-1)

这个解决方案可能看起来很长,这意味着为这个看似很小的任务编写了这么多代码。 但是当我们在子窗口中有一个列表或树时,所有项目都在子窗口中创建 并且项目必须移动到父窗口, 那么它是有道理的。 这个源代码可以很容易地创建一个窗口,并在关闭之前将窗口中的信息传递给父窗口。

    //copy the two functions in your code 

    //1-    bool peek_and_pump(void)

    //      template<class T,class THISCLASS>
    //2-    void TshowWindow(int id,T *&pVar,THISCLASS *ths)

    //and make two member variable
    // bool do_exit;
    // bool do_cancel;
    //in child dialog class.
    //set true value in do_exit in child dialog for exit

    CchildDialog *dlg;

    template<class T,class THISCLASS>
    void TshowWindow(int id,T *&pVar,THISCLASS *ths)
    {
        T *p=pVar;
        if(!p)
            p= new T;
        if(p->m_hWnd)
        {
            p->SetForegroundWindow();
        }
        else
        {
            delete p;
            p= new T;
            if(!(p->m_hWnd && IsWindow(p->m_hWnd)))
            {
                p->Create(id,ths);
                if(IsWindow(p->m_hWnd))
                    p->ShowWindow(TRUE);
            }   
        }
        pVar=p;
    }


    bool peek_and_pump(void)
    {
        MSG msg;

    #if defined(_AFX) || defined(_AFXDLL)
        while(::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
        {
            if(!AfxGetApp()->PumpMessage())
            {
                ::PostQuitMessage(0);
                return false;
            }
        }
        long lIdle = 0;
        while(AfxGetApp()->OnIdle(lIdle++))
            ;
    #else
        if(::PeekMessage(&msg,NULL,0,0,PM_REMOVE))
        {
            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);
        }
    #endif

        return true;
    }

    void CparentPage::OnBnClick1()
    {
        if(dlg)
        {
            dlg->DestroyWindow();   
        }
        TshowWindow<CchildDialog,CparentPage>(IDD_DIALOG_child,dlg,this);
        dlg->GetDlgItem(IDC_EDIT_1)->SetWindowText("");
        dlg->m_temp_window.EnableWindow(FALSE);//enable or disable controls.
        dlg->UpdateData(false);//for to be done enable of disable or else.
        dlg->do_exit=false;
        dlg->do_cancel=false;
        while(dlg->do_exit==false)
        {
            peek_and_pump();//wait for dlg->do_exit set true
        }
        if( dlg->do_cancel==false ) 
        {
            CString str1;
            dlg->GetDlgItem(IDC_EDIT_1)->GetWindowText(str1);
            //or other member variale of CchildDialog
            //after finish all work with dlg then destroy its.
        }
        dlg->DestroyWindow();   
        

    }
    
    void CchildDialog::OnBnClickedOk()
    {
        UpdateData();
        OnOK();
        do_exit=true;
        do_cancel=false;
    }
    void CchildDialog::OnBnClickedCancel()
    {
        OnCancel();
        do_exit=true;
        do_cancel=true;
    }