CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Drukowanie tabeli StringGrid
Strona 1 z 2

Drukowanie tabeli StringGrid

Nowy postNapisane: wtorek, 28 września 2010, 18:42
przez Pitek
Witam!
Mam dwa problemy.
Pierwszy to problem z przekształceniem Baronowej funkcji drukującej zawartość tabeli StringGrid. Chodzi o przekształcenie tej funkcji tak aby to wykropkowanie w razie zbyt długiego wyrazu w komórce odnosiło się tylko do pierwszej kolumny a nie do całej tabeli. Heh niby proste ale mi takie głupoty potem w praktyce drukuje że proszę tutaj o radę. Jak to zrobić ?
Poniżej kod funkcji :
KOD cpp:     UKRYJ  
void __fastcall PrintGrid(TStringGrid *Grid)
{
 Printer()->BeginDoc();
 int x = Printer()->PageWidth;
 int y = Printer()->PageHeight;
 int k;

 float tmp = 0.0;
 for(int i = 0; i < Grid->ColCount; i++)
  tmp = tmp + (float)Grid->ColWidths[i];

 float ratio_x = x/tmp;

 int w, h = 0;
 int ratio_y = Grid->Canvas->TextHeight("TEXT");
 Printer()->Canvas->Brush->Style = bsClear;
 for(int i = 0; i < Grid->RowCount; i++)
 {
  w = 0;
  for(int j = 0; j < Grid->ColCount; j++)
  {
   String tekst = Grid->Cells[j][i];
   //lab_1:
   //if(Printer()->Canvas->TextWidth(tekst) + ratio_y >= Grid->ColWidths[j] * ratio_x)
   //{
   //tekst = tekst.SubString(1, tekst.Length() - 4) + "...";
   //goto lab_1;
   //}
   Printer()->Canvas->Rectangle(
                                 w * ratio_x,
                                 h * ratio_x,
                                 (w + Grid->ColWidths[j]) * ratio_x,
                                 (h + Grid->RowHeights[i] + ratio_y) * ratio_x
                                );
   Printer()->Canvas->TextOut(w * ratio_x + ratio_y, h * ratio_x + ratio_y, tekst);
   w = w + Grid->ColWidths[j];
  }
  h = h + Grid->RowHeights[i] + ratio_y;
  if((h + Grid->RowHeights[i] + (ratio_y * 4)) * ratio_x >= y)
  {
   h = 0;
   Printer()->Canvas->TextOut(0, y - (ratio_y * 3), "strona " + (String)Printer()->PageNumber);
   Printer()->NewPage();
  }
 }
 Printer()->Canvas->TextOut(0, y - (ratio_y * 3), "strona " + (String)Printer()->PageNumber);
 Printer()->EndDoc();
}

Mam tam komentarz w kilku miejscach tak tymczasowo przynajmniej nigdzie nie mam kropek.
A drugi. Czy da się i ew. jak przekazać informacje do PrintDialog żeby zawsze domyślnie drukował stronę w poziomie ?

Re: Drukowanie tabeli StringGrid

Nowy postNapisane: wtorek, 28 września 2010, 18:58
przez Cyfrowy Baron
Co się tyczy tego wykropkowania, to w zasadzie powinno się to robić trochę inaczej, ale nie chce mi się tej funkcji przerabiać, więc należy dodać warunek, któy ogranicza wykropkowanie do pierwszej kolumny:

KOD cpp:     UKRYJ  
for(int j = 0; j < Grid->ColCount; j++)
  {
   String tekst = Grid->Cells[j][i];
   lab_1:

   if(Printer()->Canvas->TextWidth(tekst) + ratio_y >= Grid->ColWidths[j] * ratio_x && j == 0)
   {
    tekst = tekst.SubString(1, tekst.Length() - 4) + "...";

    goto lab_1;
   }
Ta funkcja goto to też nieporozumienie, ale niech już tak zostanie. Co się tyczy tego wykropkowania to powinno się to raczej zrobić tak:

KOD cpp:     UKRYJ  
for(int j = 0; j < Grid->ColCount; j++)
  {
   String tekst = Grid->Cells[j][i];

   TRect dRect;
   dRect.Left    = w * ratio_x + ratio_y;
   dRect.Top    = h * ratio_x + ratio_y;
   dRect.Right  = (w + Grid->ColWidths[j]) * ratio_x + ratio_y;
   dRect.Bottom = (h + Grid->RowHeights[i] + ratio_y) * ratio_x + ratio_y;
   
    // [...]
   
   DrawText(Printer()->Canvas->Handle,
           tekst.t_str(),
           -1,
           &dRect,
           DT_LEFT | DT_VCENTER | DT_END_ELLIPSIS | DT_NOCLIP);

 /*  Printer()->Canvas->TextOut(w * ratio_x + ratio_y, , tekst); <-- wtedy tego nie trzeba, ani obcinania tekstu jak wyżej */


O tym czy strona jest drukowana w poziomie czy pionie decyduje funkcja Orientation:

KOD cpp:     UKRYJ  
 Printer()->Orientation = poLandscape;


Należy go umieści w funkcji przed funkcją Printer()->BeginDoc();

Re: Drukowanie tabeli StringGrid

Nowy postNapisane: wtorek, 28 września 2010, 21:24
przez Pitek
Dziękuję jeżeli chodzi o wykropkowanie ale drukowanie w poziomie nie działa ale tak sobie myślę czy to możliwe że tylko w moim przypadku ? Mam drukarkę HP i tam są jakieś dziwne sterowniki jak się da właściwości w PrinterDialog i myślę sobie że nie ma kompatybilności czy jest jeszcze jakiś inny sposób na to ?
I jeszcze przy okazji aby nie tworzyć nowego tematu jak zrobić żeby po jakieś kolumnie ta funkcja wstawiała np. grubszą kreskę lub co kolwiek co oznaczałoby "aha tu mam koniec pierwszego semestru"(bo o to chodzi) :D nie wiem mały trójkącik nad tą prawą kreską ten danej kolumny, oraz, Jak zrobić większy margines od prawej bo w niektórych miejscach mam linie kolumny na literce w wydruku czy da się to jakoś kontrolować ?

Re: Drukowanie tabeli StringGrid

Nowy postNapisane: wtorek, 28 września 2010, 21:52
przez Cyfrowy Baron
Przede wszystkim uświadom sobie, że drukowanie, to tak naprawdę rysowanie po płótnie TCanvas, więc kreskę możesz sobie narysować gdzie tylko chcesz. Do określania drukowania w poziomie służy funkcja którą podałem, nie ma od tego wyjątku.

ale drukowanie w poziomie nie działa ale tak sobie myślę


To mi zupełnie nic nie mówi.

Powinieneś wiedzieć jeszcze o jednym. Drukarki drukują w różnych rozdzielczościach i np. dla rozdzielczości 300 dpi strona może mieć długość 2400 pikseli, ale już przy rozdzielczości 600 dpi ta długość się podwoi do 4800 pikseli. Dlatego nie można na sztywno określać położenia obiektów na płótnie Canvas drukarki, lecz trzeba użyć jakiegoś współczynnika, przez który przelicza się współrzędne.

Nie ma żadnej prostej metody drukowania, która mówiłaby to drukuje się tak, a to tak. Trzeba opracować własne algorytmy.

Zapoznaj się z tym wątkiem: http://programowanie.cal.pl/forum/viewtopic.php?f=4&t=971&start=30&hilit=drukowanie oraz z działem Drukowanie w serwisie Cyfrowy Baron.

Re: Drukowanie tabeli StringGrid

Nowy postNapisane: środa, 29 września 2010, 17:07
przez Pitek
Dobrze skoro nie ma wyjątku, czemu u mnie to nie działa ? Dlatego pytam czy da się to zrobić jakoś inaczej.

Re: Drukowanie tabeli StringGrid

Nowy postNapisane: środa, 29 września 2010, 19:09
przez Cyfrowy Baron
Jeżeli to nie działa u Ciebie to oznacza, że to Ty gdzieś popełniasz błąd, a nie, że funkcja nie działa. Z informacji jakich udzieliłeś nie da się wywnioskować co robisz źle.

Re: Drukowanie tabeli StringGrid

Nowy postNapisane: czwartek, 30 września 2010, 21:20
przez Pitek
Przedstawiam fragmenty kodu mam nadzieję że jeżeli błąd istnieje to jest gdzieś tu :
Kod funkcji drukującej :
KOD cpp:     UKRYJ  
void __fastcall PrintGrid(TStringGrid *Grid)
{
 Printer()->Orientation = poLandscape;
 Printer()->BeginDoc();
 int x = Printer()->PageWidth;
 int y = Printer()->PageHeight;
 int k;

 float tmp = 0.0;
 for(int i = 0; i < Grid->ColCount; i++)
  tmp = tmp + (float)Grid->ColWidths[i];

 float ratio_x = x/tmp;

 int w, h = 0;
 int ratio_y = Grid->Canvas->TextHeight("TEXT");
 Printer()->Canvas->Brush->Style = bsClear;
 for(int i = 0; i < Grid->RowCount; i++)
 {
  w = 0;
  for(int j = 0; j < Grid->ColCount; j++)
  {
   String tekst = Grid->Cells[j][i];
   lab_1:
   if(Printer()->Canvas->TextWidth(tekst) + ratio_y >= Grid->ColWidths[j] * ratio_x && j == 1)
   {
   tekst = tekst.SubString(1, tekst.Length() - 4) + "...";
   goto lab_1;
   }
   Printer()->Canvas->Rectangle(
                                 w * ratio_x,
                                 h * ratio_x,
                                 (w + Grid->ColWidths[j]) * ratio_x,
                                 (h + Grid->RowHeights[i] + ratio_y) * ratio_x
                                );
   Printer()->Canvas->TextOut(w * ratio_x + ratio_y, h * ratio_x + ratio_y, tekst);
   w = w + Grid->ColWidths[j];
  }
  h = h + Grid->RowHeights[i] + ratio_y;
  if((h + Grid->RowHeights[i] + (ratio_y * 4)) * ratio_x >= y)
  {
   h = 0;
   Printer()->Canvas->TextOut(0, y - (ratio_y * 3), "strona " + (String)Printer()->PageNumber);
   Printer()->NewPage();
  }
 }
 Printer()->Canvas->TextOut(0, y - (ratio_y * 3), "strona " + (String)Printer()->PageNumber);
 Printer()->EndDoc();
}
//---------------------------------------------------------------------------

Kod wywołania funkcji :
KOD cpp:     UKRYJ  
void __fastcall TForm9::Button1Click(TObject *Sender)
{
if(Form1->PrintDialog1->Execute())
{
    PrintGrid(Form1->StringGrid1);
}
}
Jeżeli czegoś jeszcze brakuje do zdiagnozowania tego błędu to proszę o informację jaki kod mam jeszcze umieścić.
Nie działa funkcja mające ustawiać właściwości wydruku na poziomy.

Re: Drukowanie tabeli StringGrid

Nowy postNapisane: piątek, 1 października 2010, 08:05
przez Cyfrowy Baron
Nie jestem tego pewien, ale jeżeli używasz do zmiany ustawień drukarki obiektu PrintDialog, to prawdopodobnie drukarka ignoruje ustawienia w kodzie programu, dlatego przeprowadź test wydruku bez wywoływania okna PrintDialog.

Re: Drukowanie tabeli StringGrid

Nowy postNapisane: piątek, 1 października 2010, 12:13
przez Pitek
Rzeczywiście ale co można zrobić żeby to z oknem PrintDialog zaczęło działać, da się tak ?

Re: Drukowanie tabeli StringGrid

Nowy postNapisane: piątek, 1 października 2010, 12:36
przez Cyfrowy Baron
Nie wiem. U mnie działa to prawidłowo zarówno z PrintDialog, z PrinterDialogSetup jak i bez tych obiektów. Wymuszenie drukowania w poziomie w kodzie programu zupełnie ignoruje to ustawienie w opcjach PrinterSetupDialog. Co się tyczy PrintDialog to okno dialogowe nie posiada opcji ustawiania orientacji drukowania, posiada je za to okno PrinterSetupDialog.

Pisałeś, że masz jakąś dziwną drukarkę, więc musi być rzeczywiście wyjątkowa, skoro ignoruje polecenia wydane przez program. Co się tyczy wspomnianych przez Ciebie sterowników, to skoro drukarka drukuje, to oznacza, że sterowniki działają.

Co to za drukarka. Model, nr. itp...

Sprawdź program na innej drukarce.

Re: Drukowanie tabeli StringGrid

Nowy postNapisane: piątek, 1 października 2010, 13:29
przez Pitek
Drukarka to HP OfficeJet D155.
U mnie to nie działa ani z PrintDialog ani z PrinterSetupDialog
Jeżeli chodzi o to co pisałem że ignoruje, no tak by to wyglądało.
Napisałem że mam dziwną drukarkę miałem na myśli że ma ona na tyle skomplikowane sterowniki że funkcja mająca wymusić drukowanie w poziomie nie jest przez nie wykrywana. To tylko mój pogląd na sprawę, być może taki zapis jest uniwersalny i powinien działać wszędzie, nie wiem więc dlatego tak napisałem.
A co do testów na innej drukarce w tej chwili nie mam takiej możliwości niestety.

Re: Drukowanie tabeli StringGrid

Nowy postNapisane: piątek, 1 października 2010, 13:35
przez Cyfrowy Baron
A co do testów na innej drukarce w tej chwili nie mam takiej możliwości niestety.


Więc wrzuć ten program na forum, ale napisz drugi prosty program testowy, czyli taki, w którym u ciebie nie działa orientacja strony, a ja to sprawdzę na swojej drukarce.

Re: Drukowanie tabeli StringGrid

Nowy postNapisane: niedziela, 3 października 2010, 21:58
przez Pitek
W załączniku przesyłam przykładowy program który mi nie działa.
Nie wiem czy robię w nim coś źle czy to wina drukarki ale nie działa.
Bardzo proszę o przetestowanie.

Re: Drukowanie tabeli StringGrid

Nowy postNapisane: poniedziałek, 4 października 2010, 07:53
przez Cyfrowy Baron
Przetestowałem i wszystko jest w porządku. Drukuje mi stronę w poziomie, mimo tego, że w PrinterSetupDialog ustawiam drukowanie w pionie, czyli kod wykonuje się prawidłowo.

Re: Drukowanie tabeli StringGrid

Nowy postNapisane: poniedziałek, 4 października 2010, 23:24
przez Pitek
A da się jakoś odwołać do PrinterSetupDialog lub PrintDialog aby tam ten RadioButton z orientacją strony był na "Poziomo" ?