2009-06-01 14 views
11

Lorsque vous éditez une légende TLabel dans le concepteur de fiches, il redimensionne TLabel pour vous. Y a-t-il un moyen pour que TMemo puisse le faire, à l'exécution? J'aimerais pouvoir prendre un TMemo, assigner quelque chose à sa propriété .lines.text, puis lui dire de se redimensionner et de ne pas dépasser une certaine largeur, bien qu'il puisse devenir aussi grand qu'il le souhaite . Quelqu'un sait comment faire cela?Puis-je faire une taille TMemo elle-même avec le texte qu'elle contient?

Répondre

6

Définissez la propriété WordWrap de la TMemo true, vider votre texte en elle, compter les lignes, et régler la hauteur au produit du nombre de lignes et la hauteur de la ligne, mais vous devez savoir la ligne la taille. Le TMemo n'expose pas une propriété de hauteur de ligne, mais si vous ne modifiez pas la taille de police ou de police à l'exécution, vous pouvez déterminer la hauteur de ligne expérimentalement au moment du design.

Voici le code que j'ai utilisé pour définir la hauteur du TMemo qui avait une hauteur de ligne de 13 pixels. J'ai également trouvé que j'avais besoin d'une petite constante pour représenter les bordures supérieure et inférieure de TMemo. J'ai limité la hauteur à 30 lignes (396 pixels) pour le garder sur le formulaire.

// Memo.WordWrap = True (at design time) 
Memo.Text := <ANY AMOUNT OF TEXT>; 
Memo.Height := Min(19 + Memo.Lines.Count * 13, 396); 

Si vous devez absolument extraire la hauteur de la ligne de l'objet lors de l'exécution, vous pouvez utiliser Someone's answer. Ou, vous pouvez utiliser TRichEdit, qui a la propriété SelAttributes contenant une propriété Height donnant la hauteur de la ligne.

-Al.

+0

J'aurais dû y penser. Je suis trop habitué à travailler avec TStringLists, qui effectue des sauts de ligne au CRLF, qu'il ne m'est jamais venu à l'esprit que la propriété WordWrap mettrait réellement des lignes encapsulées sur des chaînes .Lines différentes. Merci! –

+0

Police.Height contient un nombre négatif comptant le nombre de pixels dans une ligne de texte. Vous pouvez également appeler Canvas.TextExtent pour que la hauteur du texte soit calculée. –

7

Cela fonctionne très bien pour moi. La constante ajoutée (8) peut varier selon que vous utilisez une bordure et/ou un biseau, expérimentez avec elle.

procedure TForm1.Memo1Change(Sender: TObject); 
var 
    LineHeight: Integer; 
    DC: HDC; 
    SaveFont : HFont; 
    Metrics : TTextMetric; 
    Increase: Integer; 
    LC: Integer; 
begin 
    DC := GetDC(Memo1.Handle); 
    SaveFont := SelectObject(DC, Memo1.Font.Handle); 
    GetTextMetrics(DC, Metrics); 
    SelectObject(DC, SaveFont); 
    ReleaseDC(Memo1.Handle, DC); 
    LineHeight := Metrics.tmHeight; 
    Increase := Memo1.Height; 
    LC := Memo1.Lines.Count; 
    if LC < 1 then 
    LC := 1; 
    Memo1.Height := LC * LineHeight + 8; 
    Increase := Memo1.Height - Increase; 
    Memo1.Parent.Height := Memo1.Parent.Height + Increase; 
end; 
+0

Bonne réponse. J'ai choisi l'autre parce que c'était plus simple, mais ça marche plutôt bien. BTW vous n'avez pas besoin de s'inquiéter de la +8; Vous pouvez simplement affecter ClientHeight et laisser le système s'occuper de la bordure. –

+0

Je sais que c'est vieux, mais j'ai essayé @MasonWheeler suggestion et cela n'a jamais fonctionné correctement. Je crois parce que ClientHeight inclut le remplissage interne que le Memo a. Donc même en définissant ClientHeight vous devez faire un appel à EM_GETRECT pour vraiment calculer l'ajustement de la taille. – Tony

1
procedure TTmpMessage.edMsgChange (Sender: TObject); 
var 
    LineHeight : Integer; 
    DC   : HDC; 
    SaveFont : HFont; 
    Metrics : TTextMetric; 
begin 
    DC := GetDC (TRxRichEdit (Sender).Handle); 
    SaveFont := SelectObject (DC, TRxRichEdit (Sender).Font.Handle); 
    GetTextMetrics (DC, Metrics); 
    SelectObject (DC, SaveFont); 
    ReleaseDC (TRxRichEdit (Sender).Handle, DC); 
    LineHeight := Metrics.tmHeight; 
    Height := TRxRichEdit (Sender).Lines.Count * LineHeight + 32; 
end; 
2

Je l'ai mis en place un TMemo auto-croissance comme un bel exemple de LiveBindings (l'un des rares exemples utiles que je pourrais venir avec pour LiveBindings en VCL).

Une citation de mon Essentials développement Delphi XE2 manuel courseware:

« Pour construire cet exemple, placez un composant TMemo sur un formulaire VCL, ouvrez la propriété LiveBindings et sélectionnez l'option « Nouveau LiveBinding » Choisissez le. . choix TBindExpression Ouvert BindExpressionMemo11 dans l'inspecteur d'objets et mis SourceComponent à Memo1 et SourceExpression à Lines.Count * 22. pour obtenir un meilleur résultat lors de l'exécution, définissez SourceExpression à l'expression plus exacte

Font.Size - 4 + (Lignes.Compte + 1) * -1 * (Police.Hauteur - 3)

Enfin, dans le gestionnaire d'événement OnChange de TMemo, écrivez une ligne de code:

BindingsList1.Notify (Sender, '');

C'est tout. Compilez et courez pour voir le mémo croissant en action.

[capture d'écran]

Dans un premier temps, le contrôle TMemo sera deux lignes haute (la ligne avec le contenu, et une ligne suivante), et chaque fois que nous frappons nous entrer ou avances emballage mot à la ligne suivante, la le contrôle TMemo va croître en hauteur (de plus en plus vers le bas en fait, alors assurez-vous de laisser suffisamment d'espace sur le formulaire pour le TMemo à se développer) «

Groetjes, Bob Swart

+0

J'étais vraiment excité par cette réponse mais cela ne semble plus être une option à partir de XE10 Berlin. – Tony

0

Et pourquoi pas seulement.

Memo1.Height := Memo1.ContentBounds.Height + 5; 
+0

parce que ce n'est pas fmx –