2009-06-02 8 views
1

J'ai un programme en Python qui obtient un handle de fenêtre via COM à partir d'un autre programme (pensez au programme Python en tant qu'addin) J'ai défini cette fenêtre comme étant le le parent principal du cadre Python, de sorte que si l'autre programme se réduit, le cadre python le sera également. Le problème est quand je vais à la sortie, et essaye de fermer ou de détruire le cadre principal, le frame.close ne termine jamais son exécution (bien qu'il disparaisse) et l'autre programme refuse de fermer à moins d'être tué avec TaskManager.wxPython ne se ferme pas Cadre avec un parent qui est un handle de fenêtre

Voici à peu près les mesures que nous prenons:

if we are started directly, launch other program 
if not, we are called from the other program, do nothing 

enter main function: 
create new wx.App 
set other program as frame parent: 
    Get handle via COM 
    create a parent using wx.Window_FromHWND 
    create new frame with handle as parent 
    show frame 
enter main loop 

App.onexit: 
    close frame 
    frame = None 
    handle as parent = None 
    handle = None 

Quelqu'un a des idées sur ce ou de l'expérience avec ce genre de chose?

J'apprécie n'importe quelle aide avec ceci!

[Modifier] Ceci est seulement le cas lorsque j'utilise la poignée en tant que parent, si je reçois juste la poignée et fermer le programme python, l'autre programme se termine bien

Répondre

0

Ma résolution à cette question est un peu piraté, et certes pas la solution la plus élégante que je suis venu jamais avec - mais il fonctionne plutôt efficacement ...

Fondamentalement mes étapes sont de commencer un fil qui interroge pour voir si le handle de fenêtre est existant ou pas. Alors qu'il existe encore, ne faites rien. S'il n'existe plus, tuez l'application python, permettant ainsi de libérer le handle (et l'application principale).

class CheckingThread(threading.Thread): 
    ''' 
    This class runs a check on Parent Window to see if it still is running 
    If Parent Window closes, this class kills the Python Window application in memory 
    ''' 
    def run(self): 
     ''' 
     Checks Parent Window in 5 seconds intervals to make sure it is still alive. 
     If not alive, exit application 
     ''' 
     self.needKill = False 

     while not self.needKill: 
      if self.handle is not None: 
       if not win32gui.IsWindow(self.handle): 
        os._exit(0) 
        break 
      time.sleep(5) 

    def Kill(self): 
     ''' 
     Call from Python Window main application that causes application to exit 
     ''' 
     self.needKill = True 

    def SetHandle(self, handle): 
     ''' 
     Sets Handle so thread can check if handle exists. 
     This must be called before thread is started. 
     ''' 
     self.handle = handle 

Encore une fois, il se sent un peu hackish, mais je ne vois pas vraiment un autre moyen de contourner. Si quelqu'un d'autre a de meilleures résolutions, s'il vous plaît poster.

1

Je me demande si votre appel Close peut être suspendu dans le proche-manieur. Avez-vous essayé d'appeler Destroy à la place? Si cela ne vous aide pas, alors la seule solution semble être de "reparer" ou de "détacher" votre image - je ne vois pas comment faire ça en wx, mais peut-être pourriez-vous descendre à l'API win32 pour cela une tâche ...?

+0

J'ai essayé à la fois de fermer et de détruire. Je ne suis pas sûr de comprendre ce que vous voulez dire par "Dropdown to win32 API", pourriez-vous élaborer? – Fry

+0

Je veux dire, par exemple, obtenir le HWND du cadre et essayer de le détruire via DestroyWindow (hFrame); la définition de WM_EX_NOPARENTNOTIFY lors de la création de la fenêtre pour s'assurer que le pseudo-parent ne participe pas au processus de destruction/fermeture; et d'autres astuces de bas niveau que Win32 rend disponibles mais qui ne peuvent pas être révélées par des frameworks multiplateformes tels que wx - voir http://msdn.microsoft.com/fr-fr/library/aa383749(VS.85).aspx pour beaucoup plus de détails. –

+0

Je n'arrive pas à trouver un moyen d'implémenter vos suggestions en Python. En ce moment je viens de mettre la fenêtre handle à détruire à la sortie du programme Python. Je ne peux pas trouver plus d'informations ailleurs – Fry

0

Si reparentage est tout ce dont vous avez besoin, vous pouvez essayer frame.Reparent(None) avant frame.Close()

+0

Merci, mais la réparation ne fonctionne pas. Le plus tôt je sais que le formulaire se ferme est dans l'événement OnClose, ce qui semble ne pas avoir d'effet – Fry

Questions connexes