home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / PRNTPREV.PAK / PRNTPREV.CPP < prev    next >
C/C++ Source or Header  |  1995-08-29  |  15KB  |  508 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1993 by Borland International
  3. //   prntprev.cpp
  4. //   Example print preview program
  5. //----------------------------------------------------------------------------
  6. #include <owl\owlpch.h>
  7. #include <owl\applicat.h>
  8. #include <owl\framewin.h>
  9. #include <owl\preview.h>
  10. #include <owl\printer.h>
  11. #include <owl\dc.h>
  12. #include <owl\gdiobjec.h>
  13. #include <owl\layoutwi.h>
  14.  
  15. #include "prntprev.rh"
  16.  
  17. //#define  USE_WINDOW_PRINTOUT
  18.  
  19. //----------------------------------------------------------------------------
  20. //
  21. // Simple text & graphic test printout class
  22. //
  23. class TTestPrintout : public TPrintout {
  24.   public:
  25.     TTestPrintout(const char* title) : TPrintout(title) {Banding=0;}
  26.     void GetDialogInfo(int& minPage, int& maxPage, int& selFromPage, int& selToPage);
  27.     void PrintPage(int page, TRect& rect, unsigned flags);
  28. };
  29.  
  30. void TTestPrintout::GetDialogInfo(int& minPage, int& maxPage, int& selFromPage, int& selToPage)
  31. {
  32.   minPage = 0;
  33.   maxPage = 0;
  34.   selFromPage = selToPage = 0;
  35. }
  36.  
  37. void TTestPrintout::PrintPage(int /*page*/, TRect& /*bandRect*/, unsigned /*flags*/)
  38. {
  39.   
  40.   TPrintDC& dc = *DC;
  41.   TSize     pageSize = PageSize;
  42.  
  43.   //
  44.   // Do the text stuff if this band can handle it.
  45.   //
  46.   const char* lines[6] = {
  47.     "*Line 1: This small text starts at DC origin*",
  48.     "*Line 2: Text only. 1 page of 6 lines.  This large text should be centered.*",
  49.     "*Line 3: This small text should be right-justified.*",
  50.     "*Line 4: This bold text should be on the bottom of the page.*",
  51.     "*Line 5: Line 4 might not be displayed if driver gives wrong size info.*",
  52.     "*Line 6: This line runs vertically.*"
  53.   };
  54.   TEXTMETRIC tm;
  55.   int h;
  56.  
  57.   //
  58.   // Size the fonts to whatever DC we print to
  59.   //
  60.   h = -MulDiv(dc.GetDeviceCaps(LOGPIXELSY), abs(-12), 72);
  61.   TFont fontSmall(h, 0, 0, 0, FW_NORMAL, 0, 0, 0,
  62.                   ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  63.                   DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, NULL);
  64.  
  65.   h = -MulDiv(dc.GetDeviceCaps(LOGPIXELSY), abs(-24), 72);
  66.   TFont fontBig(h, 0, 0, 0, FW_NORMAL, 0, 0, 0,
  67.                 ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  68.                 DRAFT_QUALITY, VARIABLE_PITCH | FF_SWISS, NULL);
  69.  
  70.   h = -MulDiv(dc.GetDeviceCaps(LOGPIXELSY), abs(-14), 72);
  71.   TFont fontItalic(h, 0, 0, 0, FW_NORMAL, TRUE, 0, 0,
  72.                    ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  73.                    DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, NULL);
  74.  
  75.   h = -MulDiv(dc.GetDeviceCaps(LOGPIXELSY), abs(-18), 72);
  76.   TFont fontBold(h, 0, 0, 0, FW_BOLD, 0, 0, 0,
  77.                  ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  78.                  PROOF_QUALITY, VARIABLE_PITCH | FF_SWISS, NULL);
  79.  
  80.   h = -MulDiv(dc.GetDeviceCaps(LOGPIXELSY), abs(-14), 72);
  81.   TFont fontVertical(h, 0, 2700, 2700, FW_NORMAL, 0, 0, 0,
  82.                      ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  83.                      DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, NULL);
  84.  
  85.   TSize     extent;
  86.   dc.SetBkMode(TRANSPARENT);
  87.  
  88.   //
  89.   // top of the page
  90.   //
  91.   dc.SelectObject(fontSmall);
  92.   dc.GetTextMetrics(tm);
  93.   dc.TextOut(0, 0, lines[0], strlen(lines[0]));
  94.  
  95.   //
  96.   // centered
  97.   //
  98.   dc.SelectObject(fontBig);
  99.   dc.GetTextMetrics(tm);
  100.   extent = dc.GetTextExtent(lines[1], strlen(lines[1]));
  101.   dc.TextOut((pageSize.cx / 2) - (extent.cx / 2),
  102.              (pageSize.cy / 2) - (extent.cy / 2),
  103.              lines[1], strlen(lines[1]));
  104.  
  105.   //
  106.   // right justified, above vertical center
  107.   //
  108.   dc.SelectObject(fontSmall);
  109.   dc.GetTextMetrics(tm);
  110.   extent = dc.GetTextExtent(lines[2], strlen(lines[2]));
  111.   dc.TextOut(pageSize.cx - extent.cx,
  112.              (pageSize.cy / 2) - (5 * extent.cy),
  113.              lines[2], strlen(lines[2]));
  114.  
  115.   //
  116.   // bottom of page
  117.   //
  118.   dc.SelectObject(fontBold);
  119.   dc.GetTextMetrics(tm);
  120.   extent = dc.GetTextExtent(lines[3], strlen(lines[3]));
  121.   dc.TextOut(0, pageSize.cy - extent.cy, lines[3], strlen(lines[3]));
  122.  
  123.   //
  124.   // below vertical center, left side
  125.   //
  126.   dc.SelectObject(fontItalic);
  127.   dc.GetTextMetrics(tm);
  128.   extent = dc.GetTextExtent(lines[4], strlen(lines[4]));
  129.   dc.TextOut(0, (pageSize.cy / 2) + (5 * extent.cy), lines[4], strlen(lines[4]));
  130.  
  131.   //
  132.   // right of center line, top, text rotated 270 degrees (vertical)
  133.   //
  134.   dc.SelectObject(fontVertical);
  135.   dc.GetTextMetrics(tm);
  136.   extent = dc.GetTextExtent(lines[5], strlen(lines[5]));
  137.   dc.TextOut((pageSize.cx / 2) + extent.cy, extent.cy * 2, lines[5], strlen(lines[5]));
  138.   
  139.  
  140.   //
  141.   // Do the graphics stuff if this band can handle it
  142.   //
  143.   TPoint p(pageSize.cx / 4, pageSize.cy / 4);
  144.   dc.SelectStockObject(HOLLOW_BRUSH);
  145.  
  146.   dc.Rectangle(p.x, p.y, pageSize.cx-p.x, pageSize.cy-p.y);
  147.   dc.Rectangle(0, 0, pageSize.cx, pageSize.cy);
  148.   dc.MoveTo(0, 0);
  149.   dc.LineTo(pageSize.cx, pageSize.cy);
  150.   dc.MoveTo(pageSize.cx, 0);
  151.   dc.LineTo(0, pageSize.cy);
  152.   dc.MoveTo(pageSize.cx / 2, -50);
  153.   dc.LineTo(pageSize.cx / 2, pageSize.cy + 50);
  154.  
  155.   dc.Ellipse(pageSize.cx / 2 - pageSize.cx / 4,
  156.              pageSize.cy / 2 - pageSize.cy / 4,
  157.              pageSize.cx / 2 + pageSize.cx / 4,
  158.              pageSize.cy / 2 + pageSize.cy / 4);
  159.  
  160.   dc.RestoreObjects();
  161. }
  162.  
  163.  
  164. //----------------------------------------------------------------------------
  165. //
  166. // Printout class that prints the contents of a window
  167. //
  168. class TWindowPrintout : public TPrintout {
  169.   public:
  170.     TWindowPrintout(const char* title, TWindow* window, BOOL scale = TRUE)
  171.       : TPrintout(title)
  172.       { Window = window;
  173.         Scale = scale;
  174.         //MapMode = MM_ISOTROPIC;    // Respect aspect ratio of window
  175.         MapMode = MM_ANISOTROPIC;  // Make printout fill the page
  176.       }
  177.  
  178.     void GetDialogInfo(int& minPage, int& maxPage, int& selFromPage, int& selToPage);
  179.     void PrintPage(int page, TRect& rect, unsigned flags);
  180.     
  181.   protected:
  182.     TWindow*  Window;
  183.     BOOL      Scale;
  184.     int       MapMode;
  185. };
  186.  
  187.  
  188. // Do not enable page range in the print dialog since only one page is
  189. // available to be printed
  190. //
  191. void TWindowPrintout::GetDialogInfo(int& minPage, int& maxPage, int& selFromPage, int& selToPage)
  192. {
  193.   minPage = 0;
  194.   maxPage = 0;
  195.   selFromPage = selToPage = 0;
  196. }
  197.  
  198.  
  199. void TWindowPrintout::PrintPage(int /*page*/, TRect& bandRect, unsigned /*flags*/)
  200. {
  201.   // Conditionally scale the DC to the window so the printout will
  202.   // resemble the window
  203.   //
  204.   int    oldMode;
  205.   TSize  oldVExt, oldWExt;
  206.   if (Scale) {
  207.     oldMode = DC->SetMapMode(MapMode);
  208.     TRect clientR = Window->GetClientRect();
  209.     DC->SetViewportExt(PageSize, &oldVExt);
  210.     DC->SetWindowExt(clientR.Size(), &oldWExt);
  211.     DC->IntersectClipRect(clientR);
  212.     DC->DPtoLP(bandRect, 2);
  213.   }
  214.  
  215.   // Call the window to paint itself to the printer DC.
  216.   //
  217.   Window->Paint(*DC, FALSE, bandRect);
  218.  
  219.   // Restore changes made to the DC
  220.   //
  221.   if (Scale) {
  222.     DC->SetWindowExt(oldWExt);
  223.     DC->SetViewportExt(oldVExt);
  224.     DC->SetMapMode(oldMode);
  225.   }
  226. }
  227.  
  228. //----------------------------------------------------------------------------
  229.  
  230. class TModalFrame : public TFrameWindow {
  231.   public:
  232.     TModalFrame (TWindow* parent, const char far* title, TWindow* client) :
  233.       TFrameWindow(parent, title, client),
  234.       TWindow(parent, title)  {}
  235.  
  236.     virtual void Destroy(int ret);
  237. };
  238.  
  239.  
  240. void TModalFrame::Destroy(int ret)
  241. {
  242.   GetApplication()->EndModal(IDCANCEL);
  243.   GetApplication()->MainWindow->EnableWindow(TRUE);
  244.  
  245.   TWindow::Destroy(ret);
  246. }
  247.  
  248. //----------------------------------------------------------------------------
  249.  
  250. class TMyClientWindow : public TWindow {
  251.   public:
  252.     TPrinter* Printer;
  253.  
  254.     TMyClientWindow() : TWindow(0, "")   {Printer = 0;}
  255.  
  256.     void Paint(TDC& dc, BOOL erase, TRect& rect);
  257.     void EvSize(UINT sizeType, TSize& size);
  258.  
  259.     void CmPrinterSetup();
  260.     void CmPrint();
  261.     void CmPrintPreview();
  262.  
  263.   DECLARE_RESPONSE_TABLE(TMyClientWindow);
  264. };
  265.  
  266.  
  267. DEFINE_RESPONSE_TABLE1(TMyClientWindow, TWindow)
  268.   EV_WM_SIZE,
  269.   EV_COMMAND(CM_PRINTERSETUP, CmPrinterSetup),
  270.   EV_COMMAND(CM_PRINT, CmPrint),
  271.   EV_COMMAND(CM_PRINTPREVIEW, CmPrintPreview),
  272. END_RESPONSE_TABLE;
  273.  
  274.  
  275. void TMyClientWindow::EvSize(UINT sizeType, TSize& size)
  276. {
  277.   TWindow::EvSize(sizeType, size);
  278.   Invalidate(TRUE);
  279. }
  280.  
  281.  
  282. void TMyClientWindow::CmPrinterSetup()
  283. {
  284.   if (!Printer)
  285.     Printer = new TPrinter;
  286.  
  287.   Printer->Setup(this);
  288. }
  289.  
  290.  
  291. void TMyClientWindow::CmPrint()
  292. {
  293.   //
  294.   // Create Printer object if not already created.
  295.   // 
  296.   if (!Printer)
  297.     Printer = new TPrinter;
  298.  
  299.   #if defined(USE_WINDOW_PRINTOUT)
  300.     TWindowPrintout printout("Print Preview Printer Output", this);
  301.   #else
  302.     TTestPrintout   printout("Print Preview Printer Output");
  303.   #endif
  304.  
  305.   Printer->Print(this, printout, TRUE);
  306. }
  307.  
  308.  
  309. void TMyClientWindow::CmPrintPreview()
  310. {
  311.   if (!Printer)
  312.     Printer = new TPrinter;
  313.  
  314.   //
  315.   // Create the printer DC. If it fails, let the print dialog report the error
  316.   // for us.
  317.   //
  318.   TPrintDC* prnDC;
  319.   try {
  320.     prnDC = new TPrintDC(Printer->GetSetup().GetDriverName(),
  321.                          Printer->GetSetup().GetDeviceName(),
  322.                          Printer->GetSetup().GetOutputName(),
  323.                          Printer->GetSetup().GetDevMode());
  324.   }
  325.   catch (TGdiBase::TXGdi) {
  326.     TPrintDialog(Parent, Printer->GetSetup()).Execute();
  327.     return;
  328.   }
  329.   
  330.   TSize printExtent(prnDC->GetDeviceCaps(HORZRES), prnDC->GetDeviceCaps(VERTRES));
  331.  
  332.   #if defined(USE_WINDOW_PRINTOUT)
  333.     TWindowPrintout printout("Print Preview", this);
  334.   #else
  335.     TTestPrintout   printout("Print Preview");
  336.   #endif
  337.  
  338.   TLayoutWindow* layout = new TLayoutWindow(0);
  339.   layout->SetBkgndColor(GetSysColor(COLOR_APPWORKSPACE));
  340.  
  341.   for (int i = 0; i < 1; i++) {
  342.     TPreviewPage* page = new TPreviewPage(layout, printout, *prnDC, printExtent);
  343.  
  344.     TLayoutMetrics metrics;
  345.     metrics.X.Set(lmLeft, lmRightOf, lmParent, lmLeft, 15);
  346.     metrics.Y.Set(lmTop, lmBelow, lmParent, lmTop, 15);
  347.  
  348.     //
  349.     // Determine major axis of preview page, have that follow parent size.
  350.     // Make minor axis a percentage (aspect ratio) of the page's major axis
  351.     //
  352.     if (printExtent.cx > printExtent.cy) {
  353.       metrics.Width.Set(lmRight, lmLeftOf, lmParent, lmRight, 15);
  354.       metrics.Height.PercentOf(page, int((long(printExtent.cy)*100)/printExtent.cx),
  355.                                lmWidth);
  356.     } else {
  357.       metrics.Height.Set(lmBottom, lmAbove, lmParent, lmBottom, 15);
  358.       metrics.Width.PercentOf(page, int((long(printExtent.cx)*100)/printExtent.cy),
  359.                               lmHeight);
  360.     }
  361.  
  362.     layout->SetChildLayoutMetrics(*page, metrics);
  363.   }
  364.  
  365.   TFrameWindow* frame = new TModalFrame(this, "Preview", layout);
  366.   frame->Create();
  367.   frame->ShowWindow(SW_SHOWNORMAL);
  368.  
  369.   GetApplication()->BeginModal(Parent);
  370.   delete prnDC;
  371. }
  372.  
  373.  
  374. void TMyClientWindow::Paint(TDC& dc, BOOL erase, TRect& rect)
  375. {
  376.   if (erase)
  377.     dc.FillRect(rect, TBrush(TColor::White));
  378.  
  379.   TRect   clientR = GetClientRect();
  380.   TSize   pageSize(clientR.right - clientR.left, clientR.bottom - clientR.top);
  381.  
  382.  
  383.   //
  384.   // Do the text stuff.
  385.   //
  386.   const char* lines[6] = {
  387.     "*Line 1: This small text starts at DC origin*",
  388.     "*Line 2: Text only. 1 page of 6 lines.  This large text should be centered.*",
  389.     "*Line 3: This small text should be right-justified.*",
  390.     "*Line 4: This bold text should be on the bottom of the page.*",
  391.     "*Line 5: Line 4 might not be displayed if driver gives wrong size info.*",
  392.     "*Line 6: This line runs vertically.*"
  393.   };
  394.   int     h;
  395.  
  396.   h = -12;
  397.   TFont fontSmall(h, 0, 0, 0, FW_NORMAL, 0, 0, 0,
  398.                   ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  399.                   DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, NULL);
  400.  
  401.   h = -24;
  402.   TFont fontBig(h, 0, 0, 0, FW_NORMAL, 0, 0, 0,
  403.                 ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  404.                 DRAFT_QUALITY, VARIABLE_PITCH | FF_SWISS, NULL);
  405.  
  406.   h = -14;
  407.   TFont fontItalic(h, 0, 0, 0, FW_NORMAL, TRUE, 0, 0,
  408.                    ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  409.                    DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, NULL);
  410.  
  411.   h = -18;
  412.   TFont fontBold(h, 0, 0, 0, FW_BOLD, 0, 0, 0,
  413.                  ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  414.                  PROOF_QUALITY, VARIABLE_PITCH | FF_SWISS, NULL);
  415.  
  416.   h = -14;
  417.   TFont fontVertical(h, 0, 2700, 2700, FW_NORMAL, 0, 0, 0,
  418.                      ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  419.                      DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, NULL);
  420.  
  421.   TSize     extent;
  422.   dc.SetBkMode(TRANSPARENT);
  423.  
  424.   //
  425.   // top of the page
  426.   //
  427.   dc.SelectObject(fontSmall);
  428.   dc.TextOut(0, 0, lines[0], strlen(lines[0]));
  429.  
  430.   //
  431.   // centered
  432.   //
  433.   dc.SelectObject(fontBig);
  434.   extent = dc.GetTextExtent(lines[1], strlen(lines[1]));
  435.   dc.TextOut((pageSize.cx / 2) - (extent.cx / 2),
  436.              (pageSize.cy / 2) - (extent.cy / 2),
  437.              lines[1], strlen(lines[1]));
  438.  
  439.   //
  440.   // right justified, above vertical center
  441.   //
  442.   dc.SelectObject(fontSmall);
  443.   extent = dc.GetTextExtent(lines[2], strlen(lines[2]));
  444.   dc.TextOut(pageSize.cx - extent.cx,
  445.              (pageSize.cy / 2) - (5 * extent.cy),
  446.              lines[2], strlen(lines[2]));
  447.  
  448.   //
  449.   // bottom of page
  450.   //
  451.   dc.SelectObject(fontBold);
  452.   extent = dc.GetTextExtent(lines[3], strlen(lines[3]));
  453.   dc.TextOut(0, pageSize.cy - extent.cy, lines[3], strlen(lines[3]));
  454.  
  455.   //
  456.   // below vertical center, left side
  457.   //
  458.   dc.SelectObject(fontItalic);
  459.   extent = dc.GetTextExtent(lines[4], strlen(lines[4]));
  460.   dc.TextOut(0, (pageSize.cy / 2) + (5 * extent.cy), lines[4], strlen(lines[4]));
  461.  
  462.   //
  463.   // right of center line, top, text rotated 270 degrees (vertical)
  464.   //
  465.   dc.SelectObject(fontVertical);
  466.   extent = dc.GetTextExtent(lines[5], strlen(lines[5]));
  467.   dc.TextOut((pageSize.cx / 2) + extent.cy, extent.cy * 2, lines[5], strlen(lines[5]));
  468.  
  469.   //
  470.   // Do the graphics stuff.
  471.   //
  472.  
  473.   TPoint p(pageSize.cx / 4, pageSize.cy / 4);
  474.   dc.SelectStockObject(HOLLOW_BRUSH);
  475.  
  476.   dc.Rectangle(p.x, p.y, pageSize.cx-p.x, pageSize.cy-p.y);
  477.   dc.Rectangle(0, 0, pageSize.cx, pageSize.cy);
  478.   dc.MoveTo(0, 0);
  479.   dc.LineTo(pageSize.cx, pageSize.cy);
  480.   dc.MoveTo(pageSize.cx, 0);
  481.   dc.LineTo(0, pageSize.cy);
  482.   dc.MoveTo(pageSize.cx / 2, -50);
  483.   dc.LineTo(pageSize.cx / 2, pageSize.cy + 50);
  484.  
  485.   dc.Ellipse(pageSize.cx / 2 - pageSize.cx / 4,
  486.              pageSize.cy / 2 - pageSize.cy / 4,
  487.              pageSize.cx / 2 + pageSize.cx / 4,
  488.              pageSize.cy / 2 + pageSize.cy / 4);
  489.  
  490.   dc.RestoreObjects();
  491. }
  492.  
  493.  
  494. class TPrintApp : public TApplication {
  495.   public:
  496.     void InitMainWindow()
  497.     {
  498.       MainWindow = new TFrameWindow(0, "Printer Test", new TMyClientWindow); 
  499.       MainWindow->AssignMenu(100);
  500.     }
  501. };
  502.  
  503.  
  504. int OwlMain(int /*argc*/, char* /*argv*/ [])
  505. {
  506.   return TPrintApp().Run();
  507. }
  508.