CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Dynamiczne tworzenie stron dla podglądu wydruku
Strona 1 z 1

Dynamiczne tworzenie stron dla podglądu wydruku

Nowy postNapisane: czwartek, 30 grudnia 2010, 18:50
przez mate006
Witam

Mam potrzebę wydrukowania listy z dbgrid i chciałbym spytać jak zrobić aby dynamicznie tworzyło oddzielne strony, oczywiście najpierw na podglądzie, myślałem o zastosowaniu klasy TCanvas komponentu TImage, a przy drukowaniu Printer()->TCanvas.

Prosiłbym o jakąś wskazówkę

Re: Dynamiczne tworzenie stron dla podglądu wydruku

Nowy postNapisane: czwartek, 30 grudnia 2010, 19:07
przez Cyfrowy Baron
Dobrze myślałeś, ale jakiej wskazówki oczekujesz, nie ma na to gotowych klas.

Re: Dynamiczne tworzenie stron dla podglądu wydruku

Nowy postNapisane: czwartek, 30 grudnia 2010, 19:22
przez mate006
Chodzi mi o tworzenie tych stron dynamicznie, czyli np. program wypełnia kolejne rekordy na liście i gdy kończy się strona, tworzy kolejny komponent TImage aż skończy się lista

np.
Kod: Zaznacz cały
TImage *str1 = new TImage(this);

  str1->Parent = this;
  str1->Width  = 815;
  str1->Left   = Form1->Width/2 - str1->Width/2;
  str1->Top    = Panel->Height + 5;

  generuj_liste(str1->Canvas, 1,1);

  no i teraz niech tworzy dynamicznie

  TImage *str2 = new TImage(this);

  str2->Parent = this;
  str2->Width  = 815;
  str2->Left   = Form1->Width/2 - str1->Width/2;
  str2->Top    = str1->Top + str->Height + 20;
 
  generuj_liste(str2->Canvas, 1,1);

 


i jak to zrobić by dynamicznie tworzyło kolejne strony

chociaż w zasadzie mogę to zrobić na jednym Canvasie tylko na odpowiedniej wysokości zrobić przerwę oddzieloną jakimś kolorkiem i też będzie

ale nie można chyba dynamicznie powiększać Canvasu, mi się nie udawało to jeszcze

Re: Dynamiczne tworzenie stron dla podglądu wydruku

Nowy postNapisane: czwartek, 30 grudnia 2010, 20:03
przez Cyfrowy Baron
Po co dzielić skoro płótno Canvas ma nieokreślony rozmiar. To tylko wszystko skomplikuje.

Re: Dynamiczne tworzenie stron dla podglądu wydruku

Nowy postNapisane: czwartek, 30 grudnia 2010, 20:24
przez mate006
A w jaki sposób pokazywać dynamicznie canvas

zrobiłem sobie taką pętlę

KOD cpp:     UKRYJ  
TImage *str1 = new TImage(this);

  str1->Parent = this;
  str1->Width  = 814;
  str1->Left   = Form_Spis->ClientWidth/2 - str1->Width/2;
  str1->Top    = Panel->Height + 5;

  lp = 1;

  for (lp; lp < 20; lp++)
  {
//    str1->Height = lp * 30;
      str1->Canvas->TextOutA(30, (lp-1)*30, lp);
  }


a taki jest wynik, wyświetla mi tylko do pierwotnej wysokości

Obrazek

gdy usunę komentarz to wyświetli mi tylko liczbę 1

Re: Dynamiczne tworzenie stron dla podglądu wydruku

Nowy postNapisane: czwartek, 30 grudnia 2010, 22:51
przez Cyfrowy Baron
Nie wiem dokładnie z czego to wynika, ale przed użyciem płótna Canvas musisz najpierw określić rozmiar obiektu który z tego płótna korzysta, tutaj jest to obiekt typu Timage. Jest to konieczne, gdyż w przypadku TImage płótno Canvas przyjmuje taki rozmiar jaki miał Image przed rozpoczęciem rysowania po tym płótnie, czyli powinno być tak:

KOD cpp:     UKRYJ  
TImage *str1 = new TImage(this);

  str1->Parent = this;
  str1->Width  = 814;
  str1->Left   = Form_Spis->ClientWidth/2 - str1->Width/2;
  str1->Top    = Panel->Height + 5;

  lp = 1;
 str1->Height = 20 * 30;

  for (lp; lp < 20; lp++)
  {
      str1->Canvas->TextOutA(30, (lp-1)*30, lp);
  }

Re: Dynamiczne tworzenie stron dla podglądu wydruku

Nowy postNapisane: piątek, 31 grudnia 2010, 11:51
przez polymorphism
Nie wiem dokładnie z czego to wynika, ale przed użyciem płótna Canvas musisz najpierw określić rozmiar obiektu który z tego płótna korzysta, tutaj jest to obiekt typu Timage.

Wynika to z tego, że Canvas nie jest miejscem, po którym rysujesz, jest tylko zestawem narzędzi do rysowania - pisałem już o tym kiedyś.

Re: Dynamiczne tworzenie stron dla podglądu wydruku

Nowy postNapisane: piątek, 31 grudnia 2010, 12:00
przez Cyfrowy Baron
Wynika to z tego, że Canvas nie jest miejscem, po którym rysujesz, jest tylko zestawem narzędzi do rysowania - pisałem już o tym kiedyś.


Wiem o tym, o ile jednak w przypadku np. formularza zmiana po zmianie rozmiaru tegoż formularza i wywołaniu funkcji Repaint, Canvas przyjmie nowy rozmiar formularza, o tyle w przypadku TImage to nie działa, co jak sądzę ma związek z tym, że Image nie posiada własnej powierzchni, lub też dlatego że Image przechowuje to co zostało na nim narysowane. Dlatego być może lepszym rozwiązaniem byłoby zastosowanie obiektu TPainBox, ale kod rysujący trzeba by wywoływać w jego zdarzeniu OnPaint.

Re: Dynamiczne tworzenie stron dla podglądu wydruku

Nowy postNapisane: piątek, 31 grudnia 2010, 12:26
przez polymorphism
Nie rozumiem, jak nie działa w TImage? Co, po zmianie rozmiaru nie możesz malować po nowej powierzchni? Bo z tego co ja pamiętam, nie było z tym żadnego problemu.

(...) co jak sądzę ma związek z tym, że Image nie posiada własnej powierzchni, lub też dlatego że Image przechowuje to co zostało na nim narysowane.

Jeśli przechowuje to, co zostało na nim narysowane, to znaczy, że jednak tę powierzchnie posiada, jest nią bitmapa.

Re: Dynamiczne tworzenie stron dla podglądu wydruku

Nowy postNapisane: piątek, 31 grudnia 2010, 12:52
przez Cyfrowy Baron
Można po nim rysować, ale obszar roboczy Canvas ogranicza się do wymiarów przed zmianą rozmiaru obiektu Image. Mówią tutaj o Image->Canvas, a nie o Image->Picture->Bitamp->Canvas. W tym właśnie problem, że Image->Canvas, nie uwzględnia zmiany rozmiaru i wywołanie funkcji Repaint tego nie zmienia.
polymorphism napisał(a):Jeśli przechowuje to, co zostało na nim narysowane, to znaczy, że jednak tę powierzchnie posiada, jest nią bitmapa.


Tak przypuszczam, ale nie jestem do końca pewien, gdyż w przypadku TImage mamy do czynienia z dwoma płótnami typu TCanvas, o czym wspomniałem wyżej, czyli:

Image->Canvas
Image->Picture->Bitmap->Canvas


Oczywiście drugie Canvas należy do klasy TBitmap. W przypadku klasy TBitmap również trzeba z góry określić rozmiar, jednak w odróżnieniu on Image->Canvas, ten rozmiar może się zmieniać dynamicznie. To mi podsuwa rozwiązanie:
KOD cpp:     UKRYJ  
 TImage *str1 = new TImage(this);

  str1->Parent = this;
  str1->Width  = 814;
  str1->Left   = 8;//Form_Spis->ClientWidth/2 - str1->Width/2;
  str1->Top    = 35;//Panel->Height + 5;

  int lp;

  for (lp = 1; lp < 20; lp++)
  {
    str1->Height = lp * 30;
    str1->Picture->Bitmap->Width = str1->Width;
    str1->Picture->Bitmap->Height = str1->Height;
    str1->Picture->Bitmap->Canvas->TextOut(30, (lp-1)*30, lp);
  }


Przy czym obiekt str1 typu TImage w żadnym razie nie powinien być obiektem lokalnym, sugerowałbym zadeklarować go w pliku nagłówkowym w sekcji private i całość zrobić w ten sposób:

plik nagłówkowym np. Unit1.h
KOD cpp:     UKRYJ  
private:
        TImage *str1;


plik źródłowy np. Unit1.cpp
KOD cpp:     UKRYJ  
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  if(str1 != NULL) delete str1;

  str1 = new TImage(this);

  str1->Parent = this;
  str1->Width  = 814;
  str1->Left   = 8;//Form_Spis->ClientWidth/2 - str1->Width/2;
  str1->Top    = 35;//Panel->Height + 5;

  int lp;

  for (lp = 1; lp < 20; lp++)
  {
    str1->Height = lp * 30;
    str1->Picture->Bitmap->Width = str1->Width;
    str1->Picture->Bitmap->Height = str1->Height;
    str1->Picture->Bitmap->Canvas->TextOut(30, (lp-1)*30, lp);
  }
}

Re: Dynamiczne tworzenie stron dla podglądu wydruku

Nowy postNapisane: piątek, 31 grudnia 2010, 13:27
przez polymorphism
W tym właśnie problem, że Image->Canvas, nie uwzględnia zmiany rozmiaru i wywołanie funkcji Repaint tego nie zmienia.

Może po prostu zmiana rozmiaru TImage nie zmienia rozmiaru (wewnętrznej) bitmapy, i wtedy miałoby to sens. Tak samo zmiana rozmiaru bitmapy nie wpływa na rozmiar obiektu image.

W sumie jeśli ustawisz właściwość Stretch na true, bitmapa powinna dostosowywać się do rozmiaru obiektu image.


KOD cpp:     UKRYJ  
  for (lp = 1; lp < 20; lp++)
  {
    str1->Height = lp * 30;
    str1->Picture->Bitmap->Width = str1->Width;
    str1->Picture->Bitmap->Height = str1->Height;
    str1->Picture->Bitmap->Canvas->TextOut(30, (lp-1)*30, lp);
  }

Strasznie nieefektywne to. Przecież rozmiar bitmapy można obliczyć i ustawić przed pętlą.

Re: Dynamiczne tworzenie stron dla podglądu wydruku

Nowy postNapisane: piątek, 31 grudnia 2010, 13:38
przez Cyfrowy Baron
polymorphism napisał(a):Strasznie nieefektywne to. Przecież rozmiar bitmapy można obliczyć i ustawić przed pętlą.


Oczywiście! Przecież zaproponowałem to samo dla Image->Canvas w swoim wcześniejszym poście: http://programowanie.cal.pl/forum/viewtopic.php?f=2&t=1210#p8389. Tutaj tylko posłużyłem się przykładowym kodem mate006 pokazując, że można to w ten sposób zrobić, lecz zamiast Image->Canvas trzeba użyć Image->Picture->Bitmap->Canvas. Przecież rozmiar samego Image również można określić przed pętlą.
Jeżeli określimy rozmiar obiektu str1 typu TImage przed pętlą i przed każdym wywołaniem go obiekt będzie niszczony i tworzony na nowo:

KOD cpp:     UKRYJ  
if(str1 != NULL) delete str1;


To bez problemu można posłużyć się Image->Canvas.
Nie wiem dlaczego autor wątku określa rozmiar Image w pętli, skoro nic - jak sądzę - nie stoi na przeszkodzie by zrobić to przed pętlą.

Re: Dynamiczne tworzenie stron dla podglądu wydruku

Nowy postNapisane: piątek, 31 grudnia 2010, 17:46
przez mate006
Ale mi nie o to chodziło, chodzi o to że ja nie wiem jaka będzie wysokość, bo to ma być dynamicznie określane, ja tylko pokazałem że nie można tego tak zwiększać.

Re: Dynamiczne tworzenie stron dla podglądu wydruku

Nowy postNapisane: piątek, 31 grudnia 2010, 20:46
przez Cyfrowy Baron
Toteż podałem ci kod z Image->Picture-Bitmap->Canvas zamiast image->Canvas i już możesz sobie zmieniać dynamicznie. Patrz ten post: http://programowanie.cal.pl/forum/viewtopic.php?f=2&t=1210#p8399