Limiter le nombre de lignes dans un textbox

Soyez le premier à donner votre avis sur cette source.

Snippet vu 9 600 fois - Téléchargée 19 fois

Contenu du snippet

J'utilise une API pour compter le nombre de lignes.
Il y a plusieurs problématiques :
Si une lettre est ajoutée, le code ne s'execute qu'après l'ajout. Mais on ne peut pas supprimer la dernière lettre du texte car l'utilisateur n'était pas forcément à cette position.
Il faut donc jouer avec SelStart.

Source / Exemple :


' Appel à l'API et déclarations
Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" _
(ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long

Private Const EM_NOMBRELIGNE = &HBA

' Si l'ajout de texte fait dépasser les 4 lignes, on supprime les caractères en trop.
Private Sub Textbox1_Change()
    If (SendMessageLong(Textbox1.hWnd, EM_NOMBRELIGNE, 0&, 0&) > 4) Then
        If Textbox1.SelStart > 0 Then
            Textbox1.SelStart = Textbox1.SelStart - 1
            Textbox1.SelLength = 1
            Textbox1.SelText = ""
        End If
    End If
End Sub

' Si l'utilisateur fait un retour chariot alors qu'il y a 4 lignes, un caractère spécial apparait, ce code l'évite.
Private Sub Textbox1_KeyPress(KeyAscii As Integer)
    If (SendMessageLong(Textbox1.hwnd, EM_NOMBRELIGNE, 0&, 0&) = 4) And (KeyAscii = 10 Or KeyAscii = 13) Then
        KeyAscii = 0
    End If
End Sub

A voir également

Ajouter un commentaire

Commentaires

Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
20
En résumé, cette source est donc inutilisable dans un prog à distribuer. Il faut toujours tester ses codes avant de les publier en n'oubliant jamais qu'avec l'utilisateur le pire est toujours certain.

Ceci reste malgré tout faisable mais pas en modifiant la sélection ni toute autre méthode qui provoque en event EN_CHANGE.
Par WM_SETTEXT est une possibilité, Modifier le texte direct dans le buffer du textbox (EM_GETHANDLE) en est une autre.
Messages postés
2
Date d'inscription
mardi 29 janvier 2002
Statut
Membre
Dernière intervention
31 janvier 2008

Il n'y a pas forcément 4 retours chariots, c'est ailleurs pour ça que je fais appel à l'API. Pense au wordwarp, la textbox fait des retours à la ligne automatiques.

D'autre part je ne supprime pas ce qui dépasse la 4ème ligne, mais je supprime tous les caractères en trop de la dernière frappe de l'utilisateur. Ce qui fait que si tu insères du texte au milieu du texte déjà existant, et que ça te fait dépasser 4 lignes, ce sont tes derniers caractères insérés qui seront supprimés, et non pas la fin du texte.

Brunews, tu as raison, texte trop grand + récursion = dépassement de pile. Note que pour un "petit" copié collé ou pour une frappe classique, il n'y a pas ce problème.
Messages postés
1411
Date d'inscription
mercredi 6 août 2003
Statut
Membre
Dernière intervention
3 mars 2019
1
Par ailleurs, je trouve un peu dommage de supprimer purement et simplement tout ce qui depasse la 4eme ligne.

Pourquoi ne pas supprimer que les retour chariots en trop.

Voici une suggestion qui corrige également le problème d'espace pile :

Private Sub Textbox1_Change()
Dim i As Integer
Dim i2 As Integer
If (SendMessageLong(Textbox1.hWnd, EM_NOMBRELIGNE, 0&, 0&) > 4) Then
'On passe les 4 premiers retour chariots
For i = 1 To 3
i2 = InStr(i2 + 1, Textbox1.Text, vbCrLf)
Next i
If i2 > 0 Then
'On remplace les retours chariots suivants par un caractere au choix
'Ici vbNullString pour supprimer sans remplacer
Textbox1.Text = Left(Textbox1.Text, i2) & Replace(Mid(Textbox1.Text, i2 + 1), vbCrLf, vbNullString)
End If
End If
End Sub
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
20
'Espace de pile doit venir du fait que le code est réentrant (récursion infinie.
Surement du au Text1_Change() qui se rappelle en boucle.
Messages postés
1411
Date d'inscription
mercredi 6 août 2003
Statut
Membre
Dernière intervention
3 mars 2019
1
Désolé d'insister mais il y a bien un problème avec le COPIER/COLLER avec en prime une erreur 'Espace de pile insuffisant' lorsque le text collé est trop long. Une dixaine de ligne suffit. Test simplement avec le code ci-dessus.

Sinon pour la simplification de Textbox1_KeyPress, bien vu, je sais pas pourquoi je me suis pris la tête avec une variable supplementaire.

++
Afficher les 8 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.