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 :

Limiter le nombre de lignes dans un TMemo


Sujet :

Langage Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    111
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 111
    Points : 64
    Points
    64
    Par défaut Limiter le nombre de lignes dans un TMemo
    D4 WXP

    Bonjour à tous,

    Comment limiter le nombre de lignes que l'utilisateur pourra entrer dans un TMemo ?

    Autrement dit, la hauteur du TMemo étant définie, comment faire pour que l'utilisateur ne puisse pas entrer plus de lignes que ce que peut contenir le TMMemo ?

    Pas trouvé dans les FAQ.

    Merci d'avance.

  2. #2
    Membre confirmé

    Inscrit en
    Novembre 2002
    Messages
    743
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 743
    Points : 500
    Points
    500
    Par défaut
    salut ,

    il faut tester la ligne courante du Memo dans le OnkeyPress par exemple.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    procedure TForm7.Memo1KeyPress(Sender: TObject; var Key: Char);
    var Ligne:integer ;
    begin
        Ligne:=SendMessage(memo1.Handle,EM_LineFromChar,memo1.SelStart,0) ;
        if Ligne = 5 then key:=#0;
    end;
    Bye et bon code...

    Ce n'est pas tant l'aide de nos amis qui nous aide , mais notre confiance dans cette aide .

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    111
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 111
    Points : 64
    Points
    64
    Par défaut Limiter le nombre de lignes dans un TMemo
    Merci petitcoucou31.

    Ca marche mais l'utilisateur ne peut plus revenir en arrière avec la touche Retour;

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    322
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2009
    Messages : 322
    Points : 310
    Points
    310
    Par défaut
    Citation Envoyé par Stevens.Georges Voir le message
    Merci petitcoucou31.

    Ca marche mais l'utilisateur ne peut plus revenir en arrière avec la touche Retour;

    Il faut simuler la touche "flèche haut"

    Sinon ceci devrait fonctionner:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        if Memo1.Lines.Count > 5 then             
          Memo1.Lines.Delete(Memo1.Lines.Count);

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 671
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 671
    Points : 13 065
    Points
    13 065
    Par défaut
    Citation Envoyé par Stevens.Georges Voir le message
    la hauteur du TMemo étant définie, comment faire pour que l'utilisateur ne puisse pas entrer plus de lignes que ce que peut contenir le TMMemo ?
    Et la largeur est fixe elle ? Word wrap, pas word wrap ? Quelle utilité ?

    Citation Envoyé par petitcoucou31 Voir le message
    il faut tester la ligne courante du Memo dans le OnkeyPress
    On peut donc ajouter autant de ligne qu'on le souhaite pour autant qu'on édite pas la ligne 5

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    111
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 111
    Points : 64
    Points
    64
    Par défaut Limiter le nombre de lignes dans un TMemo
    Oui, la largeur est fixe mais elle n'intervient pas dans le problème. En effet, la limitation du nombre de lignes doit fonctionner même si l'utilisateur entre un seul caractère par ligne.

    Merci à tous de votre aide mais, sauf erreur de ma part, les solutions proposées jusqu'à maintenant ne fonctionne pas correctement.

  7. #7
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 844
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 844
    Points : 11 274
    Points
    11 274
    Billets dans le blog
    6
    Par défaut
    En réglant TMemo.MaxLength au nombre de lignes * caractères par ligne (avec une police non proportionnelle) ?
    Delphi 5 Pro - Delphi 10.4 Rio Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  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 263
    Points
    3 263
    Par défaut
    Bonjour,

    Ca marche mais l'utilisateur ne peut plus revenir en arrière avec la touche Retour;
    Avec une petite modif comme suit ça devrait gazer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TForm7.Memo1KeyPress(Sender: TObject; var Key: Char);
    var Ligne:integer ;
    begin
        Ligne:=SendMessage(memo1.Handle,EM_LineFromChar,memo1.SelStart,0) ;
        if Ligne = 5 then key:=#08; // key:=#0;
    end;
    avec key:=#08 = BackSpace le retour est automatique.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    111
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 111
    Points : 64
    Points
    64
    Par défaut
    Merci tourlourou. Oui ça devrait marcher mais c'est dommage d'avoir la contrainte d'une police non proportionnelle.

    Merci Gilbert Geyer, ça marche en effet si étant à la dernière ligne l'utilisateur presse une touche de caractère, mais pas si il presse la touche Entrée auquel cas ça passe bel et bien à la ligne suivante.

    Encore merci à tous les deux.

  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 263
    Points
    3 263
    Par défaut
    Re-salut,

    Merci Gilbert Geyer, ça marche en effet si étant à la dernière ligne l'utilisateur presse une touche de caractère, mais pas si il presse la touche Entrée auquel cas ça passe bel et bien à la ligne suivante.
    Bin, dans ce cas if (Ligne = 5) or (key=#13) then key:=#08;

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    111
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 111
    Points : 64
    Points
    64
    Par défaut
    Merci Gilbert Geyer mais ça ne marche pas.

    Fais un bout d'essai et tu verras que plus aucune touche ne répond à l'exception de Entrée, ce qui fait que l'utilisateur ne peut plus rien écrire dans le Memo.

    A+.

  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 263
    Points
    3 263
    Par défaut
    Bonjour,

    Stevens.Georges : Fais un bout d'essai et tu verras ...
    Oui, Oups !!! , j'ai vu.

    Mais ce code 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
    procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: Char);
    var Li, Co, i: integer; 
    begin
      if Memo1.Lines.Count > 5 then begin
        for i := Memo1.Lines.Count - 1 downto 6 do Memo1.lines.Delete(i);
      end;
      with Memo1.CaretPos do begin Co := X; Li := Y; end;
      if (Li = 5) and (key = #13) then key := #0;
    end;
     
    procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    var Li, Co: integer; S: string;
    begin
      with Memo1.CaretPos do begin Co := X; Li := Y; end;
      StatusBar1.Panels[0].Text := Format(' Col %d Li %d', [Co, Li]); StatusBar1.Update;
      if (Li = 5) then begin
        S := Memo1.Lines[5];
        case Key of
          VK_RETURN, VK_DOWN: Key := 0;
          VK_RIGHT: begin if Co >= length(S) then Key := VK_BACK; end;
        end;
      end;
    end;
    Je n'ai pas trouvé plus simple car KeyPress laissait passer les touches du pavé de flèches, et l'insertion de texte dans le texte rallongeait bien entendu la longueur et le nombre de lignes.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    322
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2009
    Messages : 322
    Points : 310
    Points
    310
    Par défaut
    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
    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
        if memo1.lines.count<6 then timer1.enabled:=false else begin
           keybd_event(VK_Back,0,0,0); //enfoncer
           keybd_event(VK_Back,0,KEYEVENTF_KEYUP,0); //relever touche
        end;
    end;
     
    procedure TForm1.Memo1KeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin
         if memo1.lines.count<6 then exit;
         timer1.Interval:=50;
         timer1.enabled:=true;
    end;
    Ça fonctionne...

    Ça pourrait être plus simple, si cela ne te dérange pas que le timer soit toujours en fonction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
        if memo1.lines.count<6 then exit;
        keybd_event(VK_Back,0,0,0); //enfoncer
        keybd_event(VK_Back,0,KEYEVENTF_KEYUP,0); //relever touche
    end;
    Ce qui est en faite la suggestion de mon premier message...


    Finalement si tu n'aimes pas que le curseur se retrouve à la ligne 6 (caret 5) (inspiré de Gilbert):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
        if memo1.lines.count>5 then begin
           keybd_event(VK_Back,0,0,0); //enfoncer
           keybd_event(VK_Back,0,KEYEVENTF_KEYUP,0); //relever touche
           exit;
        end;
        if memo1.CaretPos.y=5 then begin
           keybd_event(VK_Left,0,0,0); //enfoncer
           keybd_event(VK_Left,0,KEYEVENTF_KEYUP,0); //relever touche
        end;
    end;

  14. #14
    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 263
    Points
    3 263
    Par défaut
    Bonjour,

    sgmsg : Ça pourrait être plus simple...
    Effectivement car l'utilisation de Memo1KeyPress était une fausse piste et le Memo1.lines.Delete(i) que j'y avais ajouté à la dernière minute pour tenir compte du cas d'insertion de texte dans le texte (par exemple avec un copier coller de 20 lignes) remplace avantageusement la traque des appuis-touches-clavier de l'utilisateur, d'où la simplification suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TForm1.Memo1Change(Sender: TObject);
    var n: integer;
    begin
      n := Memo1.Lines.Count;
      if n > 5 then Memo1.lines.Delete(n - 1);
    end;
    Ce code fonctionne comme une boucle car chaque Delete déclenche un nouvel évènement onChange.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    111
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 111
    Points : 64
    Points
    64
    Par défaut
    Bonjour et un grand merci à tous les deux Gilbert et sgmsg.

    Finalement je pense que je vais adopter le dernier code de sgmsg qui fonctionne parfaitement et est très simple.

    Merci encore, j'aurais été incapable de trouver par moi-même la solution.

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    322
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2009
    Messages : 322
    Points : 310
    Points
    310
    Par défaut
    Citation Envoyé par Stevens.Georges Voir le message
    Bonjour et un grand merci à tous les deux Gilbert et sgmsg.

    Finalement je pense que je vais adopter le dernier code de sgmsg qui fonctionne parfaitement et est très simple.

    Merci encore, j'aurais été incapable de trouver par moi-même la solution.
    Voici encore plus simple, efficace, professionnel (pas de décalage de curseur animé qui fait marche arrière visuellement) et... inspiré de Gilbert

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TForm1.Memo1Change(Sender: TObject);
    begin
         if memo1.lines.count>5 then begin
             memo1.lines.delete(5);
             exit;
         end;
         if memo1.CaretPos.y=5 then begin
              keybd_event(VK_Left,0,0,0); //enfoncer
              keybd_event(VK_Left,0,KEYEVENTF_KEYUP,0); //relever touche
         end;
    end;

  17. #17
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    111
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 111
    Points : 64
    Points
    64
    Par défaut
    Citation Envoyé par sgmsg Voir le message
    Voici encore plus simple, efficace, professionnel (pas de décalage de curseur animé qui fait marche arrière visuellement) et... inspiré de Gilbert

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TForm1.Memo1Change(Sender: TObject);
    begin
         if memo1.lines.count>5 then begin
             memo1.lines.delete(5);
             exit;
         end;
         if memo1.CaretPos.y=5 then begin
              keybd_event(VK_Left,0,0,0); //enfoncer
              keybd_event(VK_Left,0,KEYEVENTF_KEYUP,0); //relever touche
         end;
    end;
    C'est super !

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

Discussions similaires

  1. Limiter le nombre de lignes dans un TMemo
    Par Stevens.Georges dans le forum Langage
    Réponses: 5
    Dernier message: 07/05/2015, 03h38
  2. [VB.NET][WindowsForm]Limiter le nombre de ligne dans un datagrid
    Par jota5450 dans le forum Windows Forms
    Réponses: 4
    Dernier message: 03/01/2007, 17h21
  3. limiter le nombre de lignes dans un etat
    Par karim15 dans le forum Bases de données
    Réponses: 1
    Dernier message: 12/12/2006, 23h48
  4. Limiter la taille des lignes dans un TMemo
    Par butch dans le forum Composants VCL
    Réponses: 5
    Dernier message: 29/03/2006, 14h08
  5. [C#] Limité le nombre de lignes dans une DataView ...
    Par maitrebn dans le forum Accès aux données
    Réponses: 5
    Dernier message: 08/11/2005, 00h57

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