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 :

Recupérer contenu controle actif d'une autre application win32


Sujet :

Windows Forms

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 123
    Points : 85
    Points
    85
    Par défaut Recupérer contenu controle actif d'une autre application win32
    Bonjour à tous,

    Je souhaite pouvoir récupérer le contenu du controle actif d'une application au moment de l'utilisation d'un raccourci clavier.

    En gros, vous travaillez sur une application win32 Lambda (APISOFT XCS dans mon cas), et vous utilisez alors un raccourci clavier qui activera une seconde application (que j'écrirai). Cette seconde application doit pouvoir récupérer la chaine de caractère qui était en cours de saisie (donc le contenu du champ actif) dans la première application

    Mais je ne sais pas du tout comment procéder...
    Enregistrer un raccourcis clavier au niveau du système ce n'est pas un soucis, mais accéder à l'autre application par contre ....

    Je sais que c'est possible, des programmes comme Revelation par exemple le font au survol de la souris...

    Une idée, une piste ?

    Merci d'avance

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 123
    Points : 85
    Points
    85
    Par défaut
    Je pensais commencer par recherche la fenêtre active

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    [System.Runtime.InteropServices.DllImport("user32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto, ExactSpelling=true)]
    public static extern IntPtr GetForegroundWindow();
    Mais après je ne suis gère avancé ...

    comment connaitre la sous fenêtre (container MDI) active ?

    puis le controle de la sous fenêtre actif ?

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 123
    Points : 85
    Points
    85
    Par défaut
    J'ai essayé ceci :
    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
     
     
    [System.Runtime.InteropServices.DllImport("user32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto, ExactSpelling=true)]
    public static extern IntPtr GetActiveWindow();
     
    [System.Runtime.InteropServices.DllImport("user32")]
    public static extern int GetWindowThreadProcessId(IntPtr hwnd, ref int lpdwProcessId);
     
    [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, ExactSpelling = true)]
    public static extern IntPtr GetFocus();
     
    [System.Runtime.InteropServices.DllImport("user32", CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    public static extern int AttachThreadInput(int idAttach, int idAttachTo, int fAttach);
     
    public int Test() {
        // On récupère l'id du thread de l'application locale
        int myProcessId = 0;
        int myThreadId = GetWindowThreadProcessId(this.Handle, ref myProcessId);
        // On récupère l'id du thread de l'application active 
        int actProcessId = 0;
        int actThreadId = GetWindowThreadProcessId(GetActiveWindow(), ref actProcessId);
        // On attache les processus
        AttachThreadInput(myThreadId, actThreadId, 1);
        // On récupère le handle actif
        int toReturn = GetFocus();
        // On détache les processus
        AttachThreadInput(myThreadId, actThreadId, 0);
        return toReturn;
    }
    Mais cela ne marche pas.

    actThreadId et myThreadId sont corrects (vérifiés avec spy.exe)

    Mais AttachTheadInput échoue (retourne 0)

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 123
    Points : 85
    Points
    85
    Par défaut
    J'ai aussi essayé ceci :

    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
     
    [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct Rect {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }
     
    [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public class GuiThreadInfo {
        public uint cbSize;
        public uint flags;
        public IntPtr hwndActive;
        public IntPtr hwndFocus;
        public IntPtr hwndCapture;
        public IntPtr hwndMenuOwner;
        public IntPtr hwndMoveSize;
        public IntPtr hwndCaret;
        public Rect rcCaret;
    }
     
    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    public static extern bool GetGUIThreadInfo(int idThread, ref GuiThreadInfo lpgui);
     
     
    public IntPtr test() {
        int myProcessId = 0;
        int myThreadId = GetWindowThreadProcessId(this.Handle, ref myProcessId);
        var info = new GuiThreadInfo();
        info.cbSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(info);
        GetGUIThreadInfo(myThreadId, ref info);
        return info.hwndActive;
     
    }
    Mais cela ne marche pas non plus (GetGUIThreadInfo échoue)

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 123
    Points : 85
    Points
    85
    Par défaut
    Bon finalement j'ai réussi !
    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
     
            const int WM_GETTEXT = 0x000D;
     
            [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, ExactSpelling = true)]
            public static extern IntPtr GetForegroundWindow();
     
            [System.Runtime.InteropServices.DllImport("user32")]
            public static extern int GetWindowThreadProcessId(IntPtr hwnd, ref int lpdwProcessId);
     
            [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, ExactSpelling = true)]
            public static extern IntPtr GetFocus();
     
            [System.Runtime.InteropServices.DllImport("user32", CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
            public static extern int AttachThreadInput(int idAttach, int idAttachTo, int fAttach);
     
            [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
            public static extern bool GetGUIThreadInfo(int idThread, out GuiThreadInfo lpgui);
     
            [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
            public struct Rect {
                public int Left;
                public int Top;
                public int Right;
                public int Bottom;
            }
     
            [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
            public struct GuiThreadInfo {
                public uint cbSize;
                public uint flags;
                public IntPtr hwndActive;
                public IntPtr hwndFocus;
                public IntPtr hwndCapture;
                public IntPtr hwndMenuOwner;
                public IntPtr hwndMoveSize;
                public IntPtr hwndCaret;
                public Rect rcCaret;
            }
     
            [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SendMessage")]
            public static extern int SendMessage (IntPtr hwnd, uint wMsg, int wParam, StringBuilder lParam);
    Et les appels eux mêmes (Je sais ce n'est pas très propre, mais c'est juste ma procédure de test):

    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
     
            /// <summary>
            /// Gestion des évènements système
            /// </summary>
            /// <param name="m"></param>
            protected override void WndProc(ref System.Windows.Forms.Message m) {
                base.WndProc(ref m);
                if (m.Msg == WM_HOTKEY) {
                    int actProcessId = 0;
                    int actThreadId = GetWindowThreadProcessId(GetForegroundWindow(), ref actProcessId);
                    var info = new GuiThreadInfo();
                    info.cbSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(info);
                    if (GetGUIThreadInfo(actThreadId, out info)) {
                    // On récupère le texte
                    StringBuilder chaine = new StringBuilder(151);
                    SendMessage(info.hwndFocus, WM_GETTEXT, 150, chaine);
                    ....
                    }
             }
    Donc on enregistre un raccourci clavier, et on lance le traitement ci-dessus

    Avec AttachThreadInput je n'arrive pas à faire marcher ... tant pis ... Si quelqu'un voit où je me suis planté ...

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

Discussions similaires

  1. controle d'une autre application
    Par subtil2 dans le forum Général VBA
    Réponses: 1
    Dernier message: 19/04/2008, 23h01
  2. Mettre en avant plan une autre application...
    Par loupdeau dans le forum MFC
    Réponses: 13
    Dernier message: 19/05/2005, 13h26
  3. Réponses: 7
    Dernier message: 23/03/2005, 22h23
  4. Recuper les items de ListBox d'une autre application [API?]
    Par Shamanisator dans le forum API, COM et SDKs
    Réponses: 3
    Dernier message: 27/09/2002, 12h32

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