Komponent i zakończenie tekstu ciągiem: '...'

0

Cześć, piszę sobie komponent pochodzący od TListBox.

2 Sprawy. Po pierwsze, zrobiłem numerowanie elementów, tzn. np:

  1. Item1
  2. Item2

Itd.
Nazwałem tą właściwość Numbered no i typu boolean. Problem pierwszy polega na tym, że jak robię dwuklik na tej właściwości w Object Inspectorze, to wtedy zamiast tego, co wyżej, pojawia się:

    1. Item1
    1. Item2

itd.
(gdy odwołuje się do właściwości w kodzie, lub nie robię dwukliku, tylko wybieram z listy w OI, to wszystko jest ok).

Jaki może być tego powód?

A teraz główny wątek.

Chcę, aby mój komponent kończył item łańcuchem: '...', jeśli jego długość jest większa niż sam komponent. Warunek sprawdzam tak:

if canvas.textWidth(item)>width then...

I właśnie, co wtedy?

  1. Jak poznać, po którym miejscu mam obciąć resztę itemu i wstawić '...'
  2. Jeśli ktoś rozszerzy komponent, to jak powrócić do tego, co było wcześniej napisanie?

Myślałem o jakiejś dodatkowej tablicy, która by przechowywała wszystkie itemy, ale to chyba niezbyt dobre rozwiązanie...

Chodzi dokładnie o taką rzecz:


|1. To jest zbyt dł...|
| |
| |

A jak ktoś go rozszerzy, ma być, to co powinno, np:


|1. To jest zbyt długi łańcuch, żeby się zmieścił w krótkim ListBoxie |
| |
| |
| |

0

zamiast TextOut wypisuj teźt DrawText z formatowaniem DT_END_ELLIPSIS

0
Misiekd napisał(a)

zamiast TextOut wypisuj teźt DrawText z formatowaniem DT_END_ELLIPSIS

Kurde, coś mi nie wychodzi.
Zrobiłem taki kod:

if ATruncate then //jeśli masz obcinać, to obcinaj
  begin
    for i:=0 to count-1 do
    begin
      if canvas.TextWidth(items[i])>width then
      begin
        r:=canvas.ClipRect;
        drawText(handle, PChar(items[i]), 5, r, DT_END_ELLIPSIS);
      end;
    end;
  end;

Wcześniej jako długość tekstu w drawText podawałem length(items[i]), ale potem zmieniłem, żeby zobaczyć, że może błąd leży w tym. Ale nie. Po prostu nic się nie robi. Item, jak był wyświetlany, tak jest. Może podaje mu źle recta, może handle? Nie wiem.
(handle to oczywiście handle do mojego listBoxa)

0
if ATruncate then //jeśli masz obcinać, to obcinaj
begin
  for i:=0 to count-1 do
  begin
    r:=canvas.ClipRect;
    DrawText(Canvas.Handle, PChar(items[i]), Length(items[i]), r, DT_END_ELLIPSIS);
  end;
end;
0

No tak, handle canvasa...

Jeszcze jeden problem:
jeśli np. napis wychodzi tak, że mieści się jeszcze jakaś część literki, to wtedy robi się tak, że dodaje ten wielokropek, ale po nim zostawia tą część tej literki.

0
Juhas napisał(a)

No tak, handle canvasa...

Jeszcze jeden problem:
jeśli np. napis wychodzi tak, że mieści się jeszcze jakaś część literki, to wtedy robi się tak, że dodaje ten wielokropek, ale po nim zostawia tą część tej literki.

daj screena bo nie wiem, jak to wygląda

0
Misiekd napisał(a)
Juhas napisał(a)

No tak, handle canvasa...

Jeszcze jeden problem:
jeśli np. napis wychodzi tak, że mieści się jeszcze jakaś część literki, to wtedy robi się tak, że dodaje ten wielokropek, ale po nim zostawia tą część tej literki.

daj screena bo nie wiem, jak to wygląda

Daje screena i jeszcze jedno pytanie:
Jak się pozbyć tej otoczki na zaznaczonym itemie?
Chodzi mi o tą otoczkę, co się pojawia, przy focusie.

Próbowałem: canvas.pen.style:=psClear, ale nic nie dało.

A oto screen:
user image

0

daj kod całej procki, która wyświetla texty tych itemów

0
Misiekd napisał(a)

daj kod całej procki, która wyświetla texty tych itemów

for i:=0 to count-1 do
    begin
      if canvas.TextWidth(items[i])>=width-5 then
      begin
        r:=itemRect(i);
        r.Left:=r.Left+FLeftMargin;
        drawText(canvas.Handle, PChar(items[i]), length(items[i]), r, DT_END_ELLIPSIS);
      end else drawItem(i, itemRect(i), []);
    end;

w warunki nieważne, czy jest width-5, czy samo width.
FLeftMargin to właściwość, którą dodałem - wiadomo, lewy margines
DrawItem tu jest nieważne, bo bez niego tez tak dziko było

I jeszcze 2 pytania. Czy można dać jakiś inny łańcuch, zamiast tego: '...', np.,żeby to wyglądało jakoś lepiej, możnaby dać: ' ... ' (ze spacjami). Jest taka możliwość?

No i jak się pozbyć tej kropkowanej linii, która się pojawia na zaznaczonym itemie, gdy listBox ma focus?

0

jak wygląda ta funkcja itemRect i ta drawItem?

0
Misiekd napisał(a)

jak wygląda ta funkcja itemRect i ta drawItem?

ItemRect to jest funkcja z ListBoxa i zwraca TRect konkretnego itema.
Natomiast w drawItem napisałem coś takiego:
(nie trzeba brać tego pod uwagę, bo bez tego było tak samo)

Połowiczne rozwiązanie dopisane na dole

procedure TJNumListBox.DrawItem(Index: Integer; Rect: TRect;
  State: TOwnerDrawState);
var
 a: byte;
begin
  if style=lbOwnerDrawFixed then a:=2 else a:=0; {potrzebne do dobrej obsługi mojej właściwości LeftMargin}

  rect.Left:=FLeftMargin-a;
  inherited;
  if FTruncateItem then setTruncateItem(FTruncateItem, Index);
end;

Tutaj setTruncateItem robi to samo, co TruncateItem(tzn. dodaje ten wielokropek), ale tylko na jednym itemie
(jest to potrzebne m.in. wtedy, gdy się klika na item - bez tego traci wielokropek)

Znalazłem pewien sposób. Otóż trzeba dodać coś do rect.right(dokładnie długość tej kolejnej literki, tylko jak ją sprawdzić dokładnie?), a także do parametru length w funkcji drawText.
Ale kolejny problem jest taki, że nie zawsze widać 3 kropki. Czasem widać 2, czasem jedną.

1 użytkowników online, w tym zalogowanych: 0, gości: 1