How to make a wx window parent of another application's window?

放肆的年华 提交于 2021-02-08 09:35:20

问题


I wish to know how to make another's application window be a parent to my wx window.

I know that it is possible because twain module does just that.

For instance, you can pass in pygame.display's handle and it will act as a parent of scanning dialog that will appear. You can give it a handle of your Tk() or wx.Frame() directly (but it will grab out only the handle number anyway).

Or you can pass in a handle of completely different application, notepad for example.

I would like to achieve this. So that my wx dialog or pop up window appear in Modal mode over another application.

You already deduced that I want to do it on MS Windows. Well, I'd like to do it cross-platform, but other platforms aren't so stupid to let anyone messing in other app's interface. Sure I think it is possible, but much harder. So, for now Windows only.

I guess for this I will need to emulate wx.Window or Frame or Panel or something based on a chosen window handle to pass it to my dialog. Or something like that.

Any ideas?


回答1:


I will talk in wxWidgets (C/C++ library) terminology, so, for example, my "wxFrame" will turn into yours wx.Frame.

wxWindow class has a method SetId (http://docs.wxwidgets.org/3.1/classwx_window.html). So you may try to create wxWindow object (let's call it "ParrentWindow") with default constructor, find out id of some window of some external application, and pass this window id to SetId method of our "ParrentWindow" object.

Then you should try to use this object as a parent of some of your own windows (wxWindow, wxFrame, wxPannel, etc.): just pass our "ParrentWindow" to the new window object's constructor.

Maybe it will work.

But remember that (in modern versions of MS Windows OS) your app can be restricted to operate only with your own windows. And if that is the case than you will need to run your app under one of the administrators accounts.

UPD:

I've just looked into MSDN and yes: you can change parent of already existing (already built) window by using SetParent() win32 API function: https://msdn.microsoft.com/en-us/library/windows/desktop/ms633541(v=vs.85).aspx

So you may load User32.dll into your Python code and use this win32 Api directly (by using default ctypes module) or indirectly (by pywin32 module). Then you just need to get HWND of your child window and HWND of external parent window. And pass them into SetParent() win32 API function. But you should remember that using win32 API bypassing wxWindows code may lead (or may not) to inconsistency in an appropriate wxWindows objects.




回答2:


I did not resolve my problem. Fortunately for me, both applications, the client one, and the one that I wanted to be its parent, were mine, so I rewrote the parent one using wxPython and added necessary interface into it, i.e. created the new application. I was unwilling to do that at first, that's why I searched for a "parenting" solution.

However, In this 2 years I happen to stumble on some useful info about it:

  1. I found a factory function called something like _CreateWindowFromNativeWindow() or _CreateWindowFromHandle() or something like that. That was an internal function in wxPython but was callable from our code as far as I saw. But for the love of it I cannot find it again. I did not try it, so it is a tip only. Perhaps somebody can dig it out.

  2. I found the method wx.Window.AssociateHandle() This however is real and should work. We cannot create a wx.Window() without a parent, but wx.Frame() we can. So something like this:


f = wx.Frame(None)
f.AssociateHandle(hwnd)

should work. Now f should be linked to the native window of another app, if the hwnd is right and we have appropriate permissions, and we should be able to use it as a parent for other wx windows. Whomever tries it, please post a comment to let us know whether it works as expected.

There is always a ctypes solution if we know how to make wxWidgets realise that the OS changed a handle of the window. I don't because I stopped to look in that direction. Also, there is a solution of exposing undocumented method setHWND() of wxWidgets, which should exist according to some sources, by modifying the wxPython sources and building them.



来源:https://stackoverflow.com/questions/40923352/how-to-make-a-wx-window-parent-of-another-applications-window

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!