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

Langage Delphi Discussion :

Connaitre le mot sous le curseur dans une cellule d'une StringGrid


Sujet :

Langage Delphi

  1. #1
    Membre habitué

    Homme Profil pro
    Direction financière et formateur en gestion et contrôle de gestion
    Inscrit en
    Mai 2003
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Direction financière et formateur en gestion et contrôle de gestion
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2003
    Messages : 194
    Points : 127
    Points
    127
    Par défaut Connaitre le mot sous le curseur dans une cellule d'une StringGrid
    Bonjour à tous,
    Bon ... je me casse la tête ...
    L'idée : je fais un clic droit sur une cellule d'une StingGrid et je souhaiterai avoir le mot sous le curseur dans le hint par exemple.

    Je rââââââmeuuu

    J'ai bricolé avec le code de la FAQ concernant le composant TStringGrid, ça donne 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
     
    procedure Grid1ContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
    Var
       Col,Row: Longint;
       ClientPoint,ScreenPoint: TPoint;
       S:String;
       myRect: TGridRect;
       ed: TInplaceEdit;
    begin
         GetCursorPos(ScreenPoint);
         ClientPoint := Grid1.ScreenToClient(ScreenPoint);
         Grid1.MouseToCell(ClientPoint.X, ClientPoint.Y, Col, Row);
     
              Grid1.Row:=Row;
              myRect.Left:=Col;
              myRect.Top:=Row;
              myRect.Right:=Col;
              myRect.Bottom:=Row;
              Grid1.Selection:=myRect;
              ActiveControl:=Grid1; // Donne le focus à la grille
              Grid1.EditorMode:=true; // passe la grille en mode édition
              ed:= GetInPlaceEdit(Grid1);
              if ed<>Nil
              then begin
                   // extraire le mot, mais comment faire ?
              end;
    end;
    Ca sélectionne bien la cellule, ça la mets bien en édition, mais rien, ed est toujours à Nil donc je ne peux pas continuer ...
    Quelqu'un à une idée ???
    Merci pour l'aide en tout les cas.

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 202
    Points : 41 443
    Points
    41 443
    Billets dans le blog
    63
    Par défaut
    Bonjour,
    sans conviction car je ne comprends pas vraiment l'utilité du code, un clic droit ne sélectionne pas la grille ? Je n'ai jamais essayé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ed:=Grid1.Cells[col,row]
    par contre, j'aurais évité de nommer ces variables col et row à cause de la confusion

  3. #3
    Membre habitué

    Homme Profil pro
    Direction financière et formateur en gestion et contrôle de gestion
    Inscrit en
    Mai 2003
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Direction financière et formateur en gestion et contrôle de gestion
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2003
    Messages : 194
    Points : 127
    Points
    127
    Par défaut
    L'idée n'est pas de sélectionner la grille ou une cellule, ça c'est simple, mais, de capter le mot sous le curseur lors d'un clic droit

    Par exemple : Dans la grille ci-dessous, mon curseur est sur le mot "SAPEURS", si je fais un clic droit, je souhaite mettre ce mot dans une variable.
    Nom : Capture.JPG
Affichages : 391
Taille : 18,9 Ko

    Dans mon code, la partie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    GetCursorPos(ScreenPoint);
         ClientPoint := Grid1.ScreenToClient(ScreenPoint);
         Grid1.MouseToCell(ClientPoint.X, ClientPoint.Y, Col, Row);
    renvoie Row et Col = ligne et la colonne de la cellule sous le curseur

    Dans la faq, il parlent de TInplaceEdit, je me suis dit que c'était peut être une piste ... notamment parce qu'il parlent de la possibilité du selstart avec TInplaceEdit (TInplaceEdit(StringGrid1.Components[0]).selstart)

    Mais ... je n'arrive à rien ...

  4. #4
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 759
    Points : 5 482
    Points
    5 482
    Par défaut
    L'événement OnContextPop fournit un paramètre MousePos de type TPoint qui te fournit tout ce que tu as besoin.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    procedure Grid1ContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
    Var
       ACol, ARow : Integer;
       WordUnderMouse : String;
    begin
       Grid1.MouseToCell(MousePos.X, MousePos.Y, ACol, ARow);
     
       WordUnderMouse := Grid1.Cells[ACol, ARow];
    end;

  5. #5
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 202
    Points : 41 443
    Points
    41 443
    Billets dans le blog
    63
    Par défaut
    @popo

    j'ai l'impression que ce qui est voulu n'est pas le contenu entier de la cellule mais uniquement le mot, dans l'image fournie ce serait donc SAPEURS
    c'est d'ailleurs pour cela que j'ai supprimé une de mes réponses

  6. #6
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 405
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 405
    Points : 3 171
    Points
    3 171
    Par défaut
    Bonjour,

    oui, c'est le mot qu'il veut et non le contenu de la cellule. Voici ce que je propose en complément de Popo :

    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
    { ======================================================================== }
    procedure TForm1.StringGrid1ContextPopup(Sender: TObject; MousePos: TPoint;
      var Handled: Boolean);
    Var
       ACol, ARow : Integer;
       WordUnderMouse : String;
       Mots : TStringList ;     // Liste des mots de la cellule pointée
       i : Integer ;
       Taille : Array of Integer ;   // Tailles cumulées des mots de la cellule pointée
       XMot  : Integer ;    // Abscisse locale de la souris
       iMot  : Integer ;    // Numéro du mot pointé
    begin
       StringGrid1.MouseToCell(MousePos.X, MousePos.Y, ACol, ARow);
     
       WordUnderMouse := StringGrid1.Cells[ACol, ARow];
       XMot := MousePos.X - XDeb(ACol) ;
       // Séparation du contenu de la cellules en mots
       Mots := TStringList.Create ;
       Try
         SplitString(WordUnderMouse, ' ',Mots) ;
         SetLength(Taille, Mots.Count) ;
         Taille[0] := StringGrid1.Canvas.TextWidth(Mots.Strings[0]+' ') ;
         For i := 1 To Mots.Count-1 Do
           Taille[i] := Taille[i-1]+ StringGrid1.Canvas.TextWidth(Mots.Strings[i]+' ') ;
         Imot := -1 ;
         For i := 0 To  Mots.Count - 1 Do
           Begin
             If (XMot < Taille[i]) Then
               Begin
                 IMot := i ;
                 Break
               End ;
           End ;
         If IMot >= 0 Then ShowMessage('Mot sous le curseur : '+Mots.Strings[IMot]) ;  
         SetLength(Taille, 0) ;
       Finally
         Mots.Free ;
       End ;
    end;
    { ======================================================================== }
    Function TForm1.XDeb(Col : Integer) : Integer ;
    // Abscisse du début de la colonne Col
    Var
      i : Integer ;
      Posi : Integer ;
    Begin
      Posi := 0 ;
      For i := 0 To Col-1 Do
        Posi := Posi + StringGrid1.ColWidths[i] ;
      Result := Posi ;  
    //
    End ;
    { ======================================================================== }
    Certainement à améliorer ...

    A+
    Charly

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 665
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 665
    Points : 25 459
    Points
    25 459
    Par défaut
    Le seul moyen après avoir récupérer le contenu de la cellule, serait calculer la longueur du texte pour chaque mot espace compris via ExtractStrings* et TextWidth et ainsi déterminer quel mot se trouve sous la souris

    ExtractStrings, ExtraireMots ou Explode qui découpe mots et séparateurs

    EDIT : Grillé par Charly910

    Effectivement, c'est d'une grande simplicité

    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
    procedure TZooThomVCLMainForm.LabelMotsMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    var
      Mots: System.Types.TStringDynArray;
      Mot: string;
      K, W: Integer;
    begin
      if SLT.Common.StrUtilsEx.Explode(LabelMots.Caption, Mots, ' ', True, '', True) > 0 then
      begin
        K := 0;
        for Mot in Mots do
        begin
          W := LabelMot.Canvas.TextWidth(Mot);
          if (K <= X) and (X <= K + W) then
          begin
            LabelMot.Caption := Mot;
            Exit;
          end;
          Inc(K, W);
        end;
      end
    end;
    Code dfm : 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
    object LabelMots: TLabel
      Left = 133
      Top = 696
      Width = 282
      Height = 13
      Caption = 'Bonjour c'#39'est le syst'#232'me qui d'#233'tecte les mots sous la souris'
      ParentShowHint = False
      ShowHint = True
      OnMouseMove = LabelMotsMouseMove
    end
    object LabelMot: TLabel
      Left = 135
      Top = 715
      Width = 43
      Height = 13
      Caption = 'LabelMot'
    end

  8. #8
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 405
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 405
    Points : 3 171
    Points
    3 171
    Par défaut
    Bonjour,

    petite amélioration possible : il parait que TextWidth n'est pas très précis et ne fonctionne bien qu'avec une police fixe. On peut donc remplacer la fonction TextWidth par la fonction de LadyWasky :

    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
    { ======================================================================== }
    function TextSize(Phrase:string;police:TFont=nil):TPoint;
    var
      DC: HDC;
      X: Integer;
      Rect: TRect;
      C : TBitmap;
    begin
      C := TBitmap.create;
    try
      if police <> nil then  C.canvas.Font := police;
     
        Rect.Left := 0;
        Rect.Top:=0;
        Rect.Right:=0;
        Rect.Bottom:=0;
        DC := GetDC(0);
        C.Canvas.Handle := DC;
        DrawText(C.Canvas.Handle, PChar(Phrase), Length(Phrase), Rect, (DT_EXPANDTABS or DT_CALCRECT));
        C.Canvas.Handle := 0;
        ReleaseDC(0, DC);
        result.X:=Rect.Right;
        result.Y:=Rect.Bottom;
    finally
      C.Free;
    end;
    end;
    { ======================================================================== }
    Je n'ai pas personnellement testé ...

    A+
    Charly

  9. #9
    Membre habitué

    Homme Profil pro
    Direction financière et formateur en gestion et contrôle de gestion
    Inscrit en
    Mai 2003
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Direction financière et formateur en gestion et contrôle de gestion
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2003
    Messages : 194
    Points : 127
    Points
    127
    Par défaut
    alors là je suis tombé de ma chaise!
    Merci pour ces belles réponses.
    Je n'avais jamais fait attention que MousePos était déjà déclaré, du coup, je simplifie mon code
    #----------------
    Essai du code et ...

    Charly910 - 11h14
    J'ai recopié le code mais à ta ligne 20, le compilateur me dit "trop de paramêtres originaux" : function SplitString(const S, Delimiters: string): TStringDynArray;
    Donc, en partant du constat que SplitString renvoie un TStringDynArray et en me servant du code de ShaiLeTroll, j'ai corrigé le code comme 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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    procedure TForm1.StringGrid1ContextPopup(Sender: TObject; MousePos: TPoint;
      var Handled: Boolean);
    Var
       ACol, ARow : Integer;
       WordUnderMouse : String;
       Mots : TStringList ;     // Liste des mots de la cellule pointée
       Mots:System.Types.TStringDynArray; 
       i : Integer ;
       Taille : Array of Integer ;   // Tailles cumulées des mots de la cellule pointée
       XMot  : Integer ;    // Abscisse locale de la souris
       iMot  : Integer ;    // Numéro du mot pointé
    begin
       StringGrid1.MouseToCell(MousePos.X, MousePos.Y, ACol, ARow);
     
       WordUnderMouse := StringGrid1.Cells[ACol, ARow];
       XMot := MousePos.X - XDeb(ACol) ;
       // Séparation du contenu de la cellules en mots
       Mots := TStringList.Create ;
    
       Try
         SplitString(WordUnderMouse, ' ',Mots) ;
         Mots:=SplitString(WordUnderMouse, ' ');
         SetLength(Taille, Mots.Count) ;
         SetLength(Taille, High(Mots)+1) ;
         Taille[0] := StringGrid1.Canvas.TextWidth(Mots.Strings[0]+' ') ;
         Taille[0] := StringGrid1.Canvas.TextWidth(Mots[0]+' ') ;
         For i := 1 To Mots.Count-1 Do
         For i := 1 To High(Mots) Do
           Taille[i] := Taille[i-1]+ StringGrid1.Canvas.TextWidth(Mots.Strings[i]+' ') ;
           Taille[i] := Taille[i-1]+ Grid1.Canvas.TextWidth(Mots[i]+' ') ;
         Imot := -1 ;
         For i := 0 To  Mots.Count - 1 Do
         For i := 1 To High(Mots) Do
           Begin
             If (XMot < Taille[i]) Then
               Begin
                 IMot := i ;
                 Break
               End ;
           End ;
         If IMot >= 0 Then ShowMessage('Mot sous le curseur : '+Mots.Strings[IMot]) ;  
         If IMot >= 0 Then ShowMessage('Mot sous le curseur : '+Mots[IMot]) ;
         SetLength(Taille, 0) ;
       Finally
         Mots.Free ;
       End ;
    end;
    Et c'est SUPER! CA FONCTIONNE PARFAITEMENT!

    Après remplacer TextWidth par la fonction de LadyWasky, la fonction TextWidth renvoie un nombre de pixel, LadyWasky renvoie un TPoint ... punaise je buggue ... comment on passe d'un TPoint à un Integer ?

  10. #10
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 678
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 678
    Points : 7 093
    Points
    7 093
    Par défaut
    Citation Envoyé par patrice@ Voir le message
    Après remplacer TextWidth par la fonction de LadyWasky, la fonction TextWidth renvoie un nombre de pixel, LadyWasky renvoie un TPoint ... punaise je buggue ... comment on passe d'un TPoint à un Integer ?
    Je suppose que TPoint.X correspond à la longueur, et TPoint.Y à la hauteur du texte.

  11. #11
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 405
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 405
    Points : 3 171
    Points
    3 171
    Par défaut
    Bonjour Patrice,

    oui désolé, j'avais oublié de mettre la fonction SplitString que j'avais "bricolée" et déclarée :

    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
    { ======================================================================== }
    Procedure TForm1.SplitString(MyText : String; Separator : String;Var  Split : TStringList );
    var
      p : integer ;         // Position du séparateur
    begin
      // Création du StringList
      Split := TStringList.Create ;
     
      // Première position du séparateur
      p := Pos(Separator, MyText) ;
      // Tant que le séparateur est trouvé
      while p <> 0 do
      begin
        // --Ajout au début de la chaine
        Split.Add(Copy(MyText, 0, p - 1)) ;
        // --Mise à jour de la chaine
        MyText := Copy(MyText, p + Length(Separator), Length(MyText)) ;
        // --Recherche du separateur
        p := Pos(Separator, MyText) ;
      end ;
      // Ajoute la fin de chaine
      Split.Add(MyText) ;
    end ;
    { ======================================================================== }
    Ce que tu as fait est mieux ! (utiliser la fonction standard)

    Pour la fonction de LadyWasky, je pense effectivement que la composante X doit représenter la largeur du texte en pixel. L'avantage c'est que cela fonctionne avec des polices exotiques si tu la modifie dans ta grille.

    A+
    Charly

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

Discussions similaires

  1. Position du curseur dans une stringgrid
    Par jyvesb dans le forum Composants VCL
    Réponses: 1
    Dernier message: 06/10/2013, 11h21
  2. Cellule du curseur dans une stringgrid
    Par jyvesb dans le forum Composants VCL
    Réponses: 1
    Dernier message: 04/10/2013, 17h14
  3. Curseur dans une stringgrid
    Par sebyo dans le forum Composants VCL
    Réponses: 2
    Dernier message: 30/06/2009, 09h36
  4. Réponses: 10
    Dernier message: 22/05/2004, 13h51
  5. Obtenir la position du curseur dans une Image
    Par bastoune dans le forum Composants VCL
    Réponses: 6
    Dernier message: 14/11/2003, 21h02

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