Drukowanie kilku stron w winapi

0

Witam,
Skorzystałem z przykładu Petzolda odnośnie drukowania .
Przygotowałem funkcje WyslijDoDrukarki(hdcPrn, xPage, yPage) , która rysuje różne elementy : linie, pola , tekst itd. po kontekście drukarki.
Jest tego dużo - na dwie albo i więcej stron.
Funkcja jest wywoływana z PrintMyPage (HWND hwnd)
Niestety drukuje tylko pierwszą stronę.

 

BOOL PrintMyPage (HWND hwnd)
{
     static DOCINFO di = { sizeof (DOCINFO), TEXT ("Print1: Printing") } ;
     BOOL           bSuccess = TRUE ;
     HDC            hdcPrn ;
     int            xPage, yPage ;
     
     if (NULL == (hdcPrn = GetPrinterDC ()))
          return FALSE ;

     xPage = GetDeviceCaps (hdcPrn, HORZRES) ;
     yPage = GetDeviceCaps (hdcPrn, VERTRES) ;
     
     if (StartDoc (hdcPrn, &di) > 0)
     {
          if (StartPage (hdcPrn) > 0)
          {
               WyslijDoDrukarki (hdcPrn, xPage, yPage) ;
               if (EndPage (hdcPrn) > 0)
                    EndDoc (hdcPrn) ;
               else
                    bSuccess = FALSE ;
          }
     }
     else
          bSuccess = FALSE ;
     
     DeleteDC (hdcPrn) ;
     return bSuccess ;
}

Jak zmusić, by funkcja BOOL PrintMyPage (HWND hwnd) wydrukowała wszystko , co jest naniesione do kontekstu drukarki, a nie tylko pierwszą stronę?

0

no ale jak wygląda WyslijDoDrukarki???

0

Nową stronę robi się funkcją StartPage. Zresztą masz ją w kodzie użytą.

0

np. tak:

WyslijDoDrukarki (HDC hdcPrn, int xPage, int yPage) 
{
	TEXTMETRIC  tm;
	GetTextMetrics (hdcPrn, &tm) ;
 
	int			 yChar = tm.tmHeight + tm.tmExternalLeading ;
	int			 xChar = tm.tmAveCharWidth;
	stringstream STREAM;
	string       STRING;
	
	SetTextAlign (hdcPrn, TA_BASELINE | TA_LEFT); 

	for ( int Row = 1; Row <100; Row ++) 
	{
		STREAM << Col << ".\n";
		STREAM  >> STRING ;
		TextOut (hdcPrn, 10, yChar*Col ,STREAM.str(STRING).c_str(), lstrlen(STREAM.str(STRING).c_str());
		
		for ( int Col = 1; Col <10; Col ++)
		{
			STREAM << Col << "\n";
			STREAM  >> STRING ;
			TextOut (hdcPrn, 10 + xChar*Col, yChar*Col ,STREAM.str(STRING).c_str(), lstrlen(STREAM.str(STRING).c_str());
		}
	}
	RestoreDC(hdcPrn,-1);
}

 
0
Azarien napisał(a):

Nową stronę robi się funkcją StartPage. Zresztą masz ją w kodzie użytą.

To znaczy, że musiałbym dopisać pętlę ?

 for( int Page = 0 ; Page < CountOfPage; ++Page)
{
    if (StartDoc (hdcPrn, &di) > 0)
     {
          if (StartPage (hdcPrn) > 0)
          {
               WyslijDoDrukarki (hdcPrn, xPage, yPage) ;
               if (EndPage (hdcPrn) > 0)
                    EndDoc (hdcPrn) ;
               else
                    bSuccess = FALSE ;
          }
     }
     else
          bSuccess = FALSE ;
}



 
0

nie - musisz zrobić tak

  1. StartDoc
  2. Wydrukuj stronę
  3. EndPage
  4. Jeśli jest inna strona do wydrukowania to punkt 2
  5. EndDoc
0
abrakadaber napisał(a):

nie - musisz zrobić tak

  1. StartDoc
  2. Wydrukuj stronę
  3. EndPage
  4. Jeśli jest inna strona do wydrukowania to punkt 2
  5. EndDoc
  1. Czyli, jeśli jest kilka stron to EndPage zwraca wartość > 0 ?
  2. Czyli nie powinien dla iWynik >0 wywoływać EndDoc(hdcPrn) tylko pozostać w pętli i ponownie wywołać WyslijDoDrukarki?

Poprawiłem kod.
Niestety ta poprawka sprawia, że nie drukuje w ogóle. Wydruk nastąpi wówczas gdy zostanie wywołana EndDoc, a myślałem, że ta funkcja kończy ostatecznie drukowanie ( czyli wywoływana jest wtedy kiedy zostanie przekazana ost. strona do sterownika drukarki).

  1. Jak sprawdzić jaka strona jest przekazywana do drukarki?
  2. Jak sprawdzić ile stron jeszcze jest do przekazania?
 
     int iWynik = 0;
     
     //if (StartDoc (hdcPrn, &di) > 0)
	 iWynik = StartDoc (hdcPrn, &di) ;
     if(  iWynik >0 )
	 {
          //if (StartPage (hdcPrn) > 0)
		  iWynik = StartPage (hdcPrn) ;
		  if(  iWynik >0 )
          {
               WyslijDoDrukarki (hdcPrn, xPage, yPage) ;
               iWynik = EndPage (hdcPrn) ;
			   //if (EndPage (hdcPrn) > 0)
			   if(  iWynik >0 )
                   bSuccess = FALSE ; 
				   //EndDoc (hdcPrn) ;
               else
		              EndDoc (hdcPrn) ;
                    //bSuccess = FALSE ;
          }
     }
     else
          bSuccess = FALSE ;
0

stary trochę samodzielności - tu masz opisane np. co robi/zwraca/potrzebuje EndPage https://msdn.microsoft.com/en-us/library/windows/desktop/dd162596(v=vs.85).aspx (ba jak tam poklikasz na dole to może się doklikasz do przykładów)

EndPage NIC NIE WIE czy są inne strony do wydrukowania - EndPage mówi urządzeniu tylko i wyłącznie to, że aktualna strona się skończyła.

Co do pkt 3 i 4 to przecież TY drukujesz to TY masz wiedzieć co drukujesz i ile jeszcze zostało!

A to

             if(  iWynik >0 )
                   bSuccess = FALSE ; 
                   //EndDoc (hdcPrn) ;
               else
                      EndDoc (hdcPrn) ;

jest dla mnie niezrozumiałe. Jak strona poszła OK to, właściwie nie wiem co, a jak się coś popieprzyło to wtedy zakończ wydruk. Czyli jak wszystko poszło OK to nigdy nie kończysz wydruku (z tego co pamiętam to EndDoc rozpoczyna faktyczny wydruk, ale mogę się mylić/może to zależeć od konkretnej drukarki/sterowników)

Algorytm, który Ci podałem wyżej ma aż 5 (słownie PIĘĆ) kroków - tak trudno go zapisać w c++?

0

Myślałem, że kiedy wywołam funkcję zapisującą do kontekstu drukarki text i grafikę to ten zapis jest w całości przekazywany do kontekstu drukarki ( zapisywany w jakimś tam metapliku i można z niego wyciągnąć różne informacje m.in na ile stron podzielił sobie zapisany tekst i grafikę).

Jak widać nie rozumiem mechanizmu drukowania kliku stron i wcale to nie jest takie jednoznaczne.
W jaki sposób i w którym miejscu mam zrealizować pkt.4 ?
piszesz "Pkt. 4 Jeśli jest inna strona to punkt 2 " - to znaczy, że mam dopisać kawałek kodu obliczający ile stron zajmie bazgranie w kontekście urządzenia?
Gdzie go dopisać, w funkcji WyslijDoDruku ?

0

Nic Ci się samo nie zrobi. System (sterowniki drukarki, cokolwiek) nie wie co chcesz wydrukować na konkretnej stronie. Na strony musisz podzielić sobie sam. Wg mnie polecenie StartPage i EndPage dość dobitnie wskazują, że drukuje się tylko jedna strona. Ba nawet przykłady z opisem po polsku (nie mówiąc o przykładach w jedynym słusznym języku) są, np. http://cpp0x.pl/kursy/Kurs-WinAPI-C++/Zaawansowane/Drukowanie/372

0
abrakadaber napisał(a):

Nic Ci się samo nie zrobi. System (sterowniki drukarki, cokolwiek) nie wie co chcesz wydrukować na konkretnej stronie. Na strony musisz podzielić sobie sam. Wg mnie polecenie StartPage i EndPage dość dobitnie wskazują, że drukuje się tylko jedna strona. Ba nawet przykłady z opisem po polsku (nie mówiąc o przykładach w jedynym słusznym języku) są, np. http://cpp0x.pl/kursy/Kurs-WinAPI-C++/Zaawansowane/Drukowanie/372

Dzięki, po łepkach przeleciałem temat drukowania i pomyślałem, że cała zawartość moich bazgrołów jest przesyłana przez GDI do metapliku i ... po sprawie. Ale nie ma tak lekko. Również brakowało mi info , co sie dzieje gdy wywołuję StartPage, EndPage ( jak sie zachowuje GDI, co sie dzieje zplikami meta). Poczytałem i wszystko staje sie jasne.

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