如何在對話框之間傳值 – Before DoModal()

目前有一個功能會先跳出另存新檔的 CFileDialog

在成功選擇要儲存的檔名和位址之後會跳出另一個自定義的對話框

在這個自定義的對話框中有一個 CEdit 的控制項

我希望能夠在這個控制項中顯示剛剛 CFileDialog 裡打好的檔名

這樣要怎麼做呢~?

 

一開始在另存新檔的對話框完成後我先 Create、Assign Value、Show自定義的對話框

// <MainFrm.cpp>
CString szFilter = "Project Files|*.dpj||";
CFileDialog fd(FALSE,"dpj","",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter,this);
 
fd.m_ofn.Flags |= OFN_ENABLETEMPLATE;
fd.m_ofn.hInstance = AfxGetInstanceHandle();
fd.m_ofn.lpTemplateName = _T("DIALOG_PREVIEW");

if(fd.DoModal() == IDOK)
{
	CNewProjectDlg newProjectDlg;
	newProjectDlg.m_dProjectDlg.m_ceProjectName.SetWindowText(fd.GetFileTitle());
	newProjectDlg.DoModal();
}

 

看上去沒甚麼問題,但是執行之後就在 IsWindow(m_hWnd) 這行檢查的程式碼上 crash 了

// <winocc.cpp>
void CWnd::SetWindowText(LPCTSTR lpszString)
{
	ENSURE(this);
	ENSURE(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL)); // Failed here

	if (m_pCtrlSite == NULL)
		::SetWindowText(m_hWnd, lpszString);
	else
		m_pCtrlSite->SetWindowText(lpszString);
}

 

根據參考資料 CEditCtrl 會在 OnInitDialog() 中被創建

但是 OnInitDialog() 是要在 DoModal() 後才會被呼叫

而在  DoModal() 完成前基本上無法操作裡面的控件,所以這樣倒底要怎麼辦呢冏

 

[解決方法]

參考資料給出了一個蠻有技巧的 idea

1. 先在自定義的 Dialog 中新增一個 public 變數

並修改本來賦值給 CEditCtrl 的程式碼,改成把檔名賦值給新增的變數

// <MyDlg.h>
public:
	CEdit m_ceProjectName; // 原先的CEditCtrl
	CString projectName; // 另外新增的變數

// <MainFrm.cpp>
	CNewProjectDlg newProjectDlg;
	newProjectDlg.m_dProjectDlg.projectName = fd.GetFileTitle();
	newProjectDlg.DoModal();

 

2. 然後在 OnInitDialog() 中把變數賦值給 CEditCtrl

// <MyDlg.cpp>
BOOL CProjectDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	m_ceProjectName.SetWindowText(projectName);
	return TRUE; 
}

雖然是麻煩了一點,但是只要能夠達到目的也不失為一個好方法

 

[參考資料]

1. MFC 对话框间传值