从MFC中的对话框访问父窗口
我正在制作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
;
请帮助我解决这个问题。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
观察到的行为很有意义。 (模式)对话框的
cview
- 衍生的类实例是儿童窗口。因此,它们不能成为(模式)对话框的所有者。当您将子窗口传递到cdialog
衍生的类的c'tor时,系统将沿窗口层次结构走去,直到找到一个重叠或弹出窗口,并将其用作所有者对话框。不管您是否拨打 , getAncestor 或cwnd :: getowner
,这是一个真正的所有者(通常是您的cframewnd
衍生的实现),其中窗口遍历启动。因此,您通常不能使用标准窗口遍历来查找传递到(模式)对话框构造函数的窗口。但是,MFC记录
cwnd
( - 派生的)类实例您将传递到coptionsdialog
构造器中,并将其存储在preected
成员变量>中m_pparentwnd ,从 /代码> 类。只要
coptionsdialog
衍生public
/受保护的
从cdialog
或cdialogex
,可以访问此类成员。以下
OnInitDialog
实现将执行您的需求:还有其他选项可用。例如,您可以提供
coptionsdialog
构造器,该构建器同时使用cwnd*
和csquaresdoc*
,将第一个授权到基础类C' tor并将文档指针存储在(私有
)类成员中。这使得对话框取决于文档的代码更容易遵循其明确阐明的代码。The observed behavior makes sense. A (modal) dialog's owner must be
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 aCDialog
-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 callGetParent
,GetAncestor
, orCWnd::GetOwner
, it is this true owner (usually yourCFrameWnd
-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 yourCOptionsDialog
constructor and stores it in aprotected
member variablem_pParentWnd
, inherited from theCDialog
class.As long as
COptionsDialog
derivespublic
/protected
fromCDialog
orCDialogEx
, the implementation can access this class member.The following
OnInitDialog
implementation will do what you're looking for:There are other options available. For example, you could supply a
COptionsDialog
constructor that takes both aCWnd*
and aCSquaresDoc*
, 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.将静态方法
getCurrentView()
添加到视图类:文件
.h文件
现在您可以从任何地方调用
getCurrentView()
.cpp 。对于MDI应用程序,解决方案可能有些不同。
您可以做的另一件事就是创建一个公共成员
csquaresview *m_pview
incoptionsdialog
并将其设置为此
喜欢:或修改
coptionsdialog
构造函数som_pview
是由构造函数直接设置的,或类似的东西。Add a static method
GetCurrentView()
to your view class:.cpp file
.h file
Now you can just call
GetCurrentView()
from anywhere you want: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
inCOptionsDialog
and set that tothis
like:or modify the
COptionsDialog
constructor som_pView
is set directly by the constructor, or something similar.使用
getowner()
。只有WS_CHILD
Windows有父母,其他Windows有所有者。Use
GetOwner()
. OnlyWS_CHILD
windows have parents, other windows have owners.