View this file in the BC++ editor. I use 1024x768 with long lines, so I
appologize if this presents a nuisance to you.

I found the standard AppExpert generated code for print preview somewhat
unsatisfactory.  You might be be satisfied with the results of making
the following small change to that code as long as you want to use the APXPrintout:
	change HORZRES and VERTRES to HORZSIZE and VERTRES respectively
	in the line in the PreviewWindow constructor.

 PrintExtent = new TSize(PrnDC->GetDeviceCaps(HORZRES), PrnDC->GetDeviceCaps(VERTRES));

This will result in a full height preview which will allow two pages on
the screen at once in portrait mode.

A couple of recommendations for Borland about MDI Doc/View AppExpert generated code:
	Add a virtual function TView::GetPrintout() that returns a printout object.
	Modify the TxxxMDIClient::CmFilePrintPreview to query the active view
		for a printout.  If the view doesn't supply a printout, then create
		a default APXPrintout.  Pass the printout as a parameter to the
		PreviewWindow constructor.

Because I use printouts that are not just screen copies, my current
workaround is to modify the PreviewWindow class to take a TPrintout*
parameter and then supply each view with a CmFilePrintPreview function
that passes the appropriate printout to PreviewWindow.  (This code
is taken directly from the TxxxMDIClient::CmFilePrintPreview function,
which I then found unnecessary and removed.)  I made a couple of other
small changes that you might find interesting.  I added a couple of bitmaps
and gadgets for zooming between full height and full width modes and added a
vertical scrollbar so that you can scroll over the full height when in
full width mode.

The modifications are commented.  Its got some rough edges, but these
changes might provide you with a better starting point for creating
your own print preview.  Some suggestions for improvement might include
adding other zoom modes that would involve horizontal scrolling, and jumping
to specific page numbers.  If you improve this routine, I would hope
that you would replace this file with an upload of your improved version.
I would also hope that Borland is working on improving the Print Preview
capability for the next version of BC++.

To use, you must create your own TxxxPrintout objects. APXPrintout doesn't
work for me.  Make the following changes to the indicated files, and replace the
AppExpert generated apxprev.h and apxprev.cpp with my modified versions.
You will also need to change the #include for xxxapp.rh in the apxprev.h file
to include your own resource header.

I included a simple TTestPrintOut that you can use to test whether you have
things working properly.  I would strongly recommend that you first create a simple
AppExpert SDI application and make the print preview modifications there first,
before trying it in more complicated applications and printouts.  There won't
be anything in the main window, but the print preview will work anyway.

I don't intend to support these modifications.  This file is provided
just to give you ideas for writing your own improved print preview.
Since most of the code presented here is Borland's, I'm not sure what
the status of these files is, but I offer my modifications as freeware.

Good luck,

Walt


The changes follow:

//*******************************************************************
// just a simple test printout class provided to test the print preview
// If you test in the simple SDI app as recommended, just cut and paste
// at the top of the TxxxApp.cpp file generated by AppExpert
//*******************************************************************
class TTestPrintOut : public TPrintout {
public:
	 TTestPrintOut(const char far *title) : TPrintout(title) {}
	 ~TTestPrintOut() {}

	 void GetDialogInfo (int& minPage, int& maxPage, int& selFromPage, int& selToPage);
	 void PrintPage (int page, TRect& rect, unsigned flags);
	 BOOL HasPage (int pageNumber) { return pageNumber>0 && pageNumber<4; }
};

void TTestPrintOut::GetDialogInfo (int& minPage, int& maxPage, int& selFromPage, int& selToPage)
{
	 minPage = 1; maxPage = 3;
	 selFromPage = selToPage = 0;
}

void TTestPrintOut::PrintPage (int page, TRect&, unsigned)
{
	int oldMapMode=DC->SetMapMode(MM_TEXT);
	// Note that it is necessary to reevaluate PageSize so that Preview will work
	PageSize.cx=DC->GetDeviceCaps(HORZRES);
	PageSize.cy=DC->GetDeviceCaps(VERTRES);
	TSize margins((DC->GetDeviceCaps(LOGPIXELSX))/2,   // half inch left and top margins
					  (DC->GetDeviceCaps(LOGPIXELSY))/2);
	TFont   normalFont("Arial", -10*DC->GetDeviceCaps(LOGPIXELSY)/72);
	TFont   largeFont("Arial",  -16*DC->GetDeviceCaps(LOGPIXELSY)/72);
	DC->SelectObject(normalFont);

	char left[]="Left";  char right[]="Right"; char top[]="Top"; char bottom[]="Bottom";
	char center[]="Center";
	// use the same text on each page to mark the sides
	TSize size=DC->GetTextExtent(top, strlen(top));
	DC->TextOut((PageSize.cx-size.cx)/2, margins.cy, top);
	size=DC->GetTextExtent(left, strlen(left));
	DC->TextOut(margins.cx, (PageSize.cy-size.cy)/2, left);
	size=DC->GetTextExtent(right, strlen(right));
	DC->TextOut(PageSize.cx-margins.cx-size.cx, (PageSize.cy-size.cy)/2, right);
	size=DC->GetTextExtent(bottom, strlen(bottom));
	DC->TextOut((PageSize.cx-size.cx)/2, PageSize.cy-margins.cy-size.cy, bottom);
	// add a little something to distinguish each page
	TRect rect(PageSize.cx/2-margins.cx, PageSize.cy/2-margins.cy,
				  PageSize.cx/2+margins.cx, PageSize.cy/2+margins.cy);
	switch (page) {
		case 1:
			break;
		case 2:
			DC->Rectangle(rect);
			break;
		case 3:
			DC->Ellipse(rect);
			break;
	}
	DC->RestoreFont();
	DC->SelectObject(largeFont);
	size=DC->GetTextExtent(center, strlen(center));
	DC->TextOut((PageSize.cx-size.cx)/2, (PageSize.cy-size.cy)/2, center);

	DC->RestoreFont();
	DC->SetMapMode(oldMapMode);
}


// Remove the CmFilePrintPreview and CmFilePrint function from TxxxMDIClient
// you will also need to add these includes to your TxxxView.h file
#include "xxxApp.h"             // for TxxxApp declaration
#include "apxprev.h"            // for PreviewWindow declaration
//*******************************************************************
// which functions to modify depends on whether using Doc/View or not
//*******************************************************************
void TxxxView::CmFilePrintPreview ()     // or TxxxApp::CmFilePrintPreview()
{
	 // INSERT>> Your code here.
	 TxxxApp *theApp = TYPESAFE_DOWNCAST(GetApplication(), TxxxApp);
	 if (theApp) {
		  if (!theApp->Printer)
				theApp->Printer = new TPrinter;

		  theApp->Printing = TRUE;

//*******************************************************************
		  // this is the only change to the TxxxMDIClient::CmFilePrintPreview code
		  // removed the code using APXPrintout
		  // TTestPrintOut is derived from TPrintout, of course
//*******************************************************************
		  TTestPrintOut printout("Print Preview");
		  PreviewWindow *prevW = new PreviewWindow(this, theApp->Printer, &printout, this, "Print Preview", new TLayoutWindow(0));

		  prevW->Create();

		  GetApplication()->BeginModal(GetApplication()->MainWindow);

		  // We must destroy the preview window explicitly.  Otherwise, the window will not be destroyed until
		  // it's parent the MainWindow is destroyed.
		  prevW->Destroy();
		  delete prevW;

		  theApp->Printing = FALSE;
	 }
}

void TxxxView::CmFilePrint ()   // or TxxxApp::CmFilePrint()
{
	 // INSERT>> Your code here.
	 //
	 // Create Printer object if not already created.
	 TxxxApp *theApp = TYPESAFE_DOWNCAST(GetApplication(), TxxxApp);
	 if (theApp) {
		  if (!theApp->Printer)
				theApp->Printer = new TPrinter;
		  // Create Printout and set characteristics.
//*******************************************************************
//  Only modification is to change the printout type
//*******************************************************************
//    APXPrintOut printout(Printer, "Title", MainWindow);
//         printout.SetBanding(TRUE);
	 TTestPrintOut printout("Print Preview");
		  theApp->Printing = TRUE;
		  // Bring up the Print dialog and print the document.
		  theApp->Printer->Print(this, printout, TRUE);
		  theApp->Printing = FALSE;
	 }
}


//*******************************************************************
// add to xxxapp.rh
// You may need to use different constants to prevent conflicts.
//*******************************************************************
#define APX_PPR_ZOOMIN  400
#define APX_PPR_ZOOMOUT 401


//*******************************************************************
// add to xxxapp.rc
//*******************************************************************
APX_PPR_ZOOMIN BITMAP
{
 '42 4D 42 01 00 00 00 00 00 00 76 00 00 00 28 00'
 '00 00 13 00 00 00 11 00 00 00 01 00 04 00 00 00'
 '00 00 CC 00 00 00 00 00 00 00 00 00 00 00 00 00'
 '00 00 10 00 00 00 00 00 00 00 00 00 C0 00 00 C0'
 '00 00 00 C0 C0 00 C0 00 00 00 C0 00 C0 00 C0 C0'
 '00 00 C0 C0 C0 00 80 80 80 00 00 00 FF 00 00 FF'
 '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
 '00 00 FF FF FF 00 77 77 77 77 77 77 77 77 77 00'
 '00 00 70 00 00 77 77 77 77 77 77 00 00 00 70 FF'
 'F0 77 77 77 77 77 77 00 00 00 70 FF F0 00 00 00'
 '00 00 00 00 00 00 70 FF F0 FF FF FF FF FF F0 00'
 '00 00 70 00 00 0F FF FF FF FF F0 00 00 00 77 70'
 'F0 00 FF FF FF FF F0 00 00 00 77 70 FF 00 0F F0'
 'FF FF F0 00 00 00 77 70 FF F0 00 F0 FF FF F0 00'
 '00 00 77 70 FF FF 00 00 FF FF F0 00 00 00 77 70'
 'FF FF F0 00 FF FF F0 00 00 00 77 70 FF F0 00 00'
 'FF FF F0 00 00 00 77 70 FF FF FF FF FF FF F0 00'
 '00 00 77 70 FF FF FF FF FF FF F0 00 00 00 77 70'
 'FF FF FF FF FF FF F0 00 00 00 77 70 00 00 00 00'
 '00 00 00 00 00 00 77 77 77 77 77 77 77 77 77 00'
 '00 00'
}

APX_PPR_ZOOMOUT BITMAP
{
 '42 4D 42 01 00 00 00 00 00 00 76 00 00 00 28 00'
 '00 00 13 00 00 00 11 00 00 00 01 00 04 00 00 00'
 '00 00 CC 00 00 00 00 00 00 00 00 00 00 00 00 00'
 '00 00 10 00 00 00 00 00 00 00 00 00 C0 00 00 C0'
 '00 00 00 C0 C0 00 C0 00 00 00 C0 00 C0 00 C0 C0'
 '00 00 C0 C0 C0 00 80 80 80 00 00 00 FF 00 00 FF'
 '00 00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
 '00 00 FF FF FF 00 77 77 77 77 77 77 77 77 77 00'
 '00 00 77 77 77 77 77 77 70 00 00 00 00 00 77 77'
 '77 77 77 77 70 FF F0 00 00 00 70 00 00 00 00 00'
 '00 FF F0 00 00 00 70 FF FF FF FF FF F0 FF F0 00'
 '00 00 70 FF FF FF FF FF F0 00 00 00 00 00 70 FF'
 'FF FF 00 00 0F F0 77 00 00 00 70 FF FF FF FF 00'
 '0F F0 77 00 00 00 70 FF FF FF F0 00 0F F0 77 00'
 '00 00 70 FF FF FF 00 0F 0F F0 77 00 00 00 70 FF'
 'FF F0 00 FF 0F F0 77 00 00 00 70 FF FF 00 0F FF'
 'FF F0 77 00 00 00 70 FF FF F0 FF FF FF F0 77 00'
 '00 00 70 FF FF FF FF FF FF F0 77 00 00 00 70 FF'
 'FF FF FF FF FF F0 77 00 00 00 70 00 00 00 00 00'
 '00 00 77 00 00 00 77 77 77 77 77 77 77 77 77 00'
 '00 00'
}


//****************************************************************
// end of modifications, other than the two separate apxprev files
//   It should take half an hour to an hour to generate and modify a simple
//   SDI example using AppExpert so that you can see how it works.
//   I repeat that I recommend you do this before modifying it or 
//   using it in a more complicated application model.
//****************************************************************

