[英]mfc access to formview item from dialog box
在我的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);
}
有人可以帮助我吗?
我可以在这里给您两个答案:
对于第一个,您必须在对话框类中声明一个指向视图的指针,并在视图的构造函数中对其进行初始化:
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;
}
现在,您已经将视图和对话框解耦了。 对话框对视图一无所知。 您可以更改其类型,更改表示形式,甚至使其成为对话框,而不必在对话框中进行任何更改。 如果您在其他地方需要相同的无模式对话框,只需将其放到那里,在父级中创建一个消息处理程序,然后瞧瞧!
有关更多说明和更好的示例,请查看以下文章:
在确定按钮上,单击下面的代码正在运行:
CEditorTxView pView;
box2 = (CEdit*)(GetDlgItem(IDC_CAMPI_BOX2));
box2->GetWindowTextW(campo);
pView.inserisciCampo(1, campo);
请注意,您正在堆栈中创建新的pView,它不与任何窗口连接。 您实际上并不是在引用已经创建并启动了充当父级对话框的视图。 重新查看上面的代码并尝试获取视图:
如果无法使用,请尝试以下代码(Google可以)
CFrameWnd * pFrame = (CFrameWnd *)(AfxGetApp()->m_pMainWnd);
CView * pView = pFrame->GetActiveView();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.