kibap
Messages postés4Date d'inscriptionlundi 16 avril 2007StatutMembreDernière intervention 2 juillet 2007
-
28 juin 2007 à 15:35
cs_rt15
Messages postés3874Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention 7 novembre 2014
-
2 juil. 2007 à 12:55
Je voudrai utiliser cet Api mais je me heurte à un plantage.
Voici ma déclaration en vb:
Public Declare Function GetTextExtentExPointI Lib "gdi32.dll" (ByVal hdc As Long, ByVal pgiIn As String, ByVal cgi As Long, ByVal nMaxExtent As Long, ByRef lpnFit As Long, ByRef alpDx As Long, ByRef lpSize As SIZE) As Long
Type SIZE
X as long
Y as long
End Type
Voici comment je l'utilise dans mon form:
dim MyString as string
dim lngFit as long
dim lngDx as long
dim lngSize as Size
dim lngRet as long
Dans les specifications de l'Api, le parametre alpDx est définit comme un pointeur vers un array d'integer. J'ai essayé de le remplacer par un tableau de nombre, mais rien n'y fait.
cs_rt15
Messages postés3874Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention 7 novembre 201413 29 juin 2007 à 08:44
Salut,
Que veux tu faire exactement ? Tu as regardé du côté de DrawText, qui gère automatiquement le wrap ?
Voilà un code qui fait un wrap au niveau caractère.
Je me suis pas servi du tableau (Je lui passe NULL)... A ce que je comprend, il stocke la position des caractères qui tiennent sur la ligne, donc j'ai pas compris ce que j'allais pouvoir en faire.
J'ai fait une première implémentation (Redraw1), mais elle me plaisait pas car elle faisait trops de recopie de chaîne.
Donc j'en ai fait une deuxième avec des pointeurs (Redraw2), sensée être nettement plus rapide (Aucune recopie de chaîne).
Attention, y a de l'unicode -> les * 2 un peu partout.
Private Type TEXTMETRIC
tmHeight As Long
tmAscent As Long
tmDescent As Long
tmInternalLeading As Long
tmExternalLeading As Long
tmAveCharWidth As Long
tmMaxCharWidth As Long
tmWeight As Long
tmOverhang As Long
tmDigitizedAspectX As Long
tmDigitizedAspectY As Long
tmFirstChar As Byte
tmLastChar As Byte
tmDefaultChar As Byte
tmBreakChar As Byte
tmItalic As Byte
tmUnderlined As Byte
tmStruckOut As Byte
tmPitchAndFamily As Byte
tmCharSet As Byte
End Type
Const sText As String = "Borland Delphi est un environnement de programmation visuelle orienté objet permettant de développer des applications 32 bits en vue de leur déploiement sous Windows et sous Linux. Avec Delphi, vous pouvez créer de puissantes applications avec un minimum de programmation."
' Pour Redraw1
Private Declare Function GetTextExtentExPoint1 Lib "gdi32" Alias "GetTextExtentExPointA" (ByVal hdc As Long, ByVal lpszStr As String, ByVal cchString As Long, ByVal nMaxExtent As Long, ByRef lpnFit As Long, alpDx As Any, ByRef lpSize As SIZEL) As Long
' Pour Redraw2
Private Declare Function GetTextExtentExPoint2 Lib "gdi32" Alias "GetTextExtentExPointW" (ByVal hdc As Long, ByVal lpszStr As Long, ByVal cchString As Long, ByVal nMaxExtent As Long, ByRef lpnFit As Long, alpDx As Any, ByRef lpSize As SIZEL) As Long
Private Declare Function TextOut Lib "gdi32" Alias "TextOutW" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As Long, ByVal nCount As Long) As Long
Private Declare Function GetTextMetrics Lib "gdi32" Alias "GetTextMetricsA" (ByVal hdc As Long, lpMetrics As TEXTMETRIC) As Long
Private Sub Form_Paint()
Redraw1
End Sub
Private Sub Form_Resize()
Redraw2
End Sub
Private Sub Redraw1()
Dim nFit As Long ' Nombre de caractères placés dans la ligne
Dim uSize As SIZEL ' Taille prise par le texte
Dim sLine As String ' Une ligne à afficher
Dim sToDraw As String ' Chaîne restant à dessiner
' On efface le contenu de la form
Me.Cls
' Il reste tout le texte à dessiner
sToDraw = sText
' Tant qu'il reste du texte à dessiner
While sToDraw <> ""
' On calcule le nombre de caractères affichables dans la ligne
Me.ScaleMode = vbPixels
GetTextExtentExPoint1 Me.hdc, sToDraw, Len(sToDraw), Me.ScaleWidth, nFit, ByVal 0&, uSize
' On récupère les caractères affichables dans la ligne
sLine = Left$(sToDraw, nFit)
' On prépare les caractères suivant pour la ligne suivante
sToDraw = Mid$(sToDraw, nFit + 1, Len(sToDraw) - nFit)
' On dessine la ligne
Print sLine
Wend
End Sub
Private Sub Redraw2()
Dim nFit As Long ' Nombre de caractères placés dans la ligne
Dim uSize As SIZEL ' Taille prise par le texte
Dim uTextMetrics As TEXTMETRIC ' Pour récupérer la hauteur d'une ligne
Dim nY As Long ' Ordonnée de dessin du texte
Dim nBegin As Long ' Début du texte à dessiner
Dim nAdrText As Long ' Adresse de la chaîne
' On efface le contenu de la form
Me.Cls
' Récupération de la hauteur d'une ligne (Devrait être dans Form_Load)
GetTextMetrics Me.hdc, uTextMetrics
' Il reste tout le texte à dessiner
nAdrText = StrPtr(sText)
nBegin = nAdrText
nY = 0
' Tant qu'il reste du texte à dessiner
While nBegin < nAdrText + Len(sText) * 2
' On calcule le nombre de caractères affichables dans la ligne
Me.ScaleMode = vbPixels
GetTextExtentExPoint2 Me.hdc, nBegin, (nAdrText + Len(sText) * 2 - nBegin) / 2, Me.ScaleWidth, nFit, ByVal 0&, uSize
' On dessine la ligne
TextOut Me.hdc, 0, nY, nBegin, nFit
' On se place sur la suite du texte
nBegin = nBegin + nFit * 2
' Passage à la ligne
nY = nY + uTextMetrics.tmHeight
Wend
End Sub
kibap
Messages postés4Date d'inscriptionlundi 16 avril 2007StatutMembreDernière intervention 2 juillet 2007 29 juin 2007 à 19:02
Merci pour vos réponses.
1. jmfmarques: Je suis sur xp. et c'est du vb.
2. BruNews: Merci pour le tableau. L'appel de la fonction ne plante plus.
3. rt15: Merci, Ton code dans Redraw1 est le même que le mien. sauf que tu écrit sur le formulaire, alors que j'écris dans un Label. A la place de me.scalewidth, j'ai Label1.width.
Mon objectif est juste d'écrire un texte dans un Label avec la possibilité de couper ce dernier (le texte) en mettant des pontillés si celui-ci dépasse la taille de mon label. (Montrer à l'utilisateur que le texte est plus grand que celui affiché).
Donc j'ai besoin de connaitre, suivant ma chaine, le nombre de caractère max que le label peut contenir.
Pour l'instant le nombre de caractère retourné(lngFit) n'est pas bon. J'ai l'impression que je dois convertir la taille du Label1 (label1.width) que je passe à la fonction.
Vos iddées sont les bienvenues.
Merci,
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_rt15
Messages postés3874Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention 7 novembre 201413 2 juil. 2007 à 10:05
Salut,
lngFit pas bonne -> GetTextExtentExPoint2 veut la largeur de l'espace disponible en unité logique. (On peut spécifier la taille d'une unité logique via SetMapMode). A ce que j'ai cru comprendre, VB6 est configuré en MM_TEXT (Une unité = un pixel) par défaut (Mais ça me paraît bizarre...). Mais il propose en plus de changer le système de coordonné pour chaque contrôle, à l'aide de la propriété ScaleMode. Cette propriété change les valeurs de ScaleWidth et ScaleHeight du contrôle courant, et peut modifier les propriété Width et Height des contrôles contenus dans ce contrôle. Par défaut, ScaleMode est à twips.
ajouter le style SS_ENDELLIPSIS -> Pour ça, il faut pouvoir récupérer un handle sur le label : Il faut qu'il est une propriété hwnd (Encore qu'on peut peut être le récupérer avec les routines d'énumération de fenêtre genre une succession de GetWindow). Une fois qu'on a le handle, il devrait suffire de faire un GetWindowLong en passant le handle du label et GWL_STYLE en index. Genre :
dim nStyle As Long
nStyle = GetWindowLong(Label1.hwnd, GWL_STYLE)
Puis on ajoute le style :
nStyle = nStyle or SS_ENDELLIPSIS
(Y a aussi SS_WORDELLIPSIS qui peut peut être plus te convenir)
Et on remet le style en place :
SetWindowLong Label1.hwnd, GWL_STYLE, nStyle
cs_rt15
Messages postés3874Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention 7 novembre 201413 2 juil. 2007 à 12:55
Pas sûr qu'il marche ton SendMessage. D'une part TB_SETSTYLE à l'air d'être fait pour les toolbar, d'autre part, tu zapes les styles que ton contrôle avait : tu remplace au lieu d'ajouter.
Pour le handle, comme je le disais, tu peux le retrouver avec GetWindow, mais c'est très chiant. Les fenêtre forment une arborescence, il te suffit de la parcourir jusqu'à tomber sur ton contrôle. Par exemple, s'il est dans la form, tu commence avec un :
hHandle = GetWindow(Form1.hwnd, GW_CHILD)
puis tu enchaîne avec des :
hHandle = GetWindow(hHandle , GW_HWNDNEXT)
jusqu'à tomber sur ton contrôle... spy++ fournit avec VS permet de connaître la structure de l'arborescence des fenêtres. Mais d'après l'aide, peut être qu'en placant ton contrôle au premier plan (Devant tous les autres), tu tomberas directement dessus avec le premier GW_CHILD.
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 28 juin 2007 à 16:50
Curieux, ton triuc ....
je ne connais pas ta fonction, mais je connais celle-ci :
Private Declare Function GetTextExtentPoint32 Lib "gdi32" Alias "GetTextExtentPoint32A" (ByVal hdc As Long, ByVal lpsz As String, ByVal cbString As Long, lpSize As POINTAPI) As Long
qui n'a que 4 paramètres qui sont les suivants :
· hdc
Identifies the device context.
· lpString
Points to the string of text. The string does not need to be zero-terminated, since cbString specifies the length of the string.
· cbString
Specifies the number of characters in the string.
· lpSize
Points to a SIZE structure in which the dimensions of the string are to be returned.
kibap
Messages postés4Date d'inscriptionlundi 16 avril 2007StatutMembreDernière intervention 2 juillet 2007 2 juil. 2007 à 12:35
Sais-tu comment avoir le handle d'un label en vb?
Je pense suivant ton conseil essayer ceci:
Sendmessage(Mon Label Handle, TB_SETSTYLE, 0,SS_ENDELLIPSIS)