从模态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;
它不起作用。
答案 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)
UpdateData(TRUE)
在对话框外:
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;
}