Je suis en train de mettre au point la solution avec la ScrollBox et les résultats sont assez encourageants (Ouf!).
Version imprimable
Je suis en train de mettre au point la solution avec la ScrollBox et les résultats sont assez encourageants (Ouf!).
Bon, allez, voici ma modeste contribution.
J'ai mis mon TMemo dans une Scrollbox
Au fur et à mesure que l'on tape le texte, la taille du mémo s'adapte automatiquement.
Sub0, tu n'as plus qu'à faire deux choses :
- Prendre en compte la taille des scrollbars dans cette partie du code :
Si il y en a une qui apparait, il faut reconsidérer la largeur et la hauteur de la "lucarne" d'affichage de la scrollbox, qui se trouve diminuée de la hauteur ou largeur des dites scrollbars.Code:
1
2 if NewHeight<ScrollBox1.Height then NewHeight:=ScrollBox1.Height-4; if NewWidth<ScrollBox1.Width then NewWidth:=ScrollBox1.Width-4;
- ajouter du code pour initialiser les dimensions du memo dans le OnShow de la fiche par exemple.
Bref, C'est assez similaire à ta méthode, c'est basé sur mon code "Comment connaître la largeur et la hauteur en pixels d'un texte ?" dans la FAQ, et ça marche avec les retour chariot et le WordWrap Activé ou désactivé ;)
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 Function TailleTexte(UnMemo:TMemo) : TPoint; var DC: HDC; X: Integer; Rect: TRect; C : TBitmap; uFormat:cardinal; UnTexte:string; begin UnTexte:=UnMemo.Lines.Text; C := TBitmap.create; C.canvas.Font := UnMemo.Font; Rect.Left := 0; Rect.Top:=0; Rect.Right:=0; Rect.Bottom:=0; if UnMemo.WordWrap then rect.Right:=UnMemo.ClientWidth; DC := GetDC(0); C.Canvas.Handle := DC; uFormat:=DT_EXPANDTABS or DT_CALCRECT; if UnMemo.WordWrap then uFormat:=uFormat or DT_WORDBREAK; DrawText(C.Canvas.Handle, PChar(UnTexte), Length(UnTexte), Rect, uFormat); C.Canvas.Handle := 0; ReleaseDC(0, DC); result.X:=Rect.Right-Rect.Left; result.Y:=Rect.Bottom-Rect.Top; C.Free; end; procedure AutosizeMemo(UnMemo:TMemo;AScrollBox:TScrollBox); const MargesScrollBox=4; TailleScrollbar=16; var HauteurTexte,HauteurMemo,HauteurLucarne:integer; LargeurTexte,LargeurMemo,LargeurLucarne:integer; NewHeight,NewWidth:integer; APoint:TPoint; SCBW,SCBH:integer; begin HauteurMemo:=UnMemo.ClientHeight; LargeurMemo:=UnMemo.ClientWidth; APoint:=TailleTexte(UnMemo); HauteurTexte:=APoint.Y; LargeurTexte:=APoint.X; if HauteurTexte<>HauteurMemo then NewHeight:=HauteurTexte; if LargeurTexte<>LargeurMemo then NewWidth:=LargeurTexte; HauteurLucarne:=AScrollBox.Height-MargesScrollBox; LargeurLucarne:=AScrollBox.Width-MargesScrollBox; if NewHeight<HauteurLucarne then NewHeight:=HauteurLucarne; if NewWidth<LargeurLucarne then NewWidth:=LargeurLucarne; UnMemo.Width:=NewWidth; UnMemo.Height:=NewHeight; end; procedure TForm1.Memo1Change(Sender: TObject); begin AutosizeMemo(Memo1,ScrollBox1); end;
Je vais, dans un 1er temps, terminé ce que j'ai commencé, après on étudiera, si vous le voulez bien, le code pour essayer d'optimiser. Bien entendu, je vais essayer le code ci-dessus. La différence avec ma méthode, c'est que le memo est posé sur la scrollbox et pas dedans... En tous les cas, pour l'instant, la gestion de la scrollbar verticale fonctionne vraiment nickel avec mon code, j'obtiens exactement le même comportement qu'avec un memo standart (molette, déplacement curseur, sélection du texte, clic sur l'ascenceur, etc...). Il ne me reste plus qu'à faire la même chose avec la barre horizontale. Seulement, comme je n'ai pas de paramètre équivalent à EM_GETFIRSTVISIBLELINE, je galère un peu pour terminer cette démo...
Voilà, j'ai enfin trouvé le moyen d'obtenir la position de la scrollbar horizontale, un équivalent de EM_GETFIRSTVISIBLELINE. "y" est la longueur du texte jusqu'au curseur et "pt" retourne la position relative du curseur dans le memo... ce qui fait que le curseur de la scrollbar se positionne maintenant automatiquement :
GetCaretPos(pt);
Position := (y - pt.X);
Je poste tout à l'heure une démo avec cette méthode, à+
J'ai testé ton code waskol. Il fonctionne bien excepté que les scrollbars ne bougent pas lorsqu'on sélectionne le texte qui se trouve masqué... Cette fonction est nécessaire pour mon projet. En fait, j'ai besoin de conserver exactement le même comportement qu'un Memo standart.
En ce qui concerne la démo que je devais poster, ça devra attendre car je n'arrive pas à scroller correctement le memo lorsqu'on clique sur les scrollbars. Cela dit, contrairement à toi, waskol, mon code fonctionne parfaitement lorsqu'on déplace le curseur, ou que l'on sélectionne du texte dans le memo, les scrollbars sont bien déplacées... Peut-être qu'à nous deux, on arrivera à quelque chose de correcte... J'espère !
;)
Salut,
Je vois que vous vous cassez la tête sur ce problème de taille de scrollbar
mais pourquoi pas faire un truc tout simple avec 2 petits boutons et une trackbar au milieu ou quelque chose d'équivalent, puis d'utiliser la procedure
?Code:
1
2 ScrollBy(DeltaX,DeltaY);
Moi j'dit ça comme ça...:roll:
Ta solution ne fait que déplacer le memo avec la trackbar mais pas l'inverse :
En effet, il est difficile de reproduire les scrollbars d'un memo et d'obtenir le même comportement :
• Le déplacement de l'ascenceur lorsque le curseur est en bout de page ou lorsqu'on sélectionne du texte hors affichage
• Le déplacement de l'ascenceur avec la molette = déplacement du memo sans toucher à la position du curseur
• Le déplacement de l'ascenceur avec les boutons de la scrollbar (= molette)
• La possibilité de redimensionner le memo = les scrollbars s'ajustent aux nouvelles dimensions