繁体   English   中英

MFC从对话框访问FormView项目

[英]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);
}

有人可以帮助我吗?

我可以在这里给您两个答案:

  1. 如何执行您要问的事情(从无模式对话框访问CFormView控件)
  2. 如何解决您的基本问题(将无模式对话框中的更改传达给所有者视图)

对于第一个,您必须在对话框类中声明一个指向视图的指针,并在视图的构造函数中对其进行初始化:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM