如何访问父窗体?

3
好的,很多人以各种方式提出了这个问题,但似乎除了在调用子对象时传递父对象之外,并没有太多答案。问题是,我无法访问父代码。
以下是我的情况。
一些我无法访问的代码,我只能使用dll(父表单),调用我的代码(子表单)中的一个函数。
我的函数调用第三方SDK(不太重要),其中需要父表单作为参数之一。此外,我无法访问第三方代码,只能通过一些c++库进行访问。
我的子表单是否能够知道其父表单,或者它注定成为孤儿?

2
您的 ParentForm 属性无法正常工作吗? - Zdeslav Vojkovic
或者FindForm()怎么样? - Uwe Keim
1
“Parent form” 是什么意思?如果您的子窗体有一个父窗体,那么父窗体将包含它,这意味着子窗体不能移出“父窗体”的边界。我认为您指的是“所有者窗体”。 - King King
@KingKing说得很对。你是想要窗体的容器,还是拥有者窗体(它将是一个不同的窗口,并且始终显示在所拥有的窗体后面)? - Matthew Watson
4个回答

3
在最一般的情况下(因为你的表单在dll中,并且你必须将父表单传递到第三方软件中),你可以使用WinAPI函数GetParent来检索父窗口句柄。 http://msdn.microsoft.com/en-us/library/windows/desktop/ms633510(v=vs.85).aspx 类似这样:
[DllImport("user32.dll",
           EntryPoint = "GetParent",
           CharSet = CharSet.Auto)]
internal static extern IntPtr GetParent(IntPtr hWnd); 

...

IntPtr parentHandle = GetParent(myForm.Handle); // <- If you have a form

...

IntPtr myFormHandle = ...
IntPtr myFormParentHandle = GetParent(myFormHandle); // <- If you have WHND only

// If there's a .net form with myFormParentHandle Handle you can retrieve it 
// Otherwise (e.g. form is not a .net one) you get null
Form parentForm = Control.FromHandle(myFormParentHandle) as Form;

这看起来可能是解决方案。将这个intptr转换回其对象是否可行?也就是说,我能否获取父窗体? - user1934821
1
@user1934821 是的,Form parent = (Form)Control.FromHandle(parentHandle) - Sriram Sakthivel

2
也许我漏掉了什么,但您可以直接使用ContainerControl.ParentForm
var parent = myForm.ParentForm;

或者(如果您实际上没有要询问的表单,而是有一个控件):
var parent = myForm.Parent;

请参见 http://msdn.microsoft.com/zh-cn/library/system.windows.forms.control.parent.aspx

那么该父控件的 Windows API 句柄将是:

IntPtr handle = parent.Handle;

您可以将其传递给第三方SDK。
请参见http://msdn.microsoft.com/en-us/library/system.windows.forms.control.handle.aspx 如果您需要检查父级是否真的是一个窗体:
Form form = myForm.Parent as Form;

if (form != null)
    // Do something with form.

但是像人们所说的那样:你应该只需要使用myForm.ParentForm

Hans PassantеїЇиЃЃдЄНи¶БдљњзФ®ParentFormпЉМиАМжШѓдљњзФ®FindForm()гАВ - Uwe Keim
@SriramSakthivel OP 是在问父窗体而不是所有者,对吧? - Matthew Watson
你能详细解释一下什么是父窗体吗?它是如何成为父窗体的?虽然我不太清楚这个问题。Parent Form 没有意义,不清楚。对于 MDIParent 来说是有意义的,我是否漏掉了什么? - Sriram Sakthivel
@UweKeim 安全需求的差异并不重要。主要区别在于当窗体没有父级时,FindForm() 不会返回 null。如果您需要知道窗体是否有父级,请调用 ParentForm 而不是 FindForm() - Matthew Watson
@SriramSakthivel 父级是包含窗体或控件的容器控件。所有者是指当一个窗体被另一个窗体拥有时,它会随着所有者窗体关闭或隐藏。 - Matthew Watson
显示剩余2条评论

0

你的表单是否出现在另一个表单的上方?尝试使用Form.Owner属性。

你确定要这样做吗?可能有很好的理由不让你访问父表单。请注意,不要通过规避此限制来破坏框架或模式。


是的,将一个遗留系统与另一个系统集成的缺点。 :( - user1934821

0

从父表单向子表单传递所有所需信息会更好(对于您的精神健康),这样您只需要以一种方式思考(父表单向子表单传递一些信息,子表单将信息+更多信息传递给下一个子表单,依此类推)

创建一个依赖其他表单/类的表单/类被称为硬耦合,这对于软件的维护是一个问题。


这不是一个选项,因为我无法访问父代码。 - user1934821

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接