Impression d'un TextBox multilignes

pjouy Messages postés 110 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 18 mai 2009 - 3 sept. 2005 à 21:09
pjouy Messages postés 110 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 18 mai 2009 - 4 sept. 2005 à 19:32
Bonjour,

Je cherche à imprimer un TextBox multilignes qu'un utilisateur remplit, avec éventuellement des retours chariot.
J'arrive à faire ce que je veux, sauf à gérer le fait que si l'utilisateur ne fait que des lignes très longues (sans appuyer sur Entrée), ça sort de la page et ça n'imprime pas la suite...

Quelqu'un aurait une idée, voir du code, pour m'aider, svp ?

18 réponses

Zlub Messages postés 809 Date d'inscription mercredi 11 octobre 2000 Statut Membre Dernière intervention 29 septembre 2010 8
3 sept. 2005 à 21:21
Salut pjouy,

Oui,
forcément, il faut que tu fasses une fonction qui ajoute des sauts de
lignes (en plus de ceux de l'utilisateur) si le texte compris entre
deux sauts de lignes (ou entre debut et fin texte) dépasse un taille
max :



voir



<li>InStr()</li>
<li>Split()</li>
<li>Mid()</li>
<li>TextWidth()

</li>


++

Zlub

<hr size="2" width="100%">
0
pjouy Messages postés 110 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 18 mai 2009
3 sept. 2005 à 21:32
Je suis un peu perdu... Pourrais-tu me donner un exemple avec un Text1.Text ?
0
Zlub Messages postés 809 Date d'inscription mercredi 11 octobre 2000 Statut Membre Dernière intervention 29 septembre 2010 8
3 sept. 2005 à 22:00
Salut,


Bon voici une version supe vite faite, juste pour te montrer le principe. Il te faut Text1 Text2 et un bouton



dans le bouton tu colles :






Dim max As Integer

max = 30



If Len(Text1.Text) < max Then

Text2.Text = Text1.Text

Exit Sub

End If



Dim lignes() As String

lignes = Split(Text1.Text, vbNewLine)



Dim i As Integer

Dim nbLignes As Integer

nbLignes = UBound(lignes)

Dim tmp As String



Text2.Text = vbNullString

For i = 0 To nbLignes

If Len(lignes(i)) > max Then

Dim j As Integer

j = 1

While j <= Len(lignes(i))


Text2.Text = Text2.Text & Mid(lignes(i), j, max) & IIf(j + max
<= Len(lignes(i)), vbCrLf, "")

j = j + max

Wend

Else

Text2.Text = Text2.Text & lignes(i) & IIf(i + 1 < max, vbCrLf, "")

End If

Next i




Tu tappes ton texte dans le text1, puis clic sur bouton -> mise en forme dans text2 ...

++

Zlub

<hr size="2" width="100%">
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
3 sept. 2005 à 22:09
Il y a plus simple en utilisant les API Windows : la fonction DrawText
permet par exemple de spécifier les dimensions d'un rectangle dans
lequel tu veux tracer ton texte, et tu peux gérer le multilignage
automatiquement comme cà.



Voici une petite fonction pour automatiser tout cà :



Private Sub PrintText(ByRef oPrinter As Object, ByVal sText As String,
ByVal lLeft As Long, ByVal lTop As Long, ByVal lWidth As Long, ByVal
lHeight As Long, ByVal lAlignment As Long, Optional ByVal bMultiLine As
Boolean = False)





'======================================================================


'Sub : PrintText


'Date : 07/07/2005


'Auteur : DarK Sidious


'But : Permet d'imprimer du texte avec l'alignement et le multilignage voulu


'======================================================================





'on active la routine de traitement d'erreur


On Error Resume Next


'l'erreur etant minime, on continue l'éxécution normalement





'déclaration des variables privées


Dim iAlignmentX As Integer 'stocke l'alignement sur l'axe X


Dim iAlignmentY As Integer 'stocke l'alignement sur l'axe Y


Dim sPrint As String 'stocke la chaîne à imprimer


Dim pRect As RECT 'stocke le rectangle contenant le texte





Let iAlignmentY = CInt(lAlignment / 3)


Let iAlignmentX = lAlignment Mod 3





Let pRect.Top = lTop / dRapportTwipsPixelsY


Let pRect.Left = lLeft / dRapportTwipsPixelsX


Let pRect.Right = (lLeft + lWidth) / dRapportTwipsPixelsX


Let pRect.Bottom = (lTop + lHeight) / dRapportTwipsPixelsY





Select Case lAlignment





Case 0, 1, 2





Let iAlignmentY = DT_TOP





Case 3, 4, 5





Let iAlignmentY = DT_VCENTER





Case 6, 7, 8





Let iAlignmentY = DT_BOTTOM





End Select





Select Case lAlignment





Case 0, 3, 6





Let iAlignmentX = DT_LEFT





Case 1, 4, 7





Let iAlignmentX = DT_RIGHT





Case 2, 5, 8





Let iAlignmentX = DT_CENTER





End Select





Call DrawText(oPrinter.hdc, sText, Len(sText), pRect, iAlignmentX
Or iAlignmentY Or IIf(bMultiLine, DT_WORDBREAK, DT_SINGLELINE))





End Sub





Il te suffit de l'appeler comme cà :

Call PrintText(Printer, Text1.Text, 0, 0, Text1.Width, Text1.Height, Text1.Alignment, True)

DarK Sidious

Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
pjouy Messages postés 110 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 18 mai 2009
3 sept. 2005 à 23:33
Zlub : J'ai réussi à implémenter ton code, c'est pas mal à ceci près que ça coupe les mots... En revanche, je n'y ai strictement rien compris ;)

DarkSidious : J'ai un problème avec ton code : RECT n'est pas défini. Est-ce que ton code coupe aussi les mots ?
0
Zlub Messages postés 809 Date d'inscription mercredi 11 octobre 2000 Statut Membre Dernière intervention 29 septembre 2010 8
3 sept. 2005 à 23:51
Salut pjouy,

Je sais
bien que ça coupe les mots ... Il faaut avant de couper, vérifier si
l'on est dans un mot ou pas ... donc si le char avant et apres est une
lettre ... ou alors n'est pas un espace ...



si avant espace> alors on coupe

si apres espace> alors on coupe

si avant et apres non espace alors rechercher espace avant le mot avec InStrRev()

++

Zlub

<hr size="2" width="100%">
0
pjouy Messages postés 110 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 18 mai 2009
4 sept. 2005 à 14:36
J'ai réussi à localiser l'endroit où il faut couper avec InStrRev(), le problème après, c'est que si l'utilisateur a mis un retour chariot, celui-ci n'est pas pris en compte (et met donc la suite sur la même ligne...)

Je vais essayer de refaire ça par moi-même (il faut bien apprendre !)
Pour ça, j'ai besoin que tu me dises :
- comment on fait pour détecter un retour chariot
- prendre en compte les caractères qui suivent ceux qu'on a coupés (pour faire une 2ème ligne)

Merci de ton aide !
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
4 sept. 2005 à 17:00
Pourquoi réinventer la roue, la fonction de l'API Windows fait ca à
merveille (elle ne coupe les mots que si tu lui demande, sinon, elle
respecte les mots entiers, elle permet d'alligner le texte, etc.). Elle
est bien plus optimisée qu'une fonction personnelle, et tu peux être
sûr qu'elle fera ce que tu lui demande sans à avoir à trouver un
algorithme !


Je l'utilise depuis belle lurette, et j'ai jamais eu à m'en plaindre !



Tu peux tout faire en utilisant les API, il suffit juste de connaître les bonnes.


DarK Sidious

Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
0
pjouy Messages postés 110 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 18 mai 2009
4 sept. 2005 à 17:48
DarkSidious : Je veux bien utiliser ton API, mais je n'arrive pas à la faire fonctionner : RECT n'est pas défini. Y a-t-il des composants ou références à ajouter ? Si oui lesquelles ?
Cette API est-elle compatible avec TOUS les Windows (à défaut tous les NT) ?

Merci
0
pjouy Messages postés 110 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 18 mai 2009
4 sept. 2005 à 17:52
DaskSidious : Tu fais aussi un Call DrawText , dont je n'ai pas le code...
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
4 sept. 2005 à 18:12
Alors, voici le code au complet :



A mettre dans un module :

Private Declare Function DrawText Lib "user32" Alias "DrawTextA" ( _

ByVal hdc As Long, _

ByVal lpStr As String, _

ByVal nCount As Long, _

lpRect As RECT, _

ByVal wFormat As Long) As Long



Private Type RECT

Left As Long

Top As Long

Right As Long

Bottom As Long

End Type



Private Const DT_TOP As Long = &H0

Private Const DT_BOTTOM As Long = &H8

Private Const DT_CENTER As Long = &H1

Private Const DT_VCENTER As Long = &H4

Private Const DT_LEFT As Long = &H0

Private Const DT_RIGHT As Long = &H2

Private Const DT_SINGLELINE As Long = &H20

Private Const DT_MULTILINE As Long = (&H1)

Private Const DT_WORDBREAK As Long = &H10





Public Sub PrintText(ByRef oPrinter As Object, ByVal sText As String,
ByVal lLeft As Long, ByVal lTop As Long, ByVal lWidth As Long, ByVal
lHeight As Long, ByVal lAlignment As Long, Optional ByVal bMultiLine As
Boolean = False)



'on active la routine de traitement d'erreur

On Error Resume Next

'l'erreur etant minime, on continue l'éxécution normalement



'déclaration des variables privées

Dim iAlignmentX As Integer 'stocke l'alignement sur l'axe X

Dim iAlignmentY As Integer 'stocke l'alignement sur l'axe Y

Dim pRect As RECT 'stocke le rectangle contenant le texte



Let iAlignmentY = CInt(lAlignment / 3)

Let iAlignmentX = lAlignment Mod 3



Select Case lAlignment



Case 0, 1, 2



Let iAlignmentY = DT_TOP



Case 3, 4, 5



Let iAlignmentY = DT_VCENTER



Case 6, 7, 8



Let iAlignmentY = DT_BOTTOM



End Select



Select Case lAlignment



Case 0, 3, 6



Let iAlignmentX = DT_LEFT



Case 1, 4, 7



Let iAlignmentX = DT_RIGHT



Case 2, 5, 8



Let iAlignmentX = DT_CENTER



End Select




Call DrawText(oPrinter.hdc, sText, Len(sText), pRect, iAlignmentX
Or iAlignmentY Or IIf(bMultiLine, DT_WORDBREAK, DT_SINGLELINE))



End Sub



Et pour l'utiliser, il te suffit d'appeler la fonction comme ceci (tu
peux mettre l'instruction dans un événement de bouton_click par
exemple) :

Call PrintText(Printer, Text1.Text, 0, 0, Text1.Width, Text1.Height, Text1.Alignment, True)



La fonction est intégrée dans le système Windows depuis Windows 3.1,
donc tu ne devrais rencontrer aucun problème de compatibilité (elle
marche parfaitement sous Win 95, 98, 2000 et Xp en tout cas !).

DarK Sidious

Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
0
pjouy Messages postés 110 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 18 mai 2009
4 sept. 2005 à 18:32
Pardon si je suis lourd, mais tu as un Call DrawText à la fin de ton code : est-ce une fonction de Windows ou une autre partie d'un code ? Parce que j'ai fait un copier / coller de ton code dans un module dans un nouveau projet avec un TextBox et un bouton, ça suit ton code mais ne produit rien en sortie...
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
4 sept. 2005 à 18:39
Ben si tu colle le code de la fonction perso PrintText, le call ne fait qu'appeler la fonction perso PrintText !



La fonction de l'API est DrawText, que tu déclare en début de code :

Private Declare Function DrawText Lib "user32" Alias "DrawTextA" ( _

ByVal hdc As Long, _

ByVal lpStr As String, _

ByVal nCount As Long, _

lpRect As RECT, _

ByVal wFormat As Long) As Long



Ah oui, j'oubliais, quand tu passe par les API, VB ne sais pas si tu as
envoyer des données à l'imprimante, donc c'est un tout petit peu plus
compliqué :



Call PrintText(Printer, Text1.Text, 0, 0, Text1.Width, Text1.Height, Text1.Alignment, True)

Printer.Print " "

Printer.EndDoc



DrawText n'est pas

DarK Sidious

Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
0
pjouy Messages postés 110 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 18 mai 2009
4 sept. 2005 à 18:40
Pardon, j'ai pas fait gaffe au Private Declare Function DrawText...
N'empêche que j'ai rien en sortie... malgré un Printer.EndDoc
0
pjouy Messages postés 110 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 18 mai 2009
4 sept. 2005 à 18:45
Je suis vraiment ou boulet ou quoi ?? Je n'ai qu'une page blanche, alors que j'ai mis des trucs dans le TextBox, et ai essayé de remplacer les "0" dans le Call PrintText par 100...
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
4 sept. 2005 à 18:45
C'est le Printer.Print " " qui est le plus important !



Regarde si quelque chose est envoyé à l'imprimante déjà...



Je viens de tester chez moi, et ca marche très bien !

DarK Sidious

Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
0
pjouy Messages postés 110 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 18 mai 2009
4 sept. 2005 à 18:55
Voici ce que j'ai mis dans Command1_Click :
Printer.CurrentX 50: Printer.CurrentY 50
Call PrintText(Printer, Text1.Text, 0, 0, Text1.Width, Text1.Height, Text1.Alignment, True)
Printer.Print " test"
Printer.EndDoc

Seul le texte " test" s'imprime"
Pour le reste, j'ai fait un pur copier/coller dans un module, comme tu me l'as dit
0
pjouy Messages postés 110 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 18 mai 2009
4 sept. 2005 à 19:32
Pourrais-tu à la rigueur envoyer le projet afin que je puisse voir ce qui ne va pas ? A moins qu'il en existe un autre sur VBFrance...
0
Rejoignez-nous