CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Rózne style czcionki w jednym ListBoxie

Rózne style czcionki w jednym ListBoxie

dział ogólny

Rózne style czcionki w jednym ListBoxie

Nowy postprzez lukagrom » wtorek, 24 października 2017, 14:44

Pytanie jak w temacie. Chcę skorzystać z ListBoxów lub czegoś podobnego do wyświetlania danych liczbowo-tekstowych. Czy jest możliwe aby taki wyświetlający komponent mógł generować różne style czcionki w zależności od wartości/warunków jakie dane wyświetla?
Może prostry przykład. Generuje 50 liczb od 1 do 51. Parzyste na niebiesko ze stylem fsItalic, nieparzyste na czerwono z fsBold. Próbuje takich wstawek (jak poniżej), jednakże ListBox generuje mi cały ciąg jednakowo, bez podziału na kolor i styl. (może robie coś zle/niekompletnie?)

Kod: Zaznacz cały
for(i=1;i<51;i++)
{
if(i%2==0)
{
  ListBox4->Font->Color=clBlue;
  ListBox4->Font->Name=fsItalic;
  ListBox4->Items->Add(IntToStr(i));
}
else
{
  ListBox4->Font->Color=clRed;
  ListBox4->Font->Name=fsBold;
  ListBox4->Items->Add(IntToStr(i));
}

}
Avatar użytkownika
lukagrom
Bladawiec
Bladawiec
 
Posty: 37
Dołączył(a): wtorek, 1 stycznia 2013, 14:54
Podziękował : 6
Otrzymał podziękowań: 0
System operacyjny: Windows Vista
Kompilator: C++ Builder 10.1 Starter
Gadu Gadu: 0
    Windows VistaChrome

Re: Rózne style czcionki w jednym ListBoxie

Nowy postprzez Cyfrowy Baron » środa, 25 października 2017, 10:07

Musisz posłużyć się zdarzeniem OnDrawItem i w tym zdarzeniu zmieniać krój czcionki. Tylko, że musisz opracować jakiś sprytny mechanizm, bo w przeciwnym razie czeka cię ustawianie warunków na sztywno poprzez tworzenie długich ciągów zależności bezpośrednio w kodzie.

Właściwość Style obiektu ListBox należy ustawić na lbOwnerDrawFixed.

KOD cpp:     UKRYJ  
void __fastcall TForm1::ListBox1DrawItem(TWinControl *Control, int Index, TRect &Rect,
                  TOwnerDrawState State)
{
 TCanvas *pCanvas = ListBox1->Canvas;


 if(ListBox1->Items->Strings[Index].ToInt() == 1)
 {
  pCanvas->Font->Name = "Stencil";
 }

 if(ListBox1->Items->Strings[Index].ToInt() == 2)
 {
  pCanvas->Font->Name = "Teen";
 }

 if(ListBox1->Items->Strings[Index].ToInt() == 3)
 {
  pCanvas->Font->Name = "Ravie";
 }

 pCanvas->FillRect(Rect);
 pCanvas->TextRect(Rect, Rect.Left,Rect.Top, ListBox1->Items->Strings[Index]);
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox

Re: Rózne style czcionki w jednym ListBoxie

Nowy postprzez polymorphism » środa, 25 października 2017, 10:26

Nie lepiej te nieładne ify zamienić na
KOD cpp:     UKRYJ  
switch(ListBox1->Items->Strings[Index].ToInt())
{
case 1: pCanvas->Font->Name = "Stencil"; break;
case 2: pCanvas->Font->Name = "Teen";    break;
case 3: pCanvas->Font->Name = "Ravie";      
}

:?:
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: Rózne style czcionki w jednym ListBoxie

Nowy postprzez Cyfrowy Baron » środa, 25 października 2017, 11:13

Można i tak, zakładając, że wiersze będą zawierały wartości uporządkowane od 1 do 51 i będą zawierały tylko liczby. Przypuszczam jednak, że ani to co ja podałem ani to co ty podałeś nie sprawdzi się tutaj w 100%
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox

Re: Rózne style czcionki w jednym ListBoxie

Nowy postprzez lukagrom » środa, 25 października 2017, 12:35

To ja na podstawie kodu Cyfrowego Barona zaproponuje rozwiązanie klasowe. Co prawda kompiluje to mi się,ale pewnie idea nie miała być taka.


KOD cpp:     UKRYJ  

 #include <vcl.h>
class new_LB
{
  private:
   TCanvas *pCanvas;
   TRect r;
   int indeks;

  public:
   new_LB(TListBox *lB,UnicodeString nazwaCzcionki,TColor nowyKolor,TRect rectValue,
   int nr_indeksu);

};
new_LB::new_LB(TListBox *lB,UnicodeString nazwaCzcionki,TColor nowyKolor,TRect rectValue,
int nr_indeksu)
{
        pCanvas=lB->Canvas;
        pCanvas->Font->Name=nazwaCzcionki;
        pCanvas->Font->Color=nowyKolor;
        r=rectValue;
        indeks=nr_indeksu;
        pCanvas->FillRect(r);
        pCanvas->TextRect(r,r.Left,r.Top,lB->Items->Strings[indeks]);
}

void __fastcall TForm1::ListBox1DrawItem(TWinControl *Control, int Index, TRect &Rect,
                  TOwnerDrawState State)
{

  int i;
  for(i=1;i<10;i++)
   if(i%2==0)
   {
        new_LB lBox(ListBox1,"Teen",clBlue,Rect,Index);
        ListBox1->Items->Add(IntToStr(i)+" parzysta");
   }
   else
   {
         new_LB lBox(ListBox1,"Ravie",clRed,Rect,Index);
         ListBox1->Items->Add(IntToStr(i)+" nieparzysta");
   }


}

 
Avatar użytkownika
lukagrom
Bladawiec
Bladawiec
 
Posty: 37
Dołączył(a): wtorek, 1 stycznia 2013, 14:54
Podziękował : 6
Otrzymał podziękowań: 0
System operacyjny: Windows Vista
Kompilator: C++ Builder 10.1 Starter
Gadu Gadu: 0
    Windows VistaChrome

Re: Rózne style czcionki w jednym ListBoxie

Nowy postprzez polymorphism » środa, 25 października 2017, 13:04

To już lepiej zrób metodę, która robi to, co robi konstruktor new_LB, bo teraz to taki przerost formy nad treścią.

ListBox1DrawItem służy do rysowania pozycji o indeksie Index, nie powinieneś tam robić nic innego, tym bardziej dodawać do listy nowe pozycje.

(...) zakładając, że wiersze będą zawierały wartości uporządkowane od 1 do 51

To, czy są uporządkowane, to akurat jest bez znaczenia... zresztą chodziło mi o zoptymalizowanie kodu pod względem stylu i redukcji niepotrzebnych operacji (po co 3x wykonywać ToInt(), jeśli można raz).
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: Rózne style czcionki w jednym ListBoxie

Nowy postprzez Cyfrowy Baron » czwartek, 26 października 2017, 09:08

Rzeczywiście przekombinowane. Jeżeli w OnDrawItem nie zamierzasz nic więcej robić, to nawet tworzenie nowej metody nie ma sensu, że o nowej klasie nie wspomnę.

W zdarzeniu OnDrawItem nie możesz dodawać nowych pozycji, bo to zdarzenie jest wywoływane zawsze gdy zachodzi potrzeba odrysowania obiektu, a więc np. po każdym przywołaniu okna na pierwszy plan. Zawartość listy będzie wypełniana w nieskończoność.

Tyle wystarczy:

KOD cpp:     UKRYJ  
void __fastcall TForm1::ListBox1DrawItem(TWinControl *Control, int Index,
        TRect &Rect, TOwnerDrawState State)
{
 TListBox *pListbox = dynamic_cast<TListBox*>(Control);
 TCanvas *pCanvas = pListbox->Canvas;



 if( Index % 2)
 {
  pCanvas->Font->Name = "Teen";
  pCanvas->Font->Color = clBlue;
 }
 else
 {
  pCanvas->Font->Name = "Raavie";
  pCanvas->Font->Color = clRed;
 }

 pCanvas->FillRect(Rect);
 pCanvas->TextRect(Rect, Rect.Left,Rect.Top, pListbox->Items->Strings[Index]);
}


A listę musisz wypełniać poza tym zdarzeniem.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox

Re: Rózne style czcionki w jednym ListBoxie

Nowy postprzez lukagrom » piątek, 27 października 2017, 09:13

Przepisałem, skompilowałem i testowałem wypełnianie listy zapomocą kliknięcia w przycisk czy w zdarzeniu OnCreate formy. ListBox naturalnie się wypełnił, lecz formatowanie żadne nie wystąpiło. Tradycyjny czarny tekst na białem tle. Użyłem dwóch różnych środowisk C++ Buildera. Co ciekawe analogiczna sytuacja występuje w komponencie "listBox" Visual C++, ten sam sam efekt po kompilacji co u poprzednika.

KOD cpp:     UKRYJ  
 System::Int32 i;
                                 
                                 for(i=1;i<51;i++)
                                 {
                                         if(i%2==0)
                                         {
                                                 
                                                 listBox1->ForeColor=System::Drawing::Color::Blue;
                                                 listBox1->Font->FontFamily->GenericSansSerif,14,FontStyle::Regular;
                                                 listBox1->Items->Add(i.ToString()+" parzysta");
                                         }
                                         else

                                         {
                                                 listBox1->ForeColor=System::Drawing::Color::Red;
                                                 listBox1->Font->FontFamily->GenericSansSerif,16,FontStyle::Underline;
                                                 listBox1->Items->Add(i.ToString()+" nieparzysta");
                                         }
                                 }
 
Avatar użytkownika
lukagrom
Bladawiec
Bladawiec
 
Posty: 37
Dołączył(a): wtorek, 1 stycznia 2013, 14:54
Podziękował : 6
Otrzymał podziękowań: 0
System operacyjny: Windows Vista
Kompilator: C++ Builder 10.1 Starter
Gadu Gadu: 0
    Windows VistaChrome

Re: Rózne style czcionki w jednym ListBoxie

Nowy postprzez polymorphism » piątek, 27 października 2017, 10:28

Prawdopodobnie systemowy ListBox nie obsługuje różnego formatowania pozycji w normalnym trybie pracy. Jak chcesz mieć inny wygląd, musisz przełączyć kontrolkę w tryb owner-draw, czyli tak jak zasugerowano Ci na początku.

Zresztą to, co jest w tym kodzie, nie ustawia stylu dla poszczególnych pozycji. Robi to globalnie (i wielokrotnie) dla całej kontrolki.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: Rózne style czcionki w jednym ListBoxie

Nowy postprzez lukagrom » piątek, 27 października 2017, 15:42

Zrobiłem to samo dla komponentu Memo i tam (stosując opóznienie w pętli) widoczne było nakładanie się na poszczególne wiersze kolorów niebieskiego i czerwonego, gdzie na koniec całość wydruku przyjmuje styl i kolor ostatniego wiersza. Analogicznie zachowuje się komponent z textBox z Visual C++, również widoczne miganie barw w czasię wykonywania pętli. Chyba pozostaje StringGrid gdzie można manipulować kolorami komórek (StringdrawCell) względem ich położenia (np naprzemiennie ) , nie wiem czy można to by robić, stosując za krytetium wartość komórki -(Cell[x][y]).
Avatar użytkownika
lukagrom
Bladawiec
Bladawiec
 
Posty: 37
Dołączył(a): wtorek, 1 stycznia 2013, 14:54
Podziękował : 6
Otrzymał podziękowań: 0
System operacyjny: Windows Vista
Kompilator: C++ Builder 10.1 Starter
Gadu Gadu: 0
    Windows VistaChrome

Re: Rózne style czcionki w jednym ListBoxie

Nowy postprzez polymorphism » piątek, 27 października 2017, 18:13

Nie rozumiem Twojego problemu. Przecież to, co Baron Ci podał, powinno działać. Podpinasz się pod zdarzenie OnDrawItem, właściwość Style ustawiasz na lbOwnerDrawFixed i powinno działać. W czym problem? Po co to szukanie innych kontrolek?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: Rózne style czcionki w jednym ListBoxie

Nowy postprzez lukagrom » piątek, 27 października 2017, 23:04

Sorry za zamieszanie, umknęła mi zmiana właściwości - Style na lbOwnerDrawFixed. Rzeczywiście po tej modyfikacji wszystko hula, jak powinno.
Avatar użytkownika
lukagrom
Bladawiec
Bladawiec
 
Posty: 37
Dołączył(a): wtorek, 1 stycznia 2013, 14:54
Podziękował : 6
Otrzymał podziękowań: 0
System operacyjny: Windows Vista
Kompilator: C++ Builder 10.1 Starter
Gadu Gadu: 0
    Windows VistaChrome


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 2 gości

cron