在我的SDI应用程序中,我需要得到这个行为。单击FormView上的按钮后,将打开一个CDialog。当我按下CDialog上的OK按钮时,我调用FormView的一个功能。我不想关闭CDialog。我尝试使用无模式对话框,但是当我从对话框调用formview函数时,我无法访问formview的控件,就像它丢失了hwnd;错误是无法读取m_hwnd的内存,hwnd是???。 这是我的代码: 打开无模式对话框:
CCampiDlg *m_pDialog = NULL;
HWND hCampi = NULL;
// Invoking the Dialog
m_pDialog = new CCampiDlg;
if (m_pDialog != NULL)
{
BOOL ret = m_pDialog->Create(m_pDialog->IDD, this);
if (!ret) //Create failed.
{
AfxMessageBox(_T("Error creating Dialog"));
}
m_pDialog->ShowWindow(SW_SHOW);
}
当我按下对话框中的确定按钮时:
CEditorTxView pView;
box2 = (CEdit*)(GetDlgItem(IDC_CAMPI_BOX2));
box2->GetWindowTextW(campo);
pView.inserisciCampo(1, campo);
在CEditorTxView(CFormView)中的inserisciCampo函数中,我必须使用我的控件txtCtrl进行操作,但它丢失了hwnd。 txtCtrl的声明在CEditorTxView.h
中CTx1 txtCtrl;
并在DoDataExchange函数中初始化它:
void CEditorTxView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TX1, txtCtrl);
}
有人可以帮助我吗?
答案 0 :(得分:3)
我可以在这里给你两个答案:
对于第一个,你必须在对话框类中声明一个指向视图的指针,并在视图的构造函数中初始化它:
class CCampiDlg : public CDialog
{
public:
CCampiDlg(CEditorTxView* pView, CWnd*pParent = NULL) // Change declaration to add pointer to view
: m_pView(pView)
{
}
// ... Whatever
private:
CEditorTxView* m_pView;
}
现在在你的按钮处理程序中:
CEdit* box2 = (CEdit*)(GetDlgItem(IDC_CAMPI_BOX2)); // Why not use a control variable?
box2->GetWindowTextW(campo);
m_pView->inserisciCampo(1, campo);
这应该做你要求的。但是,这是错误的做法。
这种方法的问题在于对话框对其父对象知之甚少。它知道它的类型为CEditorTxView
,并且它有一个名为inserisciCampo
的成员,它带有一个数字和一些文本。
它不应该知道那么多。事实上,除了CView类型甚至CWnd之外,了解它的任何内容都太过分了。
如果对话框知道视图,则无法将对话框重新用于其他视图,并且只要视图更改其表示(例如,现在的文本框现在可能是组合框),对话框必须更改相应
解决方案是向家长发送消息,解释发生了什么。然后父(视图)应该知道如何处理该事件。例如:
class CCampiDlg : public CDialog
{
public:
CCampiDlg(CWnd*pParent = NULL) {}
protected:
OnOk()
{
CString campo;
c_CampiBox2.GetWindowText(campo);
GetParent()->SendMessage(UWM_CAMPO2_SET, 0, (LPARAM)&campo);
}
}
在视图中:
// It can be ON_REGISTERED_MESSAGE:
ON_MESSAGE(UWM_CAMPO2_SET, OnCampo2Set)
//...
LRESULT CEditorTxView::OnCampo2Set(WPARAM, LPARAM lParam)
{
CString* s = (CString*) lParam;
inserisciCampo(1, *campo);
return 0;
}
现在,您已将视图和对话框分离。该对话框对视图一无所知。您可以更改其类型,更改表示,甚至使其成为对话框,并且您不必更改对话框中的任何内容。如果您在其他地方需要相同的无模式对话框,只需将其放在那里,在父级中创建一个消息处理程序,然后vo!
有关进一步说明和更好的示例,请查看以下文章:
答案 1 :(得分:0)
在“确定”按钮上单击以下代码正在运行:
CEditorTxView pView;
box2 = (CEdit*)(GetDlgItem(IDC_CAMPI_BOX2));
box2->GetWindowTextW(campo);
pView.inserisciCampo(1, campo);
请注意,您正在堆栈中创建新的pView,并且它不会附加到任何窗口。您实际上并未引用已创建的视图并启动了作为父级的对话框。重新访问上面的代码并尝试获取视图:
如果代码无效,请尝试以下代码(Google it)
CFrameWnd * pFrame = (CFrameWnd *)(AfxGetApp()->m_pMainWnd);
CView * pView = pFrame->GetActiveView();