从MFC中的对话框访问父窗口

发布于 2025-02-08 04:47:24 字数 663 浏览 3 评论 0 原文

我正在制作DOC/查看Arch SDI应用程序。 我在 csquaresview 中调用 coptionsdialog

void CSquaresView::OnOptions()
{
 COptionsDialog dlg(this);
 if (dlg.DoModal() == IDOK) 
 ...
}

coptionsdialog 我想访问 csquaresview

BOOL COptionsDialog::OnInitDialog()
{
 CDialog::OnInitDialog();
 CWnd *pParent = GetParent();
 if (pParent) {
  CSquaresView *pView = dynamic_cast<CSquaresView*>(pParent); //pView is always NULL
  if (pView != NULL) 
  {
    CSquaresDoc* pDoc = pView->GetDocument();
 ...
 }

但是我总是得到 pview 作为 null ; 请帮助我解决这个问题。

I am making a doc/view arch SDI application.
I invoke a COptionsDialog in CSquaresView.

void CSquaresView::OnOptions()
{
 COptionsDialog dlg(this);
 if (dlg.DoModal() == IDOK) 
 ...
}

In COptionsDialog I want to access CSquaresView.

BOOL COptionsDialog::OnInitDialog()
{
 CDialog::OnInitDialog();
 CWnd *pParent = GetParent();
 if (pParent) {
  CSquaresView *pView = dynamic_cast<CSquaresView*>(pParent); //pView is always NULL
  if (pView != NULL) 
  {
    CSquaresDoc* pDoc = pView->GetDocument();
 ...
 }

But I always get pView as NULL;
Please help me to solve this problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

云巢 2025-02-15 04:47:24

观察到的行为很有意义。 (模式)对话框的

一个重叠或弹出窗口[...];子窗口不能是所有者窗口。

cview - 衍生的类实例儿童窗口。因此,它们不能成为(模式)对话框的所有者。当您将子窗口传递到 cdialog 衍生的类的c'tor时,系统将沿窗口层次结构走去,直到找到一个重叠或弹出窗口,并将其用作所有者对话框。不管您是否拨打 getAncestor cwnd :: getowner ,这是一个真正的所有者(通常是您的 cframewnd 衍生的实现),其中窗口遍历启动。


因此,您通常不能使用标准窗口遍历来查找传递到(模式)对话框构造函数的窗口。但是,MFC记录 cwnd ( - 派生的)类实例您将传递到 coptionsdialog 构造器中,并将其存储在 preected 成员变量>中m_pparentwnd ,从 /代码> 类。

只要 coptionsdialog 衍生 public /受保护的 cdialog cdialogex ,可以访问此类成员。

以下 OnInitDialog 实现将执行您的需求:

BOOL COptionsDialog::OnInitDialog()
{
    CDialog::OnInitDialog();
    CSquaresView *pView = dynamic_cast<CSquaresView*>(m_pParentWnd);
    if (pView != NULL) 
    {
        CSquaresDoc* pDoc = pView->GetDocument();
        ...
    }

还有其他选项可用。例如,您可以提供 coptionsdialog 构造器,该构建器同时使用 cwnd* csquaresdoc*,将第一个授权到基础类C' tor并将文档指针存储在(私有)类成员中。这使得对话框取决于文档的代码更容易遵循其明确阐明的代码。

The observed behavior makes sense. A (modal) dialog's owner must be

an overlapped or pop-up window [...]; a child window cannot be an owner window.

CView-derived class instances generally are child windows. As such they cannot be the owner of a (modal) dialog. When you pass a child window into the c'tor of a CDialog-derived class, the system walks up the window hierarchy until it finds an overlapped or pop-up window, and uses that as the owner of the dialog. Regardless of whether you then call GetParent, GetAncestor, or CWnd::GetOwner, it is this true owner (usually your CFrameWnd-derived implementation) where window traversal starts.


Thus, you cannot generally use standard window traversal to find the window passed into a (modal) dialog's constructor. However, MFC records the CWnd(-derived) class instance you pass into your COptionsDialog constructor and stores it in a protected member variable m_pParentWnd, inherited from the CDialog class.

As long as COptionsDialog derives public/protected from CDialog or CDialogEx, the implementation can access this class member.

The following OnInitDialog implementation will do what you're looking for:

BOOL COptionsDialog::OnInitDialog()
{
    CDialog::OnInitDialog();
    CSquaresView *pView = dynamic_cast<CSquaresView*>(m_pParentWnd);
    if (pView != NULL) 
    {
        CSquaresDoc* pDoc = pView->GetDocument();
        ...
    }

There are other options available. For example, you could supply a COptionsDialog constructor that takes both a CWnd* and a CSquaresDoc*, delegating the first onto the base class c'tor and storing the document pointer in a (private) class member. This makes for code that's easier to follow in that it explicitly spells out, that the dialog depends on the document.

ゞ记忆︶ㄣ 2025-02-15 04:47:24

将静态方法 getCurrentView()添加到视图类:

文件

CSquaresView* CSquaresView::GetCurrentView()
{
    CFrameWnd* pFrame = (CFrameWnd*)(AfxGetApp()->m_pMainWnd);
    return dynamic_cast<CSquaresView*>(pFrame->GetActiveView());
}

.h文件

class CSquaresView : public CView
{
    ...  
    static CSquaresView* GetCurrentView();
    ...
};

现在您可以从任何地方调用 getCurrentView()

...
CSquaresView *pView = CSquaresView::GetCurrentView();
...

.cpp 。对于MDI应用程序,解决方案可能有些不同。


您可以做的另一件事就是创建一个公共成员 csquaresview *m_pview in coptionsdialog 并将其设置为喜欢:

void CSquaresView::OnOptions()
{
  COptionsDialog dlg(this);
  dlg.m_pView = this;
  if (dlg.DoModal() == IDOK) 
    ...
}

或修改 coptionsdialog 构造函数so m_pview 是由构造函数直接设置的,或类似的东西。

Add a static method GetCurrentView() to your view class:

.cpp file

CSquaresView* CSquaresView::GetCurrentView()
{
    CFrameWnd* pFrame = (CFrameWnd*)(AfxGetApp()->m_pMainWnd);
    return dynamic_cast<CSquaresView*>(pFrame->GetActiveView());
}

.h file

class CSquaresView : public CView
{
    ...  
    static CSquaresView* GetCurrentView();
    ...
};

Now you can just call GetCurrentView() from anywhere you want:

...
CSquaresView *pView = CSquaresView::GetCurrentView();
...

This works for SDI applications. For MDI applications the solution might be somewhat different.


Another thing you could do is just create a public member CSquaresView *m_pView in COptionsDialog and set that to this like:

void CSquaresView::OnOptions()
{
  COptionsDialog dlg(this);
  dlg.m_pView = this;
  if (dlg.DoModal() == IDOK) 
    ...
}

or modify the COptionsDialog constructor so m_pView is set directly by the constructor, or something similar.

日暮斜阳 2025-02-15 04:47:24

使用 getowner()。只有 WS_CHILD Windows有父母,其他Windows有所有者。

Use GetOwner(). Only WS_CHILD windows have parents, other windows have owners.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文