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

C++Builder Discussion :

Clavier visuel. Comment ça marche ?


Sujet :

C++Builder

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France, Drôme (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2006
    Messages : 78
    Points : 81
    Points
    81
    Par défaut Clavier visuel. Comment ça marche ?
    Bonjour à tous,

    J'ai besoin d'aide pour réaliser un clavier virtuel dans le genre du "clavier visuel windows". A priori, il suffit de réaliser une application fenêtre qui envoie des codes de touches à une autre application lorsque l'on clique sur elle.
    Mais le problème est que, lorsque l'on clique sur le clavier, l'autre application pert naturellement le focus.
    Comment faut-il donc faire pour laisser le focus sur l'application qui avait le focus avant l'"activation" du clavier?

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France, Drôme (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2006
    Messages : 78
    Points : 81
    Points
    81
    Par défaut
    Comment retrouver le handle d'une fenêtre qui avait le focus immédiatement avant l'activation de la nouvelle fenêtre?

  3. #3
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Points : 3 766
    Points
    3 766
    Par défaut
    Salut engrobel
    A l'aide d'un utilitaire comme Spy++ par exemple, on peut recuperer le nom d'une fenetre donc sont Handle a l'aide " FindWindow "
    Un exemple apres avoir ouvert Excel j'ai besoin de recuperer le Handle de la fenetre puis de la barre de commande je fais comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     // ici le fichier Excel est charge
     // on va recuperer le Handle de la fenetre ainsi que celui de la barre de menus
    HWND h = FindWindow("XLMAIN", NULL);
    HWND h1 = FindWindowEx(h, NULL, "EXCEL2", NULL);
    HWND h2 = FindWindowEx(h1, NULL, "MsoCommandBar", "Barre de menus Feuille de calcul");
     // on selectionne la Barre de menus
    .....

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France, Drôme (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2006
    Messages : 78
    Points : 81
    Points
    81
    Par défaut
    Bonjour blondelle,

    Pour utiliser FindWindow il faut connaitre le nom ou la classe de la fenêtre. Celle-ci n'est a priori pas connue de l'application clavier. Tout ce qui est connu c'est que la fenêtre avait le focus juste avant! Windows doit stocker dans une pile la liste des fenêtres activées mais je ne connais par la fonction qui permet d'y accéder!

  5. #5
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Points : 3 766
    Points
    3 766
    Par défaut
    Pour connaitre le nom il faut utiliser soit Spy++ de Visual C++ soit WinSight32 de BCB

  6. #6
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    Citation Envoyé par blondelle Voir le message
    Pour connaitre le nom il faut utiliser soit Spy++ de Visual C++ soit WinSight32 de BCB
    Donc ... on devrait pouvoir faire la même chose qu'eux !

    On peut s'amuser à faire ceci (c'est juste un début ...) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    HWND hDeskTop;
    HWND hWindow;
    char Buffer[1024]; // <<... ça devrait aller !!!
    Je vais faire écho de tout ce que je trouve dans un memo :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Memo1->Clear();
    hDeskTop = GetDesktopWindow();
    hWindow  = GetTopWindow(hDeskTop);
    while(hWindow != NULL)
        {
        if(IsWindow(hWindow))
            {
            GetClassName(hWindow, Buffer, 1024);
            //Donc ici on tient le nom de la classe
            Memo1->Lines->Add(Buffer);
            }
        hWindow = GetNextWindow(hWindow, GW_HWNDNEXT);
        }
    Ma foi ... après ... ???

    A plus !

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France, Drôme (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2006
    Messages : 78
    Points : 81
    Points
    81
    Par défaut
    Bonjour henderson.
    Ca me parait être un bon début. Je vais expérimenter!

  8. #8
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 390
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    Ensuite il existe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    BOOL PostMessage(
     
        HWND hWnd,	// handle of destination window
        UINT Msg,	// message to post 
        WPARAM wParam,	// first message parameter
        LPARAM lParam 	// second message parameter
       );
    Pour les messages clavier il y a :

    WM_ACTIVATE
    WM_CHAR
    WM_DEADCHAR
    WM_GETHOTKEY
    WM_HOTKEY
    WM_KEYDOWN
    WM_KEYUP
    WM_KILLFOCUS
    WM_SETFOCUS
    WM_SETHOTKEY
    WM_SYSCHAR
    WM_SYSDEADCHAR
    WM_SYSKEYDOWN
    WM_SYSKEYUP
    Le tout ... c'est de cibler la bonne fenêtre !

    A plus !

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France, Drôme (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2006
    Messages : 78
    Points : 81
    Points
    81
    Par défaut
    En filtrant les 235 fenêtres trouvées, je suis arrivé à trouver une solution.
    La bonne fenêtre est enregistrée dans le handle focusedWindow.
    Le filtrage consiste à supprimer la fenêtre courante, les fenêtres invisibles, les fenêtres sans nom et (dans mon cas) RocketDock qui apparait systématiquement en premier plan.
    Après cela, la première fenêtre détectée est la bonne. Ca reste malgré tout à vérifier!
    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
     
      HWND hWindow;
      HWND hDeskTop;
      char Buffer[1024]; // <<... ça devrait aller !!!
     
      Memo1->Clear();
      hDeskTop = GetDesktopWindow();
      hWindow  = GetTopWindow(hDeskTop);
      while(hWindow != NULL)
      {
        if(IsWindowVisible(hWindow)  && hWindow != Handle)
        {
            GetClassName(hWindow, Buffer, 1024);
            //Donc ici on tient le nom de la classe
    //        Memo1->Lines->Add(Buffer);
     
            GetWindowText(hWindow,Buffer,1024);
            if (!AnsiString (Buffer).IsEmpty() &&
                 AnsiString (Buffer) != "RocketDock")
            {
              Memo1->Lines->Add(Buffer);
              focusedWindow = hWindow;
              return;
            }
     
        }
        hWindow = GetNextWindow(hWindow, GW_HWNDNEXT);
      }

  10. #10
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Points : 3 766
    Points
    3 766
    Par défaut
    Suite a une recherche sur le Forun j'ai trouve ce lien
    et j'ai effectue un teste sur une Form, un Button, un Edit, un Memo
    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
     
    void __fastcall TForm1::FormClick(TObject *Sender)
    {
    char buf[300];
    HWND Handle;
    HWND Handle1;
    HWND Handle2;
    HWND Handle3;
    // on recupere le Handle sous la souris
    Handle = WindowFromPoint(Mouse->CursorPos);
    // on change le titre
    SetWindowText(Handle,"Titre Form");
    // on recupere le titre
    GetWindowText(Handle,buf,300);
    // on affiche le titre
    Label1->Caption = buf;
    Handle1 = GetWindow(Handle ,GW_CHILD);
    SetWindowText(Handle1,"Texte TEdit");
    GetWindowText(Handle1,buf,300);
    Label2->Caption = buf;
    Handle2 = GetWindow(Handle1 ,GW_HWNDNEXT);
    SetWindowText(Handle2,"Caption Button");
    GetWindowText(Handle2,buf,300);
    Label3->Caption = buf;
    Handle3 = GetWindow(Handle2 ,GW_HWNDNEXT);
    SetWindowText(Handle3,"Texte Memo");
    GetWindowText(Handle3,buf,300);
    Label4->Caption = buf;
    }
    //---------------------------------------------------------------------------

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France, Drôme (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2006
    Messages : 78
    Points : 81
    Points
    81
    Par défaut
    Bon, j'ai donc réussi à faire fonctionner mon clavier 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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    void __fastcall TForm1::GetFocusWindows(void)
    {
      HWND hWindow;
      HWND hDeskTop;
      char Buffer[1024]; // <<... ça devrait aller !!!
     
      hDeskTop = GetDesktopWindow();
      hWindow  = GetTopWindow(hDeskTop);
      while(hWindow != NULL)
      {
        if(IsWindowVisible(hWindow)  && hWindow != Handle)
        {
            GetWindowText(hWindow,Buffer,1024);
            if (!AnsiString (Buffer).IsEmpty() &&
                 AnsiString (Buffer) != "RocketDock")
            {
              focusedWindow = hWindow;
              return;
            }
        }
        hWindow = GetNextWindow(hWindow, GW_HWNDNEXT);
      }
    }
     
     
    //------------------------------------------------------------------------void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        GetFocusWindows();
     
         //Met le Focus "clavier" sur la fenètre spécifiée
         SetForegroundWindow(focusedWindow);
         ::SetFocus(focusedWindow);
     
         //Envoi le code touche
         SendKeys("A");
    }
    Lorsque le bouton est cliqué, je récupère le handle de la fenêtre qui avait le focus avant le clique, je mets la fenêtre en avant plan et j'envoie les codes de touche.

    Le bref changement de focus entre la fenêtre et le clavier pourrait être évité si je savais comment créer une fenêtre qui ne prend pas le focus focus quand on clique dessus!

    Quelqu'un sait-il comment programmer une telle fenêtre sous C++ Builder?
    En fait une fenêtre qui se comporte comme la barre de tâche de windows!

Discussions similaires

  1. Comment faire un clavier visuel?
    Par Ludo_360 dans le forum Delphi
    Réponses: 12
    Dernier message: 02/05/2007, 15h03
  2. Comment afficher le clavier visuel ?
    Par crossrobotik dans le forum MFC
    Réponses: 1
    Dernier message: 30/01/2007, 14h38
  3. [SYNEDIT] -> Comment ça marche ?
    Par MaTHieU_ dans le forum C++Builder
    Réponses: 2
    Dernier message: 18/01/2004, 19h11
  4. [TP][Turbo Vision] comment ça marche ??
    Par Costello dans le forum Turbo Pascal
    Réponses: 7
    Dernier message: 05/08/2003, 00h24
  5. [update][req. imbriquee] Comment ca marche ??
    Par terziann dans le forum Langage SQL
    Réponses: 3
    Dernier message: 11/07/2003, 12h51

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