如何使用窗口句柄更改窗口所有者

12

我想将一个.NET窗体作为另一个外部应用程序(不是.NET相关的、纯Win32的应用程序)的TopMost窗体,这样它就可以在该Win32应用程序之上显示,但不会覆盖其他正在运行的应用程序。

我有Win32应用程序的句柄(由Win32应用程序本身提供),并尝试过使用Win32 SetParent()函数,通过C#中的P/Invoke,但那样我的.NET窗体会被限制在Win32应用程序中,而这并不是我想要的。

3个回答

19

我认为你正在寻找的是使用 P/Invoke 的方式 SetWindowLongPtr(win32window, GWLP_HWNDPARENT, formhandle)

谷歌搜索


3
问题是我用"change windows owner"这个词进行了谷歌搜索,而不是搜索"change windows parent"。 :) - Ricardo Amores
22
我曾经多次路过这个回答,认为它回答了错误的问题,直到我在msdn文档中读到以下内容:“您不应该使用GWL_HWNDPARENT索引调用SetWindowLong来更改子窗口的父窗口。相反,请使用SetParent函数。” 这个声明是误导性的。GWL_HWNDPARENT会更改窗口的所有者(OWNER),而不是父窗口。如果出于这个目的使用它是安全的。 - bj0

2

是的!我已经有了一个安全的x64 P/Invoke导入SetWindowLongPtr。并且使用Reflector搜索了Form.Owner属性(即get_Owner(Form value)方法),成功地更改了所有者。

SetWindowLongPtr(childHdl, -8, OwnerHdl)

在我能够在这里发布解决方案之前,我一直在寻找“-8(0xFFFFFFFFFFFFFFF8)”的含义,但是Joel已经指出了。

谢谢!


-3

距离这个问题被提出已经过去了12年,所以我想从这里提供一个更新的答案。

不要使用GWLP_HWNDPARENT索引调用SetWindowLongPtr来更改子窗口的父窗口。相反,请使用SetParent函数。


1
请再次阅读问题。这不是关于更改子窗口的父级,而是关于更改另一个顶级窗口的所有者。这是两个完全不同的操作。如当前已接受答案的评论中所解释的那样,SetWindowLongPtr(..., GWLP_HWNDPARENT, ...)是更改所有者句柄的正确方法。 - whY

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