IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

Trouver handle et nom fenêtre appelante


Sujet :

Windows Forms

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 246
    Points : 123
    Points
    123
    Par défaut Trouver handle et nom fenêtre appelante
    Salut à toutes et à tous.

    Je dois trouver le handle et le titre de la fenêtre à partir de laquelle j'appelle mon application.

    Qu'est-ce à dire ?

    Dans AutoCAD MAP 2004 J'ai crée un bouton qui, en LISP, ouvre une application que j'ai créée en C#.

    Le problème est que j'ai besoin, à partir de l'application, d'extraire des données d'AutoCAD.

    Si je démarre une nouvelle session d'AutoCAD à partir de l'application, je n'ai pas de pbl. Mais l'utilisateur final ne va pas passer beaucoup de temps à ouvrir de nouvelles instances d'AutoCAD et à les refermer au fur et à mesure. Il viendra me tapper dessus avant et il aura raison ...

    J'utilise, pour ouvrir AutoCAD à partir de mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    using AutoCAD;
    ...
       publicstaticAcadApplication acad_app;
        publicstaticAcadDocument acad_doc;
     
       privatevoid OpenAcadDrawing(string DwgPath, bool ReadOnly)
       {
           try
           {
               acad_app = newAcadApplication();
               acad_doc = acad_app.ActiveDocument;
               acad_app.Application.Visible = true;
     
    ...
    Je pourrais rechercher tous les handle des fenêtres puis trouver celle qui commence par acad, mais si plusieurs instances d'AutoCAD sont ouvertes, comment savoir laquelle est l'instance appelante ?

    J'ai pensé à extraire le handle et le titre de la fenêtre active à l'ouverture de l'application (plus précisément j'ai essayé sur le load du premier form et dans le main du program.cs), puisque celle-ci est ouverte en lisp à partir d'une icone dans AutoCAD. La fenêtre active étant forcément la fenêtre de l'instance appelante.

    J'ai codé ceci qui me retourne effectivement le titre de l'application active :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    [DllImport("user32.dll")]
    staticexternint GetForegroundWindow();
    [DllImport("user32.dll")]
    staticexternint GetWindowText(int hWnd, StringBuilder text, int count);
    privatestring GetActiveWindowTitle()
    {
       constint nChars = 256;
       int handle = 0;
       StringBuilder Buff = newStringBuilder(nChars);
       string ApplicationTitle = "";
       handle = GetForegroundWindow();
       if (GetWindowText(handle, Buff, nChars) > 0)
       {
           ApplicationTitle = Buff.ToString();
       }
       return ApplicationTitle;
    }
    Malheureusement, là où j'ai tenté d'utiliser ce bout de code (le load du premier form ou le main du program.cs), il me retourne invariablement "".
    Je pense que déjà ici il me sort le handle le mon application, mais ne retourne rien dans le titre puisqu'aucune fenêtre n'est encore ouverte.

    Comment trouver le Handle de l'application AutoCAD et, par extension, le titre de sa fenêtre ?

    Enfin, par extension, comment attribuer l'application AutoCAD ouverte et découverte à acad_app dans le premier bout de code ?

    Merci de vos z'avis z'avisés,
    Jean-Marc

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    240
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 240
    Points : 254
    Points
    254
    Par défaut
    Tu pourrais peut etre chercher du coté de l'API GetActiveWindow ...

  3. #3
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 246
    Points : 123
    Points
    123
    Par défaut
    Le résultat est malheureusement le même avec le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    [DllImport("user32.dll")]
    staticexternint GetActiveWindow();
    [DllImport("user32.dll")]
    staticexternint GetWindowText(int hWnd, StringBuilder text, int count);
    privatestring GetActiveWindowTitle()
    {
    
    constint nChars = 256; int handle = 0; StringBuilder Buff = newStringBuilder(nChars); string ApplicationTitle = ""; handle = GetActiveWindow(); //handle = GetForegroundWindow(); if (GetWindowText(handle, Buff, nChars) > 0) {
    ApplicationTitle = Buff.ToString();
    }
    return ApplicationTitle;
    }
    Je pense qu'en fait l'application étant démarrée mais pas qu'aucun form n'est encore affiché, l'application active est mon application et non AutoCAD. Et donc, comme aucune fenêtre n'est encore ouverte, le titre de la fenêtre est vide.

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    240
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 240
    Points : 254
    Points
    254
    Par défaut
    un rapide coup d'oeil a Msdn m'a donné la fonction GetGUIThreadInfo qui est un "GetWindow" qui prend en plus en parametre le thread que tu souhaite interroger ...
    Jamais utilisé, je doute que ca te soit utile ... etant donné que tu ne connais pas plus le thread que la Form

  5. #5
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 246
    Points : 123
    Points
    123
    Par défaut
    En effet, je ne vois pas non plus comment faire à partir de cela. En fait il faudrait pouvoir utiliser le GetActiveWindow ou le GetForegroundWindow tout au début de l'application, AVANT que la fenêtre d'AutoCAD ne se désactive.
    J'ai constaté que la fenêtre de mon Visual Studio changeait de couleur avant que la commande ne passe. Mais ou la mettre pour qu'elle passe tout en début ? Je pense qu'il doit y avoir moyen de coder avant que la fenêtre ne soit ouverte, ou peut-être même créée. Mais où faut-il mettre le code ?

  6. #6
    Membre actif Avatar de g_tarik0010
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2006
    Messages : 186
    Points : 284
    Points
    284
    Par défaut
    Bonjour,

    Je sais pas si j'ai bien compris ta question

    mais au moment de l'appel de ton appli tu pourrais lui donner comme parametres le nom et le handle de la fentere appelante
    Dans le boutton dans AutoCad qui demmare ton appli
    tu fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    monAppli.exe "Nom de la fenetre", currentHandle;
    Je ne sais pas comment fonctionne AutoCad mais je pense que ce que j'ai dit est faisable
    et dans le main de ton appli tu recupere tes données

  7. #7
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 246
    Points : 123
    Points
    123
    Par défaut
    A partir de AutoCAD 2006 pas de pbl. Mais comme 2004 n'est pas prévu pour .net, ben il faut se débrouiller sans. C'est pour ça que je cherche à simplement lancer mon appli à partir de AutoCAD avec LISP puis à pouvoir, dans l'appli, déterminer le handle de la fenêtre appelante, soit la session AutoCAD à partir de laquelle on a appuyé sur l'icone qui lance l'appli.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 547
    Points : 627
    Points
    627
    Par défaut
    Salut,

    ce qui suit est hautement hypothetique, mais n'y aurait il pas moyen de recuperer le parent d'une appli par une requete WMI (ou autre) ? Peut etre aussi cette manip, aucune idée de comment implementer ca en C#, mais ca peut peut-etre te mettre sur une piste.

    Bon courage.

  9. #9
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 246
    Points : 123
    Points
    123
    Par défaut
    Salut SirJulio,

    Je n'ai absolument RIEN contre les hypothèse. Je pense même que si on n'essayer rien, on aura une certitude : Celle de n'arriver à rien. Or ce n'est pas mon but.
    Je m'en vais donc zieuter ça et, pour les autres, n'ayez pas peur de donner vos idées. Il n'y en a pas de mauvaise.

    Quoi qu'il ne soit, merci à toutes et tous de votre aide qui, même si infructueuse à présent (ce qui ne durera pas j'en suis sûr), est précieuse pour moi.

    Jean-Marc

  10. #10
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 246
    Points : 123
    Points
    123
    Par défaut
    En effet, ça à l'air intéressant, mais je n'y comprend pas grand chose. Je ne sais pas non plus comment implémenter cela en c#, mais je pense que ton idée est à creuser.

  11. #11
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 246
    Points : 123
    Points
    123
    Par défaut
    Grâce à la piste de SirJulio (Tu vois que ce n'était pas si hypothétique que ça ... ), j'ai trouvé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    # using System;
    # using System.Runtime.InteropServices;
    #
    # /// <summary>
    # /// Gère les processus
    # /// </summary>
    # public class ProcessManager
    # {
    # [DllImport("kernel32.dll", SetLastError=true)]
    # static extern IntPtr CreateToolhelp32Snapshot(uint dwFlags,
    # uint th32ProcessID);
    #
    #
    # [DllImport("kernel32.dll", SetLastError=true)]
    # static extern bool Process32First(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
    #
    #
    # [DllImport("kernel32.dll", SetLastError=true)]
    # static extern bool Process32Next(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
    #
    # [DllImport("kernel32.dll", SetLastError=true)]
    # static extern bool CloseHandle(IntPtr hObject);
    #
    # /// <summary>
    # /// structure d'information sur un processus
    # /// </summary>
    # [StructLayout(LayoutKind.Sequential)]
    # internal struct PROCESSENTRY32
    # {
    # public uint dwSize;
    # public uint cntUsage;
    # public uint th32ProcessID;
    # public IntPtr th32DefaultHeapID;
    # public uint th32ModuleID;
    # public uint cntThreads;
    # public uint th32ParentProcessID;
    # public int pcPriClassBase;
    # public uint dwFlags;
    # [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)] public string szExeFile;
    # };
    #
    # const int TH32CS_SNAPPROCESS = 2;
    # const int SIZEOF_PROCESSENTRY32 = 564;
    # const int SIZE_OFFSET = 0;
    # const int PROCESS_OFFSET = 8;
    # const int PARENT_OFFSET = 24;
    #
    #
    #
    #
    # /// <summary>
    # /// Renvoi le PID du processus parent
    # /// </summary>
    # /// <param name="Pid"></param>
    # /// <returns></returns>
    # public static uint GetParentProcess(uint Pid)
    # {
    # //structure d'information sur un processus
    # PROCESSENTRY32 _pe = new PROCESSENTRY32();
    # _pe.dwSize = (uint)Marshal.SizeOf(typeof(PROCESSENTRY32));
    #
    #
    # //Handle pour accèder aux infos des processus
    # IntPtr handleProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    #
    # uint PidParent = 0;
    #
    # try
    # {
    # //Récupère la structure de processus sur le premier Handle
    # bool rv = Process32First(handleProcess,ref _pe);
    #
    # if(!rv)
    # throw new Exception("Ne peut pas énumérer les processus");
    #
    # //tant qu'il y a des processus à éumérer
    # while(rv)
    # {
    # uint pid = _pe.th32ProcessID;
    # uint parent = _pe.th32ParentProcessID;
    #
    # if( pid == Pid ) //si c'est le process en cours
    # {
    # //on va renvoyer le process parent
    # PidParent = parent;
    # break; //sorti du while, on arrête d'énumérer les processus
    # }
    #
    # //Récupère la structure de processus sur le handle suivant
    # rv = Process32Next(handleProcess, ref _pe);
    # }
    # }
    # finally
    # {
    # CloseHandle(handleProcess);
    # }
    #
    # return PidParent;
    # }
    # }
    #
    # /***********************************************************************************
    # ***********************************************************************************
    # ***********************************************************************************
    # ***********************************************************************************/
    #
    # //Utilisation
    # uint current_pid = (uint)Process.GetCurrentProcess().Id;
    # uint parent_pid = ProcessManager.GetParentProcess(current_pid);
    # Process parent_process = Process.GetProcessById((int)parent_pid);
    # string strParentFilePath = parent_process.MainModule.ModuleName;
    Ça à l'air de donner un résultat. Reste maintenant à démarrer l'appli à partir d'AutoCAD (Ça ne doit pas être un gros problème), mais aussi à pouvoir attribuer l'application (AutoCAD, dont on connait le handle maintenant) à la variable acad_app (Là je ne vois pas non plus, mais ça viendra. Si qqn a déjà une idée ...).

    Quoi qu'il ne soit, un merci tout particulier à SirJulio, et merci aussi à Totanne et g_tarik0010 pour leurs propositions ainsi qu'à tous ceux qui ont pris le temps de lire ma question.

    Jean-Marc

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 547
    Points : 627
    Points
    627
    Par défaut
    Content que cela ce soit avéré fructueux. =)

    Bon courage pour la suite.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 27/05/2010, 10h55
  2. Trouver un la handle d'une fenêtre cachée sans FindWindow()
    Par Jean-Philippe Shields dans le forum Windows
    Réponses: 3
    Dernier message: 24/02/2006, 12h08
  3. Coment récupérer le handle d'une fenêtre
    Par robocop2776 dans le forum MFC
    Réponses: 2
    Dernier message: 30/10/2005, 22h21
  4. Réponses: 2
    Dernier message: 10/05/2005, 14h20
  5. Réponses: 2
    Dernier message: 14/03/2004, 22h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo