StringGrid i centrowanie

dział ogólny

StringGrid i centrowanie

Nowy postprzez Frani0 » sobota, 1 sierpnia 2009, 23:52

W materiałach na stronie zauważyłem centrowani i multi linijne wiersze w stringgridzie ;) zastosowałem tą procedurę lecz nie działa ona do końca poprawnie tzn...

w niektórych momentach pojawia się migotanie dlaczego tak się dzieje?

np.
kolumna | ilość linii
1 | 1
2 | 3
3 | 2
4 | 1
5 | 1

będzie to tak działało wypisze pierwszą komórke pierwszej linii i przejdzie do drugiej tu zobaczy że wielkośc wymaga 3 linii więc spowrotem przejdzie do pierwszej poprawi pierwszą na 3 linijną i przejdzie do 2 wypisze na 3 linijną i przejdzie do 3 komórki pierwszego wiersza tu zobaczy że są 2 linie więc poprawi na 2 linijną :| no i poprawianie zaczyna się od początku

przy 2 komórce zamienia na 3 linijne przy 3 komórce na 2 linijne i tak w kółko

wystarczy wprowadzić max'a i powinno być ok niestety i w wypadku maksymalnej wysokości czasem pojawia się migotanie blokujące program

w związku z tym moje pytanie jest takie czy zna ktoś inną procedurę która nie wywołuje migotania?
Avatar użytkownika
Frani0
Bladawiec
Bladawiec
 
Posty: 48
Dołączył(a): poniedziałek, 25 sierpnia 2008, 18:23
PodziÄ™kowaÅ‚ : 0
OtrzymaÅ‚ podziÄ™kowaÅ„: 0
    NieznanyNieznana

Re: StringGrid i centrowanie

Nowy postprzez Cyfrowy Baron » niedziela, 2 sierpnia 2009, 09:36

Ja nie bardzo rozumiem co to jest centrowanie i multi linijność.
Jeżeli centorwanie to wyrównywanie tekstu w komórce do środka, a multi linijność to zawijanie tekstu w komórkach, to nie należy tych porad łączyć ze sobą.

Porada: Zawijanie tekstu w komórkach tabeli StringGrid. podaje rozwiązanie jak zawijać tekst w komórkach, oraz jak go wyrównywać:

Kod: Zaznacz cały
DrawText(StringGrid1->Canvas->Handle, CellText.c_str(), -1, &DrawRect, DT_WORDBREAK | DT_CALCRECT | DT_LEFT);


Zamiast DT_LEFT stosujesz DT_CENTER

Funkcja DrawText obsługuje również flagi:
DT_TOP
DT_LEFT
DT_CENTER
DT_RIGHT
DT_VCENTER
DT_BOTTOM
DT_WORDBREAK
DT_SINGLELINE
DT_EXPANDTABS
DT_TABSTOP
DT_NOCLIP
DT_EXTERNALLEADING
DT_CALCRECT
DT_NOPREFIX
DT_INTERNAL

Jeżeli przez multilinijność rozumiesz zawijanie tekstu, to muszę Ciebie wyprowadzić z błędu, gdyż oznacza to wielolinijność, a to nie dokładnie to samo, gdyż multiline pozwala na tworzenie wielu linii, a nie ich zawijanie.



Co do migotania linii to chyba się domyślam - umieściłeś w zdarzeniu OnDrawCells pętlę, a pisałem już o tym przy okazji innego problemu, nie należy stosować pętli w zdarzeniach OnDraw, gdyż zawsze będzie to wywoływać migotanie obiektu.
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
    NieznanyNieznana

Re: StringGrid i centrowanie

Nowy postprzez Frani0 » sobota, 8 sierpnia 2009, 16:36

Już Ci pokazuje o co chodzi ;)

wstaw na formatkę zwykłego stringgrida

w drawcall wklej(to z twoich porad ;))
Kod: Zaznacz cały
AnsiString CellText = StringGrid1->Cells[ACol][ARow];
int j = (Rect.Bottom - Rect.Top - StringGrid1->Canvas->TextHeight(CellText))/2;

if(State.Contains(gdFixed))
{
  StringGrid1->Canvas->Brush->Color = clBtnFace;
  StringGrid1->Canvas->Font->Color = clWindowText;
  StringGrid1->Canvas->FillRect(Rect);
  Frame3D(StringGrid1->Canvas, Rect, clBtnHighlight, clBtnShadow, 1);
}
else
  if(State.Contains(gdSelected))
  {
   StringGrid1->Canvas->Brush->Color = clHighlight;
   StringGrid1->Canvas->Font->Color = clHighlightText;
   StringGrid1->Canvas->FillRect(Rect);
  }
  else
  {
   StringGrid1->Canvas->Brush->Color = StringGrid1->Color;
   StringGrid1->Canvas->Font->Color = StringGrid1->Font->Color;
   StringGrid1->Canvas->FillRect(Rect);
  }

TRect DrawRect = Rect;
DrawText(StringGrid1->Canvas->Handle, CellText.c_str(), -1, &DrawRect, DT_WORDBREAK | DT_CALCRECT | DT_LEFT);

if(StringGrid1->RowHeights[ARow] < (DrawRect.Bottom - DrawRect.Top) + 2)
  StringGrid1->RowHeights[ARow] = (DrawRect.Bottom - DrawRect.Top) + 2;
else
  if(StringGrid1->RowHeights[ARow] > (DrawRect.Bottom - DrawRect.Top) + 2 && (DrawRect.Bottom - DrawRect.Top) + 2 > StringGrid1->DefaultRowHeight)
   StringGrid1->RowHeights[ARow] = (DrawRect.Bottom - DrawRect.Top) + 2;

if(StringGrid1->RowHeights[ARow] <= StringGrid1->DefaultRowHeight)
{
  StringGrid1->Canvas->Brush->Color = StringGrid1->Canvas->Brush->Color;
  StringGrid1->Canvas->FillRect(Rect);
  StringGrid1->Canvas->TextOut(Rect.Left, Rect.Top + j, CellText);
}
else
  DrawText(StringGrid1->Canvas->Handle, CellText.c_str(), CellText.Length(), &DrawRect, DT_WORDBREAK | DT_LEFT);


a w
FormCreate wklej...

StringGrid1->Cells[0][0]="aaaaa aaaa aaaa aaaa aaaa aaaa";
StringGrid1->Cells[1][0]="aaaaa aaaa aaaa aaaa";

i masz migotanie ;) gdy w DrawCall dasz do tego powiedzmy
ShowMessage("OK");

to będziesz wiedział o co chodzi ;)

p.s można to łączyć z Wyśrodkowanie tyle że umiejętnie ;)

Kod: Zaznacz cały
if(StringGrid1->RowHeights[ARow] <= StringGrid1->DefaultRowHeight)
{
  StringGrid1->Canvas->Brush->Color = StringGrid1->Canvas->Brush->Color;
  StringGrid1->Canvas->FillRect(Rect);
}
 
DrawText(StringGrid1->Canvas->Handle, CellText.c_str(), CellText.Length(), &DrawRect, DT_WORDBREAK | DT_CENTER);
Avatar użytkownika
Frani0
Bladawiec
Bladawiec
 
Posty: 48
Dołączył(a): poniedziałek, 25 sierpnia 2008, 18:23
PodziÄ™kowaÅ‚ : 0
OtrzymaÅ‚ podziÄ™kowaÅ„: 0
    NieznanyNieznana

Re: StringGrid i centrowanie

Nowy postprzez Cyfrowy Baron » niedziela, 9 sierpnia 2009, 08:28

Nie wiem dlaczego u Ciebie występuje "migotanie", a u mnie nie. Jeżeli przepisałeś kod z porady bez modyfikacji to migotania nie powinno być.

i masz migotanie ;) gdy w DrawCall dasz do tego powiedzmy
ShowMessage("OK");


w żadnym razie nie należy umieszczać funkcji ShowMessage w zdarzeniu OnDrawCell, gdyż spowoduje to (u mnie na pewno) zawieszenie programu, gdyż przy każdym odrysowaniu obiektu StringGrid będzie wyskakiwał komunikat.
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
    NieznanyNieznana

Re: StringGrid i centrowanie

Nowy postprzez Frani0 » niedziela, 9 sierpnia 2009, 11:21

Przekleiłem ;)

to trochę opisze używam Builder 2009 choć to nie powinno sprawiać problemu ;)
ShowMessage w OnDrawCell wstawiłem po to by zobaczyć co powoduje błąd ;) i u mnie dzieje się w ten sposób

1. poprawia wielkość na 3 linijną bo takiej potrzebuje komórka nr.1
2. poprawia wielkość na 2 linijną bo takiej potrzebuje komórka nr.2 no i poprawia komórkę nr 1
3. ->powrót do kroku nr 1

i tak w kółko na ekranie z tego powodu jest migotanie komponentu.

w załączniku wysyłam projekt
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
Avatar użytkownika
Frani0
Bladawiec
Bladawiec
 
Posty: 48
Dołączył(a): poniedziałek, 25 sierpnia 2008, 18:23
PodziÄ™kowaÅ‚ : 0
OtrzymaÅ‚ podziÄ™kowaÅ„: 0
    NieznanyNieznana

Re: StringGrid i centrowanie

Nowy postprzez Cyfrowy Baron » niedziela, 9 sierpnia 2009, 12:57

Co mi po Twoim projekcie skoro ja używam starszej wersji C++ Builder 2007?! Nie jestem w stanie go uruchomić.
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
    NieznanyNieznana

Re: StringGrid i centrowanie

Nowy postprzez Frani0 » niedziela, 9 sierpnia 2009, 17:20

w załączniku wersja 2007
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
Avatar użytkownika
Frani0
Bladawiec
Bladawiec
 
Posty: 48
Dołączył(a): poniedziałek, 25 sierpnia 2008, 18:23
PodziÄ™kowaÅ‚ : 0
OtrzymaÅ‚ podziÄ™kowaÅ„: 0
    NieznanyNieznana

Re: StringGrid i centrowanie

Nowy postprzez Cyfrowy Baron » wtorek, 11 sierpnia 2009, 14:22

Sprawdziłem. Błąd spowodowany jest tym, że sąsiadujące obok siebie komórki wypełnione tekstem mają różną wysokość i obiekt próbuje dostosować wysokość obydwu czyniąc to zmianę co wywołuje miganie obiektu.

Problem rozwiązuje usunięcie tego kodu:

Kod: Zaznacz cały
  else
    if(StringGrid1->RowHeights[ARow] > (DrawRect.Bottom - DrawRect.Top) + 2 && (DrawRect.Bottom - DrawRect.Top) + 2 > StringGrid1->DefaultRowHeight)
    StringGrid1->RowHeights[ARow] = (DrawRect.Bottom - DrawRect.Top) + 2;


nie pamiętam już dlaczego go tam umieściłem, ale są tam dwa warunki które ze sobą kolidują.

Tak powinno być dobrze:

Kod: Zaznacz cały
void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol, int ARow,
     TRect &Rect, TGridDrawState State)
{
AnsiString CellText = StringGrid1->Cells[ACol][ARow];
int j = (Rect.Bottom - Rect.Top - StringGrid1->Canvas->TextHeight(CellText))/2;

if(State.Contains(gdFixed))
{
  StringGrid1->Canvas->Brush->Color = clBtnFace;
  StringGrid1->Canvas->Font->Color = clWindowText;
  StringGrid1->Canvas->FillRect(Rect);
  Frame3D(StringGrid1->Canvas, Rect, clBtnHighlight, clBtnShadow, 1);
}
else
  if(State.Contains(gdSelected))
  {
   StringGrid1->Canvas->Brush->Color = clHighlight;
   StringGrid1->Canvas->Font->Color = clHighlightText;
   StringGrid1->Canvas->FillRect(Rect);
  }
  else
  {
   StringGrid1->Canvas->Brush->Color = StringGrid1->Color;
   StringGrid1->Canvas->Font->Color = StringGrid1->Font->Color;
   StringGrid1->Canvas->FillRect(Rect);
  }

TRect DrawRect;// = Rect;
DrawRect.left = Rect.left + 5; // lewy margines
DrawRect.right = Rect.right - 5; // prawy margines
DrawRect.top = Rect.top + 5;  // górny margines
DrawRect.Bottom = Rect.bottom - 5; // dolny margines
DrawText(StringGrid1->Canvas->Handle, CellText.c_str(), -1, &DrawRect,
          DT_WORDBREAK | DT_CALCRECT);

if(StringGrid1->RowHeights[ARow] < (DrawRect.Bottom - DrawRect.Top) + 10)
  StringGrid1->RowHeights[ARow] = (DrawRect.Bottom - DrawRect.Top) + 10;


if(StringGrid1->RowHeights[ARow] <= StringGrid1->DefaultRowHeight)
{
  StringGrid1->Canvas->Brush->Color = StringGrid1->Canvas->Brush->Color;
  StringGrid1->Canvas->FillRect(Rect);
  StringGrid1->Canvas->TextOut(Rect.Left, Rect.Top + j, CellText);
}
else
{
  DrawText(StringGrid1->Canvas->Handle, CellText.c_str(), CellText.Length(),
           &DrawRect, DT_WORDBREAK | DT_CENTER);
}
}
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
    NieznanyNieznana


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 9 gości