Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym artykule opisano protokół drukowania systemu Windows i wyjaśniono, jak drukować dokumenty zawierające więcej niż jedną stronę. W tym artykule omówiono następujące tematy:
Protokół drukowania
Aby wydrukować dokument wielostronicowy, struktura i widok wchodzą w interakcje w następujący sposób. Najpierw platforma wyświetla okno dialogowe Drukowanie , tworzy kontekst urządzenia dla drukarki i wywołuje funkcję składową StartDoc obiektu CDC . Następnie dla każdej strony dokumentu struktura wywołuje funkcję składową CDC
obiektu, instruuje obiekt widoku, aby wydrukował stronę i wywołuje funkcję składową EndPage. Jeśli tryb drukarki należy zmienić przed uruchomieniem określonej strony, widok wywołuje polecenie ResetDC, który aktualizuje strukturę DEVMODE zawierającą informacje o nowym trybie drukarki. Po wydrukowaniu całego dokumentu struktura wywołuje funkcję składową EndDoc .
Zastępowanie funkcji klas widoku
Klasa CView definiuje kilka funkcji składowych, które są wywoływane przez platformę podczas drukowania. Przesłaniając te funkcje w swojej klasie widoków, zapewniasz połączenia między logiką drukowania platformy a logiką drukowania Twojej klasy widoków. W poniższej tabeli wymieniono te funkcje składowe.
Funkcje zastępowalne obiektu CView do drukowania
Nazwa | Przyczyna zastąpienia |
---|---|
OnPreparePrinting | Aby wstawić wartości w oknie dialogowym Drukowanie, szczególnie długość dokumentu |
OnBeginPrinting | Aby przydzielić czcionki lub inne zasoby GDI |
OnPrepareDC | Aby dostosować atrybuty kontekstu urządzenia dla danej strony lub przeprowadzić stronicowanie w czasie drukowania |
OnPrint | Aby wydrukować daną stronę |
OnEndPrinting (Podczas zakończenia drukowania) | Dealokować zasoby GDI |
Można również wykonywać przetwarzanie związane z drukowaniem w innych funkcjach, ale te funkcje są tymi, które napędzają proces drukowania.
Na poniższej ilustracji przedstawiono kroki związane z procesem drukowania i pokazano, gdzie są wywoływane poszczególne CView
funkcje składowe drukowania. W pozostałej części tego artykułu bardziej szczegółowo opisano większość tych kroków. Dodatkowe części procesu drukowania opisano w artykule Przydzielanie zasobów GDI.
Pętla drukowania
Paginacja
Struktura przechowuje wiele informacji o zadaniu drukowania w strukturze CPrintInfo . Kilka wartości w sekcji CPrintInfo
dotyczy stronicowania. Te wartości są dostępne, jak pokazano w poniższej tabeli.
Informacje o numerze strony przechowywane w CPrintInfo
Zmienna składowa lub nazwy funkcji |
Numer strony, do której się odnosi |
---|---|
GetMinPage /SetMinPage |
Pierwsza strona dokumentu |
GetMaxPage /SetMaxPage |
Ostatnia strona dokumentu |
GetFromPage |
Pierwsza strona do wydrukowania |
GetToPage |
Ostatnia strona do wydrukowania |
m_nCurPage |
Strona aktualnie drukowana |
Numery stron zaczynają się od 1, czyli pierwsza strona jest numerowana 1, a nie 0. Aby uzyskać więcej informacji na temat tych i innych członków CPrintInfo, zobacz dokumentację MFC.
Na początku procesu drukowania framework wywołuje funkcję członkowską widoku OnPreparePrinting, przekazując wskaźnik do struktury CPrintInfo
. Asystent aplikacji udostępnia implementację OnPreparePrinting
, która wywołuje DoPreparePrinting, inną funkcję składową CView
.
DoPreparePrinting
to funkcja, która wyświetla okno dialogowe Drukowanie i tworzy kontekst urządzenia drukarki.
W tym momencie aplikacja nie wie, ile stron znajduje się w dokumencie. Używa ona wartości domyślnych 1 i 0xFFFF dla liczb pierwszej i ostatniej strony dokumentu. Jeśli wiesz, ile stron zawiera dokument, nadpisz OnPreparePrinting
i wywołaj metodę [SetMaxPage]---brokenlink--(reference/cprintinfo-class.md#setmaxpage) dla struktury CPrintInfo
przed wysłaniem jej do DoPreparePrinting
. Pozwala to określić długość dokumentu.
DoPreparePrinting
następnie wyświetla okno dialogowe Drukowanie. Po powrocie struktura CPrintInfo
zawiera wartości określone przez użytkownika. Jeśli użytkownik chce wydrukować tylko wybrany zakres stron, może określić numery stron początkowych i końcowych w oknie dialogowym Drukowanie. Struktura pobiera te wartości przy użyciu funkcji GetFromPage
i GetToPage
należących do CPrintInfo. Jeśli użytkownik nie określi zakresu stron, platforma wywołuje GetMinPage
i GetMaxPage
i używa wartości zwróconych, aby wydrukować cały dokument.
Dla każdej strony dokumentu, która ma zostać wydrukowana, struktura wywołuje dwie funkcje składowe w klasie widoków , OnPrepareDC i OnPrint, a następnie przekazuje do każdej funkcji dwa parametry: wskaźnik do obiektu CDC i wskaźnik do CPrintInfo
struktury. Za każdym razem, gdy struktura wywołuje OnPrepareDC
i OnPrint
, przekazuje inną wartość w składowej struktury CPrintInfo
. W ten sposób struktura informuje widok, która strona powinna zostać wydrukowana.
Funkcja składowa OnPrepareDC jest również używana do wyświetlania ekranu. Powoduje to dostosowanie kontekstu urządzenia przed rozpoczęciem rysowania.
OnPrepareDC
pełni podobną rolę w drukowaniu, ale istnieje kilka różnic: najpierw CDC
obiekt reprezentuje kontekst urządzenia drukarki zamiast kontekstu urządzenia ekranu, a drugi obiekt CPrintInfo
jest przekazywany jako drugi parametr. (Ten parametr ma wartość NULL , gdy OnPrepareDC
jest wywoływany dla wyświetlania ekranu). Zastąpij OnPrepareDC
, aby wprowadzić zmiany w kontekście urządzenia na podstawie tego, która strona jest drukowana. Możesz na przykład przenieść źródło widoku i region wycinków, aby upewnić się, że odpowiednia część dokumentu zostanie wydrukowana.
Funkcja składowa OnPrint wykonuje rzeczywiste drukowanie strony. W artykule Jak drukowanie domyślne jest wykonywane pokazano, jak framework wywołuje metodę OnDraw z kontekstem urządzenia drukarki, aby wykonać drukowanie. Dokładniej mówiąc, framework wywołuje OnPrint
z CPrintInfo
strukturą i kontekstem urządzenia, a OnPrint
przekazuje kontekst urządzenia do OnDraw
. Zastąpij, aby wykonać dowolne renderowanie OnPrint
, które powinno być wykonywane tylko podczas drukowania, a nie do wyświetlania ekranu. Na przykład, aby wydrukować nagłówki lub stopki (zobacz artykuł Nagłówki i stopki aby uzyskać więcej informacji). Następnie wywołaj OnDraw
z przesłonięcia OnPrint
w celu wykonania renderowania wspólnego dla wyświetlania na ekranie i drukowania.
Fakt, że OnDraw
odpowiada za renderowanie zarówno wyświetlania na ekranie, jak i drukowania, oznacza, że twoja aplikacja jest WYSIWYG: "To, co widzisz, jest tym, co otrzymasz". Załóżmy jednak, że nie tworzysz aplikacji WYSIWYG. Rozważmy na przykład edytor tekstów, który używa czcionki pogrubionej do drukowania, ale wyświetla kody sterujące wskazujące pogrubiony tekst na ekranie. W takiej sytuacji należy używać OnDraw
wyłącznie do wyświetlania ekranu. Gdy zastąpisz OnPrint
metodę, zamień wywołanie OnDraw
na wywołanie oddzielnej funkcji rysującej. Ta funkcja rysuje dokument tak, jak pojawia się na papierze, przy użyciu atrybutów, które nie są wyświetlane na ekranie.
Strony drukarki a strony dokumentów
W przypadku odwoływania się do numerów stron czasami konieczne jest rozróżnienie między koncepcją strony drukarki a koncepcją strony dokumentu. Z punktu widzenia drukarki strona jest jednym arkuszem papieru. Jednak jeden arkusz papieru nie musi być równy jednej stronie dokumentu. Jeśli na przykład drukujesz biuletyn, w którym arkusze mają być składane, jeden arkusz papieru może zawierać zarówno pierwsze, jak i ostatnie strony dokumentu. Podobnie, jeśli drukujesz arkusz kalkulacyjny, dokument nie składa się w ogóle ze stron. Zamiast tego jeden arkusz papieru może zawierać wiersze od 1 do 20, kolumn od 6 do 10.
Wszystkie numery stron w strukturze CPrintInfo odwołują się do stron drukarek. Framework wywołuje OnPrepareDC
i OnPrint
raz dla każdego arkusza papieru, który przejdzie przez drukarkę. Po zastąpieniu funkcji OnPreparePrinting w celu określenia długości dokumentu należy użyć stron drukarki. Jeśli istnieje korespondencja jeden do jednego (oznacza to, że jedna strona drukarki jest równa jednej stronie dokumentu), jest to łatwe. Jeśli strony dokumentów i strony drukarki nie odpowiadają sobie bezpośrednio, trzeba dokonać ich konwersji. Rozważ na przykład drukowanie arkusza kalkulacyjnego. Podczas zastępowania OnPreparePrinting
należy obliczyć, ile arkuszy papieru będzie wymaganych do wydrukowania całego arkusza kalkulacyjnego, a następnie użyć tej wartości podczas wywoływania SetMaxPage
funkcji składowej CPrintInfo
. Podobnie podczas zastępowania OnPrepareDC
należy przetłumaczyć m_nCurPage na zakres wierszy i kolumn, które będą wyświetlane w danym arkuszu, a następnie odpowiednio dostosować źródło widoku.
Print-Time stronicowanie
W niektórych sytuacjach klasa widoku może nie wiedzieć z góry, jak długi jest dokument, dopóki nie zostanie rzeczywiście wydrukowany. Załóżmy na przykład, że aplikacja nie jest WYSIWYG, więc długość dokumentu na ekranie nie odpowiada jego długości podczas drukowania.
To powoduje problem podczas zastępowania OnPreparePrinting dla klasy widoku: nie można przekazać wartości do funkcji SetMaxPage
struktury CPrintInfo, ponieważ nie znasz długości dokumentu. Jeśli użytkownik nie określi numeru strony do zatrzymania korzystania z okna dialogowego Drukowanie, platforma nie wie, kiedy zatrzymać pętlę drukowania. Jedynym sposobem określenia, kiedy zatrzymać pętlę drukowania, jest wydrukowanie dokumentu i sprawdzenie, kiedy się kończy. Klasa widoku musi sprawdzić koniec dokumentu podczas jego drukowania, a następnie poinformować strukturę po osiągnięciu końca.
Struktura opiera się na funkcji OnPrepareDC klasy widoku, aby poinformować, kiedy należy zatrzymać proces. Po każdym wywołaniu OnPrepareDC
, framework sprawdza element członkowski struktury CPrintInfo
o nazwie m_bContinuePrinting. Jego wartość domyślna to TRUE. Tak długo, jak to pozostanie, struktura kontynuuje pętlę drukowania. Jeśli ustawiono wartość FALSE, framework zostanie zatrzymany. Aby wykonać stronicowanie w czasie drukowania, nadpisz OnPrepareDC
, aby sprawdzić, czy koniec dokumentu został osiągnięty, i ustaw wartość m_bContinuePrinting na FALSE, gdy tak się stanie.
Domyślna implementacja OnPrepareDC
ustawia m_bContinuePrinting na FALSE, jeśli bieżąca strona jest większa niż 1. Oznacza to, że jeśli długość dokumentu nie została określona, framework zakłada, że dokument ma jedną stronę. Jedną z konsekwencji jest to, że należy zachować ostrożność, jeśli wywołasz wersję klasy bazowej OnPrepareDC
. Nie należy zakładać, że m_bContinuePrinting będzie mieć wartość TRUE po wywołaniu wersji klasy bazowej.