abhinav
abhinav

Reputation: 537

Getting edit box text from a modal MFC dialog after it is closed

From a modal MFC dialog, I want to extract text from an edit box after the dialog is closed. I attempted this:

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;

It does not work.

Upvotes: 4

Views: 25951

Answers (5)

hessamini
hessamini

Reputation: 59

This solution may seem long, meaning that so much code has been written for this seemingly small task. But when we have a list or tree inside the child window where all the items are created in the child window and the items have to be moved to the parent window, then it makes sense. This source code can easily create a window and transfer information from the window before closing to the parents.

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

Upvotes: -1

Nguyen Dinh Quy
Nguyen Dinh Quy

Reputation: 1

I often use

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

With dsohinh is Dialog form that you want to get data to mainform . After get data then call SetModifiedFlag(true) to set view data updated. call UpdateAllViews(NULL) to Set data to mainform

Upvotes: 0

dwo
dwo

Reputation: 3636

  1. Open your dialog resource, right-click on the textbox and choose "Add variable", pick value-type and CString
  2. In the dialog-class: before closing, call UpdateData(TRUE)
  3. Outside the dialog:

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

    // the new value is still in dlg.m_myVariableName

Upvotes: 1

Marius Bancila
Marius Bancila

Reputation: 16328

The dialog and its controls is not created until you call DoModal() and as already pointed, is destroyed already by the time DoModal() returns. Because of that you cannot call GetDlgItem() neither before, nor after DoModal(). The solution to pass or retrieve data to a control, is to use a variable in the class. You can set it when you create the class instance, before the call to DoModal(). In OnInitDialog() you put in the control the value of the variable. Then, when the window is destroyed, you get the value from the control and put it into the variable. Then you read the variable from the calling context.

Something like this (notice I typed it directly in the browser, so there might be errors):

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

Then you can use it like this:

CMyDialog dlg;

dlg.SetValue("stackoverflow");

dlg.DoModal();

CString response = dlg.GetValue();

Upvotes: 23

Jonathan Wood
Jonathan Wood

Reputation: 67203

DoModal() destroys the dialog box before it returns and so the value is no longer available.

It's hard to tell why you are setting m_pMainWnd to your dialog. To be honest, I'm not really sure what you are trying to do there. That's bound to cause problems as now AfxGetMainWnd() is broken.

Either way, you can't get the dialog box's control values after the dialog has been destroyed.

Upvotes: 0

Related Questions