home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / OWLSRC.PAK / RICHEDPR.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  9.8 KB  |  369 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1995, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   10.5  $
  6. //
  7. // Implementation of support classes for Print/PrintPreview of TRichEdits
  8. //----------------------------------------------------------------------------
  9. #include <owl/pch.h>
  10. #if !defined(OWL_WINDOW_H)
  11. # include <owl/window.h>
  12. #endif
  13. #if !defined(OWL_CONTROL_H)
  14. # include <owl/control.h>
  15. #endif
  16. #if !defined(OWL_EDIT_H)
  17. # include <owl/edit.h>
  18. #endif
  19. #if !defined(OWL_EDITSEAR_H)
  20. # include <owl/editsear.h>
  21. #endif
  22. #if !defined(OWL_EDITFILE_H)
  23. # include <owl/editfile.h>
  24. #endif
  25. #if !defined(OWL_RICHEDIT_H)
  26. # include <owl/richedit.h>
  27. #endif
  28. #if !defined(OWL_RICHEDPR_H)
  29. # include <owl/richedpr.h>
  30. #endif
  31.  
  32. OWL_DIAGINFO;
  33.  
  34. //
  35. //
  36. //
  37. const int PageIndexInit  = 5;
  38. const int PageIndexDelta = 5;   
  39.  
  40. //
  41. // Constructs a Printout object which represent a RICHEDIT's document
  42. //
  43. TRichEditPrintout::TRichEditPrintout(TPrinter& printer, 
  44.                                      TRichEdit& richEdit,
  45.                                      const char far *title)
  46.  TPrintout(title),
  47.  Printer(printer),
  48.  RichEdit(richEdit),
  49.  SizePhysPage(0),
  50.  SizePhysInch(0),
  51.  Margins(0),
  52.  FlushCache(false),
  53.  PageIndices(PageIndexInit, PageIndexDelta)
  54.   PRECONDITION(HWND(RichEdit));
  55.  
  56.   // Initialize data members
  57.   //
  58.   PageCount      = 0;
  59.   TextLen        = 0;
  60.   PageIndices[0] = 0;
  61. }
  62.  
  63. //
  64. // Destructor of 'RichEdit PrintOut' - Flushes any cached formatting 
  65. // information
  66. //
  67. TRichEditPrintout::~TRichEditPrintout()
  68. {
  69.   // Flush cached format information
  70.   //
  71.   if (FlushCache) {
  72.     CHECK(HWND(RichEdit));
  73.     RichEdit.FormatRange();
  74.   }
  75. }
  76.  
  77. //
  78. // This method is invoked by the printer or print-preview classes to allow
  79. // the printout to update the page range information.
  80. //
  81. void 
  82. TRichEditPrintout::GetDialogInfo(int& minPage, int& maxPage, 
  83.                                  int& selFromPage, int& selToPage)
  84. {
  85.   if (PageCount && TextLen) {
  86.     minPage = 1;
  87.     maxPage = PageCount;
  88.  
  89.     CHECK(HWND(RichEdit));
  90.     uint startSel, endSel;
  91.     RichEdit.GetSelection(startSel, endSel);
  92.  
  93.     //
  94.     selFromPage = startSel != endSel ? PageOfOffset(startSel) : 1;
  95.     selToPage = PageCount > selFromPage ? selFromPage+1 : 0;
  96.   }
  97.   else {
  98.     minPage = maxPage = 0;
  99.     selFromPage = selToPage = 0;
  100.   }
  101. }
  102.  
  103. //
  104. // This method is invoked by the printer or print-preview objects to hand
  105. // the printout object the target device context and the size of its pages.
  106. //
  107. void
  108. TRichEditPrintout::SetPrintParams(TPrintDC* dc, TSize pageSize)
  109. {
  110.   PRECONDITION(HWND(RichEdit));
  111.  
  112.   // Chain call base class' version
  113.   //
  114.   TPrintout::SetPrintParams(dc, pageSize);
  115.  
  116.   // Update size info about printer DC
  117.   //
  118.   SizePhysInch = TSize(dc->GetDeviceCaps(LOGPIXELSX),
  119.                        dc->GetDeviceCaps(LOGPIXELSY));
  120.   SizePhysPage = TSize(dc->GetDeviceCaps(PHYSICALWIDTH), 
  121.                        dc->GetDeviceCaps(PHYSICALHEIGHT));
  122.   if (!SizePhysPage.cx)
  123.     SizePhysPage.cx = dc->GetDeviceCaps(HORZRES);
  124.   if (!SizePhysPage.cy)
  125.     SizePhysPage.cy = dc->GetDeviceCaps(VERTRES);
  126.  
  127.  
  128.   // Set up the target and render DCs
  129.   // NOTE: In the case of PrintPreview, the two HDCs differ.
  130.   //       When we're really printing, the attribute DC and
  131.   //       GetHDC() return the same HDC.
  132.   //
  133.   FmtRange.SetTargetDC(dc->GetAttributeHDC()); // Format Device
  134.   FmtRange.SetRenderDC(dc->GetHDC());          // Render Device
  135.  
  136.   // Set the page and render rectangles in twips 
  137.   // Handle margins, if requested.
  138.   //
  139.   TRect rect(0, 0, MulDiv(SizePhysPage.cx, 1440, SizePhysInch.cx),
  140.                    MulDiv(SizePhysPage.cy, 1440, SizePhysInch.cy));
  141.   if (Margins.cx) {
  142.     ;
  143.   }
  144.   if (Margins.cy) {
  145.     ;
  146.   }
  147.   FmtRange.SetPageRect(rect);
  148.   FmtRange.SetRenderRect(rect);
  149.  
  150.   // Retrieve length of document and set range
  151.   //
  152.   TextLen = RichEdit.GetWindowTextLength();
  153.  
  154.   // Compute number of pages and cache their offsets
  155.   //
  156.   if (TextLen > 0) {
  157.     PageCount = 1;                  // Pages are not zero-based
  158.     FmtRange.SetRange(0, TextLen);  // Format entire range.....
  159.     int endOfRange;
  160.     do {
  161.       endOfRange = RichEdit.FormatRange(FmtRange, false);
  162.       PageIndices[PageCount++] = endOfRange;
  163.       FmtRange.chrg.cpMin = endOfRange;
  164.       FmtRange.SetRenderRect(rect); // Ctl seems to corrupt the 'rc' member!
  165.     } while (FmtRange.chrg.cpMin < TextLen);
  166.  
  167.     PageCount--;
  168.  
  169.     // Free cached formatting information
  170.     //
  171.     RichEdit.FormatRange();
  172.   } 
  173.   else {
  174.     PageCount = 0;
  175.   }
  176. }
  177.  
  178. //
  179. // This routine is invoked to inform the printout that a printing 
  180. // operation has begun. 
  181. //
  182. void 
  183. TRichEditPrintout::BeginPrinting()
  184. {
  185. }
  186.  
  187. //
  188. // This routine is invoked to inform the printout that the printing
  189. // operation has ended.
  190. //
  191. void
  192. TRichEditPrintout::EndPrinting()
  193. {
  194. }
  195.  
  196. //
  197. // This routine is invoked to request the printout object to print a page
  198. //
  199. void 
  200. TRichEditPrintout::PrintPage (int page, TRect& bandRect, unsigned)
  201. {
  202.   PRECONDITION(page > 0);
  203.   PRECONDITION(page <= PageCount);
  204.  
  205.   // Check control's handle is !0
  206.   //
  207.   PRECONDITION(HWND(RichEdit));
  208.  
  209.   // These should have been set via a prior call to 'SetPrintParams' 
  210.   //
  211.   PRECONDITION(FmtRange.hdcTarget !=0);
  212.   PRECONDITION(FmtRange.hdc != 0);
  213.  
  214.   // Check whether we're in 'real' printing mode or just print preview.
  215.   // In print preview mode the target does not match the render DC.....
  216.   //
  217.   if (FmtRange.hdc != FmtRange.hdcTarget) {
  218.  
  219.     int saveId = SaveDC(FmtRange.hdc);
  220.     if (FmtRange.hdc) {
  221.       TDC dc(FmtRange.hdc);
  222.  
  223.       // Make window DC match target's logical size
  224.       //
  225.       dc.SetMapMode(MM_ANISOTROPIC);
  226.       dc.SetWindowExt(TSize(MulDiv(SizePhysPage.cx, 
  227.                                   dc.GetDeviceCaps(LOGPIXELSX), 
  228.                                   SizePhysInch.cx),
  229.                             MulDiv(SizePhysPage.cy, 
  230.                                   dc.GetDeviceCaps(LOGPIXELSY), 
  231.                                   SizePhysInch.cy)));
  232.       dc.SetViewportExt(TSize(bandRect.Width(), bandRect.Height()));
  233.  
  234.       // Update character range for specified page
  235.       //
  236.       FmtRange.SetRange(PageIndices[page-1], PageIndices[page]);
  237.  
  238.       // Have Edit control draw into window
  239.       //
  240.       RichEdit.FormatRange(FmtRange);
  241.  
  242.       // Flag that we need to reset control
  243.       //
  244.       FlushCache = true;
  245.     }
  246.     // Restore the DC
  247.     //
  248.     RestoreDC(FmtRange.hdc, saveId);
  249.   }
  250.   else {
  251.     // We're really printing! Update character range for specified page
  252.     //
  253.     FmtRange.SetRange(PageIndices[page-1], PageIndices[page]);
  254.  
  255.     // Have Edit control format data
  256.     //
  257.     RichEdit.FormatRange(FmtRange, false);
  258.  
  259.     // Flag that we need to reset control
  260.     //
  261.     FlushCache = true;
  262.  
  263.     // Have Edit control display to render rectangle of device
  264.     //
  265.     RichEdit.DisplayBand(*((TRect*)&FmtRange.rc));
  266.   }
  267. }
  268.  
  269. //
  270. // This routine is invoked to asked the printout object whether it has
  271. // necessary information to print the specified page.
  272. //
  273. bool 
  274. TRichEditPrintout::HasPage (int pageNumber)
  275. {
  276.   return pageNumber > 0 && pageNumber <= PageCount;
  277. }
  278.  
  279. //
  280. // Return the index of the page at the particular offset within the buffer
  281. // of an edit control.
  282. //
  283. int
  284. TRichEditPrintout::PageOfOffset(int offset)
  285. {
  286.   PRECONDITION(offset <= TextLen);
  287.   
  288.   int page = 0;
  289.   if (PageCount > 0) {
  290.     for (int i=1; i<=PageCount; i++) {
  291.       if (PageIndices[i] >= offset) {
  292.         if (PageIndices[i-1] <= offset) {
  293.           page = i;
  294.           break;
  295.         }
  296.       }    
  297.     }    
  298.   }
  299.   return page;
  300. }
  301.  
  302. //
  303. // Constructor of RichEdit PagePreview object
  304. //
  305. TRichEditPagePreview::TRichEditPagePreview(TWindow* parent, 
  306.                                            TPrintout& printout,
  307.                                            TPrintDC& prndc,
  308.                                            TSize& printExtent,
  309.                                            int pagenum)
  310. :
  311.   TPreviewPage(parent, printout, prndc, printExtent, pagenum)
  312. {
  313. }
  314.  
  315. //
  316. // WM_PAINT handler of RichEdit PagePreview window. Displays a preview of the
  317. // page if the printout can handle it. Otherwise, simply fills the window
  318. // with a white background.
  319. //
  320. void
  321. TRichEditPagePreview::Paint(TDC& dc, bool, TRect& /*clip*/) 
  322. {
  323.   TRect client;
  324.   GetClientRect(client);
  325.  
  326.   TPreviewDCBase pdc(dc, PrintDC);
  327.   Printout.SetPrintParams(&pdc, PrintExtent);
  328.  
  329.   if (Printout.HasPage(PageNum)) {
  330.     Printout.BeginPrinting();
  331.     Printout.BeginDocument(PageNum, PageNum, pfBoth);
  332.     Printout.PrintPage(PageNum, client, pfBoth);
  333.     Printout.EndDocument();
  334.     Printout.EndPrinting();
  335.   }
  336.   else
  337.     dc.PatBlt(client, WHITENESS);
  338. }
  339.  
  340. //
  341. // Constructor of a RichEdit Preview Frame
  342. //
  343. TRichEditPreviewFrame::TRichEditPreviewFrame(TWindow* parentWindow, 
  344.                                              TPrinter& printer, 
  345.                                              TPrintout& printout, 
  346.                                              TRichEdit& richEdit, 
  347.                                              const char far* title, 
  348.                                              TLayoutWindow* client)
  349. :
  350.   TPreviewWin(parentWindow, printer, printout, richEdit, title, client)
  351. {
  352. }
  353.  
  354. //
  355. // Return pointer to a preview page object
  356. //
  357. TPreviewPage* 
  358. TRichEditPreviewFrame::GetNewPreviewPage(TWindow* parent, 
  359.                                          TPrintout& printout,
  360.                                          TPrintDC&  prndc,
  361.                                          TSize&     printExtent,
  362.                                          int        pagenum)
  363. {
  364.   return new TRichEditPagePreview(parent, printout, prndc, 
  365.                                   printExtent, pagenum);
  366. }
  367.