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

Delphi Discussion :

Comment faire un clavier visuel?


Sujet :

Delphi

  1. #1
    Membre habitué Avatar de Ludo_360
    Profil pro
    Étudiant
    Inscrit en
    Avril 2007
    Messages
    295
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2007
    Messages : 295
    Points : 191
    Points
    191
    Par défaut Comment faire un clavier visuel?
    bonjour

    je cherche une solution pour récupérer le focus dans une application extérieur que je ne suis pas censé connaitre.
    Je dois pouvoir récupérer le handle de l'application où se situe le focus.
    puis avec un postmessage j'envoi un 'string' la ou se situe le curseur toujours.

    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
     
    // extrait du prog
     
    Var
      hWindow: HWND;
      pt: TPoint;
      pIconInfo: TIconInfo;
      dwThreadID, dwCurrentThreadID: DWORD;
      Hd_proc : THandle;
     
    procedure TForm_Clavier.SendString(s : String);
    begin
      Hd_proc:= GetCursorHandle;
      // pour l'instant afficher juste une lettre me conviendrait .. :(
      PostMessage(Hd_proc,WM_CHAR,Ord('t'),0);
    end;
     
    function Tform_clavier.GetCursorHandle: Hcursor;
    begin
       // Trouver l'application ou il y a le curseur
      GetCursorPos(pt);
      hWindow := WindowFromPoint(pt);
     
      // Récupère le  thread ID ou le cursor se situe.
      dwThreadID := GetWindowThreadProcessId(hWindow, nil);
     
       // Récupère thread ID de l'application courante
      dwCurrentThreadID := GetCurrentThreadId;
     
      // Si le curseur est dans une application différente de la notre
      // on utilise GetCursor() pour renvoyer le hcursor correcte
      if (dwCurrentThreadID <> dwThreadID) then
      begin
        if AttachThreadInput(dwCurrentThreadID, dwThreadID, True) then  begin
          // Récupère le handle du curseur
          Result := GetCursor;
          showmessage('test');
          AttachThreadInput(dwCurrentThreadID, dwThreadID, False);
        end;
      end else begin
         Result := GetCursor;
      end;
    end;
     
     
    procedure TForm_Clavier.ButtonClick(Sender: TObject);
    begin
      // click sur une touche
      SendString('toto');
    end;
     
    end.

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    624
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 624
    Points : 754
    Points
    754
    Par défaut
    Peux tu expliquer ton projet?( context, objectif, but à atteindre...)
    Envoyer des strings partout comme un maboul ok, mais il n'ya pas que des TEdit ou des TMemo qui prennent le focus dans les applications.

  3. #3
    Membre habitué Avatar de Ludo_360
    Profil pro
    Étudiant
    Inscrit en
    Avril 2007
    Messages
    295
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2007
    Messages : 295
    Points : 191
    Points
    191
    Par défaut com un maboul... je suis en train de le devenir :cry:
    Je dois réaliser un clavier visuel et je suis bien d'accord qu'il n'y a pas que des Tedit ou des Tmemo.. c'est bien la la difficulté.

    Mon clavier visuel doit remplir les mêmes objectifs que ceux du clavier visuel windows, je dois trouver le focus dans n'importe quelle application ouverte, et écrire au niveau de ce focus par click de souris sur mon application( qui du coup détient le focus).

    La difficulté est de récupérer le focus d'une application avant que mon application reprenne le focus. Je ne connais pas très bien toutes les fonctions delphi alors je viens ici pour bénéficier de l'expérience des géveloppeurs.

    ++

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    624
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 624
    Points : 754
    Points
    754
    Par défaut
    Maintenant c'est clair. J'ai cru un instant que tu cherchais a faire un logiciel de spam.

    Ca doit être réalisable avec AttachThreadInput... Si je trouve le temps je ferais un test.


    Penses à mettre en ou :delestage: tes anciens post.

    @+

  5. #5
    Membre habitué Avatar de Ludo_360
    Profil pro
    Étudiant
    Inscrit en
    Avril 2007
    Messages
    295
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2007
    Messages : 295
    Points : 191
    Points
    191
    Par défaut attachthreadinput
    J'utilise déja attachthreadinput.. Mais je dois oublier quelque chose

    Je trouve mon programme logique, mais j'ai beau modifier quelques trucs il n'y a aucun changement.

    Je désespère on dirait que personne ne sait comment faire...

    ++

  6. #6
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Juste quelques remarques :

    1) procedure TForm_Clavier.ButtonClick(); : je commencerais par remplacer le TButton par n'importe quel type de bouton (SpeedButton par ex) qui ne prend pas le focus lors du click ... car ButtonClick lance SendString qui lance GetCursorHandle ce qui en bonne logique donne le Handle du Button en question et non celui de l'appli de la fenêtre de l'appli externe qui avait le focus auparavent.

    2) Lorque je clickes dans la fenêtre de l'appli externe pour lui donner le focus, cela rend l'appli Delphi inactive tant que l'autre détient le focus et pendant ce temps les routines de l'appli Delphi sont en sommeil et ne peuvent détecter le "Si le curseur est dans une application différente de la notre" n'est-ce-pas?

    Bien que ceci ne donne pas la réponse du comment faire, cela donne à mon avis au moins une idée sur ce qui semble illogique dans le code.

    Je me demande s'il ne faudrait pas dans un TForm1.Timer1Timer() enregistrer, dans une variable globale HandleCible, à intervalles réguliers (tant que l'appli Delphi est active), le handle HCourant de la fenêtre ou du contrôle qui se situe sous le curseur-souris lors des déplacements de la souris et en même temps y guetter l'appui sur le bouton-gauche-souris avec bGSouris:=getAsyncKeyState(VK_LButton); et de considérer que le HandleCible est le dernier handle enregistré par cette variable globale à l'instant où l'appui sur le bouton-gauche-souris est détecté et qu'il passe le focus à l'autre appli.
    En placant juste après le bGSouris:=getAsyncKeyState(VK_LButton); une instruction disant if bGSouris=0 then HandleCible:=0 else HandleCible:=HCourant et au début de la routine Timer1Timer un if HandleCible=0 alors suivre-ce-qui-se-passe-avec-la souris else EXIT; cela préserverait le contenu de la variable HandleCible sans être modifié par le ou les clicks qui re-donnent le focus à l'appli Delphi au retour.

    Et la procédure MonBoutonClick se réduirait à une instruction qui envoie la String 'toto' à HandleCible suivie immédiatement de l'instruction HandleCible:=0 qui déverrouille le Timer1Timer qui se remet à suivre-ce-qui-se-passe-avec-la-souris pour la suite des événements.

    P.S : on pourrait également essayer d'afficher 'toto' avec SetWindowText(HandleCible,Texte); où var Texte : array[0..1000] of Char;

  7. #7
    Membre habitué Avatar de Ludo_360
    Profil pro
    Étudiant
    Inscrit en
    Avril 2007
    Messages
    295
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2007
    Messages : 295
    Points : 191
    Points
    191
    Par défaut :)
    meric pour ces quelques conseils.

    C'est vrai que mon code est illogique , c'était d'ailleurs bien mon problème puisque je ne connais pas assez toutes ces fonctions dont tu me parles.

    En tout cas je vais revoir ça, merci!

    ++

  8. #8
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Rassure-toi je ne connais pas non plus toutes les fonctions et leurs comportements. Mais comme pour apprendre à nager il faut se jeter à l'eau et nager on n'a pas le choix ... y'a des jours où l'on brasse du code sans avancer et d'autres où l'on avance au point d'être content de sa journée.

    Espérons que les pistes données apporteront une amélioration à ton problème.

  9. #9
    Membre habitué Avatar de Ludo_360
    Profil pro
    Étudiant
    Inscrit en
    Avril 2007
    Messages
    295
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2007
    Messages : 295
    Points : 191
    Points
    191
    Par défaut ok je me mets à nager
    Je galère pour trouver la façon de récupérer le handle sous le pointeur de la souris.(... fin de journée lol)

    Je te remercie pour l'aide je pense que ça va vraiment m'aider.

  10. #10
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Salut,

    J'ai testé le code suivant qui marche :

    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
    //Insérer texte dans lucarne-texte d'applis externes :
     
    var HCible : HWnd;
     
    procedure TfrmEmetteur.Timer1Timer(Sender: TObject);
    var       HCourant : HWnd;
              SourisBG,SourisBD : integer;
    begin     if HCible<>0 then EXIT; // <: indispensble pour préserver le contenu de HCible d'une modif lors du mouvement de retour de la souris vers le bouton bEnvoyer
              HCourant:=WindowFromPoint(Mouse.CursorPos);
              label1.caption:='HCourant = '+intToStr(HCourant);
              sourisBG:=getAsyncKeyState(VK_LButton);
              sourisBD:=getAsyncKeyState(VK_RButton);
              if (sourisBG<>0) or (sourisBD<>0)
              then HCible:=HCourant;
              label2.caption:='HCible = '+intToStr(HCible);
    end;
     
    procedure TfrmEmetteur.bEnvoyerClick(Sender: TObject);
    var       //Texte : array[0..1000] of Char;
              Texte2 : string;
              i : integer;
    begin     // 1ère approche :
              //Texte:='tagada texte à envoyer vers fen qui a le focus-clavier';
              //SetWindowText(HCible,Texte); <: ne marche que si HCible est sur Form émettrice
     
              // 2ème approche qui marche mieux :
              Texte2:='texte à insérer dans dernière lucarne pointée par un click-souris marquant le point d''insertion';
              for i:=1 to length(Texte2)
              do PostMessage(HCible,WM_CHAR,Ord(Texte2[i]),0); //<: marche avec cibles tEdit, tMemo, tRichEdit où ReadOnly:=false;
              HCible:=0; label2.caption:='';
    end;
     
    initialization
               HCible:=0;
               // avec en plus fsStayOnTop pour la Form
    end.
    Cela a marché pour insérer du texte dans des cibles externes tEdit, tMemo, tRichEdit si leur ReadOnly:=false (sinon rien ne se passe).
    Cela a aussi marché pour insérer le texte par exemple dans le champ 'adresse' d'Internet Exploreur.
    Bizarrement cela n'a pas marché pour insérer du texte dans l'éditeur de Delphi.
    Mais cela a aussi marché dans la présente lucarne de saisie du Forum: texte à insérer dans dernière lucarne pointée par un click-souris marquant le point d'insertion

  11. #11
    Membre habitué Avatar de Ludo_360
    Profil pro
    Étudiant
    Inscrit en
    Avril 2007
    Messages
    295
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2007
    Messages : 295
    Points : 191
    Points
    191
    Par défaut fonctionne aussi
    Moi aussi j'ai réussi à faire fonctionner mon programme en suivant ton conseil avec le timer.
    Pour l'éditeur de texte Delphi je pense savoir pourquoi ça ne marche pas:

    Dans mon programme de test je me servais d'un edit pour afficher le handle au niveau du pointeur de souris: celui ci évolue selon sa position sur un bouton, une barre de tache, une fenetre (internet explorer) mais quand on se déplace dans l'éditeur de texte de delphi il garde la même valeur sur toutes les lignes et toutes les colonnes.

    Je pense qu'il faudrait récupérer la valeur de la position en X et en Y du curseur réellemnt et ainsi afficher du texte à cet endroit précis.

    Tu me dis ce que tu en penses.

    ++

  12. #12
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Pour l'éditeur de texte Delphi je pense savoir pourquoi ça ne marche pas
    Peut-être aussi que l'éditeur de texte Delphi se place automatiquement sur ReadOnly=true par mesure de sécurité dès qu'il n'a plus le focus et l'inverse quand on re-clique dedans. Je ne vois pas pourquoi on devrait lui dire écris-moi-ceci en X,Y alors qu'ailleurs le X,Y est par défaut l'emplacement de l'appli externe où l'on a cliqué pour en détecter le handle. Mais entre-nous, je ne verrais pas l'intéret de l'ancer une appli pour insérer du code dans l'éditeur de Delphi alors que je peux y taper directement le code. Non?

  13. #13
    Membre habitué Avatar de Ludo_360
    Profil pro
    Étudiant
    Inscrit en
    Avril 2007
    Messages
    295
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2007
    Messages : 295
    Points : 191
    Points
    191
    Par défaut logic
    juste un cas d'école...

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 14/01/2009, 18h54
  2. Clavier visuel. Comment ça marche ?
    Par engrobel dans le forum C++Builder
    Réponses: 10
    Dernier message: 22/10/2008, 19h56
  3. Comment faire des commentaires automatique (clavier) sur eclipse ?
    Par poulette3000 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 16/05/2007, 16h54
  4. Comment afficher le clavier visuel ?
    Par crossrobotik dans le forum MFC
    Réponses: 1
    Dernier message: 30/01/2007, 15h38
  5. Réponses: 4
    Dernier message: 07/11/2005, 16h54

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