我想知道如何让另一个应用程序窗口成为我的wx窗口的父窗口。
我知道这是可能的,因为twain模块就是这样做的。
例如,您可以传入pygame.display的句柄,它将作为将出现的扫描对话框的父级。 你可以直接给它一个Tk()或wx.Frame()的句柄(但它只会抓取句柄号)。
或者你可以传递一个完全不同的应用程序的句柄,例如记事本。
我想实现这一目标。这样我的wx对话框或弹出窗口就会以模态模式显示在另一个应用程序上。
您已经推断出我想在MS Windows上执行此操作。 好吧,我想跨平台做这件事,但其他平台并不是那么愚蠢,让任何人都搞乱其他应用程序的界面。 当然我认为这是可能的,但更难。所以,现在只有Windows。
我想为此我需要模仿wx.Window或Frame或Panel或基于所选窗口句柄的东西将其传递给我的对话框。或类似的东西。
有什么想法吗?
答案 0 :(得分:0)
我将在wxWidgets(C / C ++库)术语中进行讨论,例如,我的“wxFrame”将变成你的wx.Frame。
wxWindow类有一个方法3.14159265359
(http://docs.wxwidgets.org/3.1/classwx_window.html)。因此,您可以尝试使用默认构造函数创建wxWindow对象(让我们称之为“ParrentWindow”),找出某个外部应用程序的某个窗口的id,并将此窗口ID传递给我们的“ParrentWindow”对象的SetId
方法。
然后你应该尝试使用这个对象作为你自己的一些窗口(wxWindow,wxFrame,wxPannel等)的父对象:只需将我们的“ParrentWindow”传递给新窗口对象的构造函数。
也许它会奏效。
但请记住(在现代版本的MS Windows OS中)您的应用程序可以限制为仅使用您自己的窗口进行操作。如果是这种情况,则需要在其中一个管理员帐户下运行您的应用程序。
<强> UPD:强>
我刚刚查看了MSDN,是的:您可以使用SetId
win32 API函数更改已存在(已构建)窗口的父级:https://msdn.microsoft.com/en-us/library/windows/desktop/ms633541(v=vs.85).aspx
因此,您可以将User32.dll加载到Python代码中并直接使用此win32 Api(使用默认的SetParent()
模块)或间接使用(通过ctypes
模块)。然后你只需要获得子窗口的HWND和外部父窗口的HWND。并将它们传递给pywin32
win32 API函数。但是你应该记住,使用绕过wxWindows代码的win32 API可能导致(或者可能不会)在适当的wxWindows对象中出现不一致。
答案 1 :(得分:0)
我没有解决我的问题。对我来说幸运的是,这两个应用程序,客户端程序和我想成为其父程序的程序都是我的,因此我使用wxPython重写了父程序,并向其中添加了必要的接口,即创建了新的应用程序。一开始我不愿意这样做,所以才寻找“育儿”解决方案。
但是,在这两年中,我偶然发现了一些有用的信息:
我发现了一个工厂函数,该函数称为_CreateWindowFromNativeWindow()或_CreateWindowFromHandle()之类。 在wxPython中,这是一个内部函数,但据我所知,可以从我们的代码中调用它。但是对于它的热爱,我再也找不到它。我没有尝试过,所以这只是一个小费。也许有人可以挖掘出来。
我找到了方法wx.Window.AssociateHandle(),但这是真实的,应该可以工作。我们不能在没有父级的情况下创建wx.Window(),但是可以创建wx.Frame()。像这样:
f = wx.Frame(None)
f.AssociateHandle(hwnd)
应该工作。现在,如果hwnd是正确的并且我们具有适当的权限,则f应该链接到另一个应用程序的本机窗口,并且我们应该能够将其用作其他wx窗口的父级。不管谁尝试,请发表评论以告知我们它是否按预期工作。
如果我们知道如何使wxWidgets意识到操作系统已更改窗口的句柄,则总是有ctypes解决方案。我不是因为我停下来朝那个方向看。此外,还有一种解决方案,可以通过修改wxPython源代码并构建它们来公开wxWidgets的未公开方法setHWND()(根据某些来源应该存在)。