关闭MFC模式对话框后获取编辑框文本

4

在一个模态的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个回答

23
对话框及其控件直到调用DoModal()时才会被创建,正如先前所指出的那样,在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();

@abhinav,有一个勾选框可以点击来表达那种情感。 - Aidan Ryan

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

    CPreparationDlg dlg(AfxGetMainWnd());
    
    dlg.m_myVariableName = "我的值"; 
    
    dlg.DoModal();
    

    // 新值仍然在dlg.m_myVariableName中


0

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

很难说你为什么要将 m_pMainWnd 设置为对话框。老实说,我真的不确定你在那里尝试做什么。这肯定会导致问题,因为现在 AfxGetMainWnd() 已经失效了。

无论如何,在对话框被销毁后,您都无法获取对话框的控件值。


谢谢你的留言,我对VC++ MFC非常陌生, 我已经删除了那一行但它还是无法运行,你能否指出 另一种从字段中提取数据的方法? - abhinav
这里无法运行 ASSERT(::IsWindow(m_hWnd)); - abhinav
由于出现错误ASSERT(::IsWindow(m_hWnd)),程序无法运行。 - abhinav

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对话框形式,您可以获取数据到主窗体。 获取数据后,调用SetModifiedFlag(true)来设置视图数据已更新。 调用UpdateAllViews(NULL)将数据设置到主窗体。


-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;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接