head	1.37;
access;
symbols
	V0-99-8:1.34
	V0-99-7:1.33
	V0-99-6:1.33
	V0-99-5:1.33
	V0-99-4:1.33
	V0-99-2:1.32
	V0-99-1:1.32
	V0-93-14:1.31
	V0-93-13:1.31
	V0-93-12:1.31
	V0-93-11:1.31
	V0-93-10:1.31
	V0-93-9:1.31
	V0-93-8:1.30
	V0-93-7:1.27
	V0-93-5:1.27
	V80:1.4
	V76d:1.3;
locks; strict;
comment	@ * @;


1.37
date	97.03.07.02.23.24;	author dumoulin;	state Exp;
branches;
next	1.36;

1.36
date	97.02.28.19.27.23;	author dumoulin;	state Exp;
branches;
next	1.35;

1.35
date	97.02.06.16.35.20;	author dumoulin;	state Exp;
branches;
next	1.34;

1.34
date	96.08.31.07.02.40;	author dumoulin;	state Exp;
branches;
next	1.33;

1.33
date	95.05.19.22.13.29;	author dumoulin;	state Exp;
branches;
next	1.32;

1.32
date	95.03.16.17.14.27;	author dumoulin;	state Exp;
branches;
next	1.31;

1.31
date	94.11.30.22.38.57;	author dumoulin;	state Exp;
branches;
next	1.30;

1.30
date	94.11.30.02.45.34;	author dumoulin;	state Exp;
branches;
next	1.29;

1.29
date	94.11.29.01.36.14;	author dumoulin;	state Exp;
branches;
next	1.28;

1.28
date	94.11.24.06.04.52;	author dumoulin;	state Exp;
branches;
next	1.27;

1.27
date	94.11.10.01.51.58;	author rushing;	state Exp;
branches;
next	;


desc
@winvn version 0.76 placed into RCS
@


1.37
log
@changed some %u's to %lu's
@
text
@/****************************************************************************
 *									   										*
 *  MODULE	: WVPRINT.C						   								*
 *									   										*
 *                  Jim Dumoulin  NASA/KSC                                  *
 *                                                                          *
 *                                                                          *
 *  PURPOSE	: Printing code for WinVN.                                 		*
 *																			*
 *  FUNCTIONS:	FreePrinterMemory () -		Frees all memory associated		*
 *											with a printer device context	*
 *																			*
 *				GetPrinterDC ()		-		Creates a printer DC for the	*
 *											default device.		   			*
 *									  										*
 *				DeletePrinterDC ()	-  		Deletes a printer DC for the 	*
 *											default device.		   			*
 *									   										*
 *				AbortProc ()		-  		Export proc. for GDI to check	*
 *											print abort.					*
 *																			*
 *				PrintDlgProc ()		-		Dialog function for the print	*
 *											cancel dialog.					*
 *																			*
 *				ReportPrintError ()	-		Decodes err codes for calls		*
 *											to Windows print functions		*
 *																			*
 *				PrintHeaderP ()		-		Determines if header string		*
 *											is one that gets printed		*
 *																			*
 *				PrintArticle ()		-  		Prints the contents of the		*
 *											an article window.				*
 ****************************************************************************/

/*
 * $Id: wvprint.c 1.36 1997/02/28 19:27:23 dumoulin Exp $
 */

#include <windows.h>
#include <windowsx.h>
#include "wvglob.h"
#include "winvn.h"
#pragma hdrstop

static BOOL near PdlgAbort = FALSE;			/* TRUE if the user has aborted the print job	*/
HWND hwndPDlg = NULL;						/* Handle to the cancel print dialog			*/

          
/****************************************************************************
 *																			*          
 *  FUNCTION   : AbortProc()												*
 *																			*
 *  PURPOSE    : To be called by GDI print code to check for user abort.    *
 *               Returns TRUE to continue Printing, FALSE to cancel.        *
 *																			*
 ****************************************************************************/
#ifndef _WIN32
BOOL CALLBACK __export
#else
BOOL CALLBACK
#endif
AbortProc (HDC hdc, int nCode)
{
 MSG msg;
 char mes[40]; 

  // I give up getting this to work for this release so we won't have
  // print canceling.  This has been intermittent ever since WinVN
  // grew too big.  Major problems with the fact the CALLBACK functions
  // can't access any global variables in the LARGE model.    (JD 11/29/94)
  
  return TRUE;
  
  if ((nCode < 0) && (nCode != SP_OUTOFDISK)) {
 	sprintf (mes, "AbortProc Error %d", (int) nCode);
 	MessageBox (NULL, "Your Windows Print Driver CallBack \n procedure "
 				"returned an error", mes, MB_OK | MB_ICONEXCLAMATION);
 	return FALSE;
  }
  else  
 
	/* Allow other apps to run, or get abort messages */
  while (!PdlgAbort && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)){
 	  if (!hwndPDlg || !IsDialogMessage (hwndPDlg, &msg)) {
 		TranslateMessage (&msg);
 		DispatchMessage (&msg);
 	  }
 	}

  if (PdlgAbort == TRUE)
 	return FALSE;
  else
 	return TRUE;
}

/****************************************************************************
 *																			*
 *  FUNCTION   : PrinterInit ()												*
 *																			*
 *  PURPOSE    : Initializes Global Variables used by the Printing Code.  	*
 *				 This function gets called once when WinVN starts up but	*
 *				 may be called again if a printer error occurs and a device	*
 *				 context is lost.											*
 *																			*
 *  RETURNS    : TRUE if successful, FALSE if not							*
 *																			*
 ****************************************************************************/
BOOL WINAPI 
PrinterInit (void)
{
  memset(&pd, 0, sizeof(pd));
  pd.lStructSize = (DWORD) sizeof (PRINTDLG);
  //(pd.hwndOwner omitted)
  //pd.hDevMode = NULL;
  //pd.hDevNames = NULL;
  //pd.hDC = (HDC) NULL;
  pd.Flags = PD_RETURNDC;
  //pd.nFromPage = 0;
  //pd.nToPage = 0;
  //pd.nMinPage = 0;
  //pd.nMaxPage = 0xFFFE;
  pd.nCopies = 1;
  //pd.hInstance = (HANDLE) NULL;
  //pd.lCustData = 0L;
  //pd.lpfnPrintHook = (UINT) NULL;
  //pd.lpfnSetupHook = (UINT) NULL;
  //pd.lpPrintTemplateName = (LPSTR) NULL;
  //pd.lpSetupTemplateName = (LPSTR) NULL;
  //pd.hPrintTemplate = (HANDLE) NULL;
  //pd.hSetupTemplate = (HANDLE) NULL;

  hFontPrint = NULL;
  hFontPrintB = NULL;
  hFontPrintI = NULL;
  hFontPrintS = NULL;

  return TRUE;
}

/****************************************************************************
 *																			*
 *  FUNCTION:	FreePrinterMemory ()										*
 *																			*
 *  PURPOSE	: 	Frees any memory structures allocated for the Printer		*
 *		 		Device context.	This is typically called once when WinVN	*
 *				exits but will also be called if a printer error occurs.	*
 *																			*
 *  RETURNS	: 	TRUE if successful else FALSE								*
 *																			*
 ****************************************************************************/
BOOL WINAPI 
FreePrinterMemory (void)
{
  BOOL success = TRUE;
  
  if (pd.hDevMode)
	success = (GlobalFree (pd.hDevMode) == NULL) ? TRUE : FALSE;
  if (pd.hDevNames)
	success = (GlobalFree (pd.hDevNames) == NULL) ? success : FALSE;
  if (pd.hDC)
	success = DeletePrinterDC (pd.hDC) ? success : FALSE;
  PrinterInit ();
  return success;
}

/****************************************************************************
 *																			*
 *  FUNCTION   : PrinterSetup ()											*
 *																			*
 *  PURPOSE    : Creates a printer display context for the default device.  *
 *																			*
 *  RETURNS    : Zero if successful, 1 = cancel, else Extended Error Code	*
 *																			*
 ****************************************************************************/
DWORD WINAPI 
PrinterSetup (HWND hwnd, DWORD flags)
{
  char mes[60];
  DWORD cError = 0;

  pd.hwndOwner = hwnd;
  pd.Flags = flags;

  if (pd.hDC != 0)
	DeletePrinterDC (pd.hDC);

  if (PrintDlg (&pd) == 0) {
	cError = CommDlgExtendedError ();
	if (cError != 0) {
	  sprintf (mes, "Comm Dialog Box Extended Error %d", (DWORD) cError);
	  MessageBox (hwnd, "WinVN was unable to either display a \n"
				  "Printer Device Context Dialog Box or \n"
				  "to get a Printer Device Context"
				  ,mes, MB_OK | MB_ICONEXCLAMATION);
	  FreePrinterMemory ();
	  return cError;
	}
	else
	  return 1;
  }
  else
	return 0;
}

/****************************************************************************
 *																			*
 *  FUNCTION:	GetPrinterDC ()												*
 *																			*
 *  PURPOSE:	Finds or creates a printer display context for the			*
 *				selected printer.											*
 *																			*
 *  RETURNS    : HDC - A handle to printer DC or Null if error				*
 *																			*
 ****************************************************************************/
HDC WINAPI 
GetPrinterDC (HWND hwnd)
{
  DWORD pError = 0;

  if (pd.hDC)
	return pd.hDC;
  else {
	if ((pd.hDevMode == NULL) && (pd.hDevNames == NULL))
	  pError = PrinterSetup (hwnd, PD_RETURNDC | PD_RETURNDEFAULT);
	else
	  pError = PrinterSetup (hwnd, PD_RETURNDC);

	if (pError > 0)
	  return NULL;
	else
	  return pd.hDC;
  }
}

/****************************************************************************
 *																			*
 *  FUNCTION   : DeletePrinterDC ()											*
 *																			*
 *  PURPOSE    : Releases a printer display context for the selected        *
 *               printer.                                                   *
 *																			*
 *  RETURNS    : TRUE if Successful, FALSE if Error                    	    *
 *																			*
 ****************************************************************************/

BOOL WINAPI 
DeletePrinterDC (HDC hDC)
{
  BOOL success = TRUE;

  if (pd.hDC != hDC)
	success = DeleteDC (pd.hDC);

  success = DeleteDC (hDC) ? success : FALSE;
  pd.hDC = NULL;
  return success;
}


/****************************************************************************
 *																			*
 *  FUNCTION   : PrintDlgProc ()											*
 *																			*
 *  PURPOSE    : Dialog function for the print cancel dialog box.			*
 *																			*
 *  RETURNS    : TRUE  - OK to abort/ not OK to abort						*
 *				 FALSE - otherwise.											*
 *																			*
 ****************************************************************************/
LRESULT CALLBACK 
PrintDlgProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  switch (msg) {
  case WM_INITDIALOG:
	hwndPDlg = hwnd;
	ShowWindow (hwnd, SW_SHOW);
	break;

  case WM_COMMAND:				/* abort printing if the cancel button gets hit */
	switch (LOWORD (wParam)) {
	case ID_OK:
	case ID_CANCEL:

	  PdlgAbort = TRUE;
	  EnableWindow (GetParent (hwnd), TRUE);
	  if (hwndPDlg){
		DestroyWindow (hwndPDlg);	/* Delete Cancel Dialog */
	  	hwndPDlg = NULL;
	  	}
	  return TRUE;
	}
	break;
  }
  return FALSE;
}

/****************************************************************************
 *																			*
 *  FUNCTION   : ReportPrintError ()										*
 *																			*
 *  PURPOSE    : Decodes error codes from calls to Windows Print functions  *
 *																			*
 *  RETURNS    : NULL  - No errors or Error has already been reported       *
 *		 		 short - Error code numbers (from Windows.H)				*
 *																			*
 ****************************************************************************/

void WINAPI 
ReportPrintError (int nError, HWND hWnd)
{
  char mes[60];
  char*msg;

  if (nError >= 0)
    return;

  if ((nError & SP_NOTREPORTED) == 0)
    return;

  switch (nError) {
  case SP_ERROR:
    strcpy(mes, "General Printing Error");
    msg = "The Windows Printer Device driver \n"
          "cannot begin printing your document. \n"
          "Your printer may be off line or out of \n"
          "paper.  It is also possible that the \n"
          "Windows Print Manager isn't loaded and \n"
          "another program is currently printing";
    break;

  case SP_APPABORT:
    strcpy(mes, "Print Canceled by Application");
    msg = "Your Print request has been canceled \n"
          "via an Abort request from your application";
    break;

  case SP_USERABORT:
    strcpy(mes, "Print Canceled by User");
    msg = "Your Print request has been canceled \n"
          "via a User cancel request from the \n"
          "Windows Print Manager";
    break;

  case SP_OUTOFDISK:
    strcpy(mes, "Out of Disk Space");
    msg = "Your Print request has been aborted \n"
          "due to insufficient disk space in your \n"
          "Windows TEMP subdirectory";
    break;

  case SP_OUTOFMEMORY:
    strcpy(mes, "Out of Memory Space");
    msg = "Your Print request has been aborted \n"
          "due to insufficient Windows memory.\n"
          "Close some applications and try again";
    break;

  default:
    sprintf (mes, "Unknown Print Error %d", (int) nError);
    msg = "Your Print request has been aborted due to \n"
          "the Windows Print function returning an error \n"
          "code that is undocumented";
    break;

  }
  MessageBox (hWnd, msg, mes, MB_OK | MB_ICONEXCLAMATION);
  return;
}


/****************************************************************************
 *																			*
 *  FUNCTION   : PrintHeaderP ()											*
 *																			*
 *  PURPOSE    : Determines if this is a header we are printing				*
 *																			*
 *        Entry:  str    substring to search                                *
 *                limit  limits the search to no more than num characters   *
 *                                                                          *
 *        Exit:   BOOL   TRUE if we are not excluding print this header     *
 *                       FALSE if we are explicited excluding header        *
 *																			*
 ****************************************************************************/

BOOL WINAPI 
PrintHeaderP (char *str, int limit)
{
  if (_strnicmp (str, "Relay-Version:", limit) == 0 
  	  || _strnicmp (str, "Path:", limit) == 0
	  || _strnicmp (str, "References:", limit) == 0
	  || _strnicmp (str, "NNTP-Posting-Host:", limit) == 0
	  || _strnicmp (str, "Mime-Version:", limit) == 0
	  || _strnicmp (str, "Content-Type:", limit) == 0
	  || _strnicmp (str, "X-Newsreader:", limit) == 0
	  || _strnicmp (str, "X-XXMessage-ID:", limit) == 0
	  || _strnicmp (str, "X-XXDate:", limit) == 0
	  || _strnicmp (str, "Xref:", limit) == 0)
	return (FALSE);
  else
	return (TRUE);
}


/****************************************************************************
 *																			*
 *  FUNCTION   : PrintFile ()												*
 *																			*
 *  PURPOSE    : Prints the contents of the edit control.					*
 *																			*
 ****************************************************************************/

void WINAPI 
PrintFile (HWND hwnd)
{
  MessageBox (hwnd, "Function Removed for Now", "Error", MB_OK);
  return;
}

/****************************************************************************
 *																			*
 *  FUNCTION   : PrintArticle ()											*
 *																			*
 *  PURPOSE    : Prints the current article.								*
 *																			*
 ****************************************************************************/

#define LEFTMARGIN 6			/* Left Margin in characters on printed page */
#define TOPMARGIN 4				/* Top Margin in characters on printed page */
#define BOTTOMMARGIN 6			/* Bottom Margin in characters on printed page */
#define MAXHEADERSIZE 20		/* Largest number of chars allowed in a header name */

void WINAPI 
PrintArticle (HWND hwnd, TypDoc * Doc)
{
  char sz[100];
  char szTitle[MAXHEADERLINE];
  char mybuf[MAXINTERNALLINE];
  DOCINFO di;
  BOOL found;
  BOOL inheader = TRUE;
  BOOL ROT13Mode = GetArticleRot13Mode (Doc->hWndFrame);
  int i, dy, dx, yExtPage, yExtSoFar, nPrintError, x;
  unsigned int LineLen, Offset, nCharsPerLine, nLinesPerPage;
  uint32 PageNum, nTotalPages, nTotalLines, iLine;
  char far *textptr;
  char *loc;
  DWORD cError = 0;
  TypBlock far *BlockPtr;
  TypLine far *LinePtr;
  HANDLE hBlock;
  TypLineID MyLineID;
  TEXTMETRIC tm;
  DEVNAMES *dv;
  ABORTPROC lpfnAbortProc = NULL;
  DLGPROC lpfnPrintDlgProc = NULL;
  TextSelect FAR *Start, *End;

  /* Create the job title */
  memset(&di, 0, sizeof(di));
  di.cbSize = sizeof (di);
  di.lpszDocName = "WinVn Article";
  di.lpszOutput = NULL;

  /* Initialize the printer */
  nPrintError = 0;
  hwndPDlg = NULL;
  PdlgAbort = FALSE;
  cError = PrinterSetup (hwnd, PD_RETURNDC | PD_USEDEVMODECOPIES);
  if ((cError != 0) || (pd.hDC == 0))
	goto exitout;

  /* Reinitialize Fonts just in case the user changed printers on us */
  InitPrintFonts ();

  /*  Create the Cancel dialog and Disable the main application window */
  lpfnPrintDlgProc = (DLGPROC) MakeProcInstance ((FARPROC) PrintDlgProc, (HINSTANCE) hInst);
  if (!lpfnPrintDlgProc)
	goto exitout;
  hwndPDlg = CreateDialog ((HINSTANCE) hInst, (LPCSTR) "PRINTDIALOG", hwnd, (DLGPROC) lpfnPrintDlgProc);
  if (!hwndPDlg)
	goto exitout;

  /* Allow the app. to inform GDI of the Abort function to call */
  lpfnAbortProc = (ABORTPROC) MakeProcInstance ((FARPROC) AbortProc, (HINSTANCE) hInst);
  if (!lpfnAbortProc)
	goto exitout;

  EnableWindow (hwnd, FALSE);
  if (SetAbortProc (pd.hDC, (ABORTPROC) lpfnAbortProc) < 0) {
	MessageBox (hwnd, "Unable to Set Abort Procedure",
				"Error", MB_OK | MB_ICONEXCLAMATION);
	nPrintError = 0;			/* don't print double error messages */
	goto exitout;
  }

  /* Get the Subject, printer description and Port number */
  found = GetHeaderLine (Doc, "Subject:", szTitle, sizeof (szTitle));
  if (!found) lstrcpy (szTitle, "Subject: No Subject");
  
  SetDlgItemText ((HWND) hwndPDlg, IDD_PRINTSUBJECT, (LPSTR) szTitle);
  dv = (DEVNAMES *) GlobalLock (pd.hDevNames);
  // sprintf (sz, "To %s on %s", (LPSTR) dv + dv->wDeviceOffset, (LPSTR) dv + dv->wOutputOffset);
  strcpy(mybuf,(LPSTR) dv + dv->wDeviceOffset);   //Heirich 19960829
  if (strncmp(mybuf,"\\\\",2))
      sprintf (sz, "To %s on %s",mybuf, (LPSTR) dv + dv->wOutputOffset);
  else
      sprintf (sz, "To %s (remote)",mybuf);   

  

  SetDlgItemText ((HWND) hwndPDlg, IDD_PRINTDEVICE, (LPSTR) sz);
  GlobalUnlock (pd.hDevNames);
  sprintf (sz, "Initializing Document for Printing");
  SetDlgItemText ((HWND) hwndPDlg, IDD_PRINTSTATUS, (LPSTR) sz);

  /*  Initialize the Printer Device Context */
  nPrintError = StartDoc (pd.hDC, &di);
  if (hwndPDlg) {
	UpdateWindow (hwndPDlg);	/* print to file may overwrite dialog */
	SetFocus (hwndPDlg);
  }
  if (nPrintError < 0)
	goto exitout;

  LockLine (Doc->hFirstBlock, sizeof (TypBlock), (TypLineID) 0L,
			&BlockPtr, &LinePtr);

  /* Get the lines in document and and a handle to the text buffer */
  iLine = 0;
  PageNum = 1;
  nTotalLines = Doc->TotalLines;
  
  // Prepare data structure if we are going to be printing selected text
  // Check to see if selected text was top-to-bottom or bottom-to-top
  if (((pd.Flags & PD_SELECTION) == 1) && (Doc->TextSelected)) {
    if ((Doc->EndSelect.LineNum > Doc->BeginSelect.LineNum) ||
  	    ((Doc->EndSelect.LineNum == Doc->BeginSelect.LineNum) &&
	     (Doc->EndSelect.CharNum >= Doc->BeginSelect.CharNum))) {
	  Start = &Doc->BeginSelect;
	  End = &Doc->EndSelect;
	}
	else {
	  Start = &Doc->EndSelect;
	  End = &Doc->BeginSelect;
	}
  }

  /* Get the height of one line and the height of a page */
  SelectObject (pd.hDC, hFontPrint);	/* Select Printer Font */
  GetTextMetrics (pd.hDC, &tm);
  dy = tm.tmHeight + tm.tmExternalLeading;
  dx = tm.tmAveCharWidth;
  nCharsPerLine = GetDeviceCaps (pd.hDC, HORZRES) / dx;
  nLinesPerPage = GetDeviceCaps (pd.hDC, VERTRES) / dy;
  nTotalPages = (nTotalLines + BOTTOMMARGIN + TOPMARGIN) / nLinesPerPage;
  if (nTotalPages < 1)
	nTotalPages = 1;
  yExtPage = GetDeviceCaps (pd.hDC, VERTRES);
  nPrintError = StartPage (pd.hDC);
  if (nPrintError <= 0)
	goto abortout;

  /* If we are printing the First Page, place the Subject line at the Top */
  if ((((pd.Flags & PD_PAGENUMS) == 0) && ((pd.Flags & PD_SELECTION) == 0)) ||
	  (pd.nFromPage == 0) ||
	  (pd.nFromPage == 1)) {
	sprintf (sz, "Now Printing Page %lu of %lu", PageNum, nTotalPages);
	SetDlgItemText (hwndPDlg, IDD_PRINTSTATUS, (LPSTR) sz);
	SelectObject (pd.hDC, hFontPrintS);		/* Select Printer Font */
	if ((pd.Flags & PD_SELECTION) == 0){
	  TextOut (pd.hDC, LEFTMARGIN * dx, TOPMARGIN * dy, szTitle, lstrlen (szTitle));
	  }
	else 
	 {
	  sprintf (sz, "Selected Text from ");
	  strncat (sz, szTitle, MAXINTERNALLINE - strlen (sz) - 1);
	  TextOut (pd.hDC, LEFTMARGIN * dx, TOPMARGIN * dy, sz, lstrlen (sz));
	  }
	yExtSoFar = (int) dy *(TOPMARGIN + 4);
  }

  /* Print out text until no more lines or user aborts */
  while ((iLine < nTotalLines) && !PdlgAbort) {
	if ((yExtSoFar + (BOTTOMMARGIN + 1) * dy) >= yExtPage) {
	  /* Reached the end of a page, print Page number */
	  if ((((pd.Flags & PD_PAGENUMS) == 0) &&
		   ((pd.Flags & PD_SELECTION) == 0)) ||	      
	      (((pd.Flags & PD_SELECTION) == 0) && 
	       ((pd.nFromPage == 0) || (PageNum >= pd.nFromPage)) &&
		   ((pd.nToPage == 0) || (PageNum <= pd.nToPage)))  ||
		  (((pd.Flags & PD_SELECTION) == 1) && 
		   (Doc->TextSelected) &&
		   ((long) iLine >= Start->LineNum) &&
		   ((long) iLine <= End->LineNum))) {
		SelectObject (pd.hDC, hFontPrintB);
		sprintf (sz, "Page %lu   ", PageNum);
		if (PageNum > 1) {
		  strncat (sz, szTitle, MAXINTERNALLINE - strlen (sz) - 1);
		  x = dx * LEFTMARGIN;	/* left justified for pages > 1 */
		}
		else {
		  x = (nCharsPerLine / 2) * dx;	/* centered for page 1 */
		}
		TextOut (pd.hDC, x, yExtSoFar + (2 * dy), sz, lstrlen (sz));

		/* Tell device driver to eject page */
		if (PageNum > nTotalPages)
		  nTotalPages = PageNum;
		sprintf (sz, "Now Printing Page %lu of %lu", PageNum, nTotalPages);
		SetDlgItemText (hwndPDlg, IDD_PRINTSTATUS, (LPSTR) sz);
		nPrintError = EndPage (pd.hDC);
		if ((nPrintError < 0) || PdlgAbort)
		  break;
		nPrintError = StartPage (pd.hDC);
		if ((nPrintError < 0) || PdlgAbort)
		  break;
	  }

	  yExtSoFar = dy * TOPMARGIN;
	  PageNum++;
	}

	/* Print the line and unlock the text handle */
	if (LinePtr->length != END_OF_BLOCK) {
	  textptr = GetTextPtr(LinePtr);
	  LineLen = lstrlen (textptr);
	  if (IsBlankStr (textptr))
		inheader = FALSE;

	  if ((((pd.Flags & PD_PAGENUMS) == 0) &&
		   ((pd.Flags & PD_SELECTION) == 0)) ||		  
		  (((pd.Flags & PD_SELECTION) == 0) && 
		   ((pd.nFromPage == 0) || (PageNum >= pd.nFromPage)) &&
		   ((pd.nToPage == 0) || (PageNum <= pd.nToPage))) ||
		  ((pd.Flags & PD_SELECTION) == 1) && 
		  Doc->TextSelected &&
		  (iLine >= (UINT) Start->LineNum) &&
		  (iLine <= (UINT) End->LineNum)) {
		if (inheader) {
		  loc = memchr (textptr, ':', MAXHEADERSIZE);
		  if (loc) {
			i = loc - textptr + 1;
			if (PrintHeaderP (textptr, i)) {
			  SelectObject (pd.hDC, hFontPrintB);
			  TextOut (pd.hDC, (LEFTMARGIN * dx), yExtSoFar, textptr, i);
			  SelectObject (pd.hDC, hFontPrint);
			  TextOut (pd.hDC, (LEFTMARGIN + MAXHEADERSIZE + 2) * dx,
					   yExtSoFar, textptr + i, LineLen - i);
			}
		  }
		  else {
			SelectObject (pd.hDC, hFontPrint);
			TextOut (pd.hDC, (LEFTMARGIN + MAXHEADERSIZE + 2) * dx,
					 yExtSoFar, textptr, LineLen);
		  }
		}
		else {		
		  if (ROT13Mode) {
			strcpy (mybuf, textptr);
			textptr = mybuf;
			strROT13 (textptr);
		  }
		  if (isLineQuotation (textptr))
			SelectObject (pd.hDC, hFontPrintI);
		  else
			SelectObject (pd.hDC, hFontPrint);

		  TextOut (pd.hDC, (LEFTMARGIN * dx), yExtSoFar, textptr, LineLen);
		}
		yExtSoFar += dy;	
	  }

	NextLine (&BlockPtr, &LinePtr);
  }

	/* Move down the page */
	iLine++;
  }   /* End While */

abortout:

  UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
  if (!PdlgAbort && (nPrintError >= 0)) {
	/* Eject the last page. */
	if ((((pd.Flags & PD_PAGENUMS) == 0) &&
		 ((pd.Flags & PD_SELECTION) == 0)) || 
		(((pd.nFromPage == 0) || (PageNum >= pd.nFromPage)) &&
		 ((pd.nToPage == 0) || (PageNum <= pd.nToPage))) ||
		(((pd.Flags & PD_SELECTION) == 1) && 
		 (Doc->TextSelected) &&
		 (iLine >= (UINT) Start->LineNum) &&
		 (iLine <= (UINT) End->LineNum))) {
	  SelectObject (pd.hDC, hFontPrintB);
	  sprintf (sz, "Page %lu   ", PageNum);
	  if (PageNum > 1) {
		strncat (sz, szTitle, MAXINTERNALLINE - strlen (sz) - 1);
		x = dx * LEFTMARGIN;	/* left justified for pages > 1 */
	  }
	  else {
		x = (nCharsPerLine / 2) * dx; /* centered for page 1 */
	  }
	  TextOut (pd.hDC, x, yExtPage - (BOTTOMMARGIN * dy), sz, lstrlen (sz));
	  nPrintError = EndPage (pd.hDC);
	}

	/* Complete the document. */
	if (!PdlgAbort && (nPrintError >= 0))
	  nPrintError = EndDoc (pd.hDC);
  }

exitout:

  if (PdlgAbort) {
	if (pd.hDC){
	  AbortDoc (pd.hDC);
	  DeletePrinterDC(pd.hDC);
	  }
	MessageBox (hwnd, "Print Request Canceled",
				"Canceled", MB_OK | MB_ICONEXCLAMATION);
  }
  else if (nPrintError < 0){
	  ReportPrintError (nPrintError, hwnd);
	  }
	  
  EnableWindow (hwnd, TRUE);	/* ReEnable main procedure */
  if (hwndPDlg)
	{
	  DestroyWindow ((HWND) hwndPDlg);	/* Delete Cancel Dialog */
	  PdlgAbort = FALSE;
	  hwndPDlg = NULL;
	}

  if (lpfnPrintDlgProc) FreeProcInstance ((FARPROC) lpfnPrintDlgProc);
  if (lpfnAbortProc) FreeProcInstance ((FARPROC) lpfnAbortProc);

  return;
}

/* 
 * Local Variables:
 * tab-width: 4
 * end:
 */
@


1.36
log
@changed a number of longs to uint32's
@
text
@d36 1
a36 1
 * $Id: wvprint.c 1.35 1997/02/06 16:35:20 dumoulin Exp $
d567 1
a567 1
	sprintf (sz, "Now Printing Page %u of %u", PageNum, nTotalPages);
d596 1
a596 1
		sprintf (sz, "Page %u   ", PageNum);
d609 1
a609 1
		sprintf (sz, "Now Printing Page %u of %u", PageNum, nTotalPages);
d694 1
a694 1
	  sprintf (sz, "Page %u   ", PageNum);
@


1.35
log
@fix uninitialized variable and convert to longs
@
text
@d36 1
a36 1
 * $Id: wvprint.c 1.34 1996/08/31 07:02:40 dumoulin Exp $
d444 1
a444 1
  unsigned long PageNum, nTotalPages, nTotalLines, iLine;
@


1.34
log
@provided more detail to printing message
@
text
@d36 1
a36 1
 * $Id: wvprint.c 1.33 1995/05/19 22:13:29 dumoulin Exp $
d111 1
d113 4
a116 2
  pd.hDevMode = NULL;
  pd.hDevNames = NULL;
d118 4
a121 5
  pd.hDC = (HDC) NULL;
  pd.nFromPage = 0;
  pd.nToPage = 0;
  pd.nMinPage = 0;
  pd.nMaxPage = 0xFFFE;
d123 8
a130 8
  pd.hInstance = (HANDLE) NULL;
  pd.lCustData = 0L;
  pd.lpfnPrintHook = (UINT) NULL;
  pd.lpfnSetupHook = (UINT) NULL;
  pd.lpPrintTemplateName = (LPSTR) NULL;
  pd.lpSetupTemplateName = (LPSTR) NULL;
  pd.hPrintTemplate = (HANDLE) NULL;
  pd.hSetupTemplate = (HANDLE) NULL;
d312 1
d315 1
a315 1
	return;
d318 1
a318 1
	return;
d322 8
a329 9
	MessageBox (hWnd, "The Windows Printer Device driver \n"
				"cannot begin printing your document. \n"
				"Your printer may be off line or out of \n"
				"paper.  It is also possible that the \n"
				"Windows Print Manager isn't loaded and \n"
				"another program is currently printing",
				"General Printing Error",
				MB_OK | MB_ICONEXCLAMATION);
	break;
d332 4
a335 5
	MessageBox (hWnd, "Your Print request has been canceled \n"
				"via an Abort request from your application",
				"Print Canceled by Application",
				MB_OK | MB_ICONEXCLAMATION);
	break;
d338 5
a342 6
	MessageBox (hWnd, "Your Print request has been canceled \n"
				"via a User cancel request from the \n"
				"Windows Print Manager",
				"Print Canceled by User",
				MB_OK | MB_ICONEXCLAMATION);
	break;
d345 5
a349 6
	MessageBox (hWnd, "Your Print request has been aborted \n"
				"due to insufficient disk space in your \n"
				"Windows TEMP subdirectory",
				"Out of Disk Space",
				MB_OK | MB_ICONEXCLAMATION);
	break;
d352 5
a356 6
	MessageBox (hWnd, "Your Print request has been aborted \n"
				"due to insufficient Windows memory.\n"
				"Close some applications and try again",
				"Out of Memory Space",
				MB_OK | MB_ICONEXCLAMATION);
	break;
d359 5
a363 7

	sprintf (mes, "Unknown Print Error %d", (int) nError);
	MessageBox (hWnd, "Your Print request has been aborted due to \n"
				"the Windows Print function returning an error \n"
				"code that is Undocumented", mes,
				MB_OK | MB_ICONEXCLAMATION);
	break;
d366 1
d443 2
a444 2
  unsigned int LineLen, Offset, nTotalPages, PageNum, iLine, nCharsPerLine,
    nLinesPerPage, nTotalLines;
d459 1
d593 2
a594 2
		   (iLine >= (UINT) Start->LineNum) &&
		   (iLine <= (UINT) End->LineNum))) {
@


1.33
log
@got rid of raw pointer manulipations and replace with GetTextPtr
macro.
@
text
@d36 1
a36 1
 * $Id: wvprint.c 1.32 1995/03/16 17:14:27 dumoulin Exp $
d504 9
a512 1
  sprintf (sz, "To %s on %s", (LPSTR) dv + dv->wDeviceOffset, (LPSTR) dv + dv->wOutputOffset);
@


1.32
log
@allow printing of ROT13 Messages
@
text
@d36 1
a36 1
 * $Id: wvprint.c 1.31 1994/11/30 22:38:57 dumoulin Exp $
d619 1
a619 1
	  textptr = (char far *) LinePtr + sizeof (TypLine) + sizeof (TypText);
@


1.31
log
@another attempt at fixing AbortProc callback bug
@
text
@d36 1
a36 1
 * $Id: wvprint.c 1.30 1994/11/30 02:45:34 dumoulin Exp $
d440 1
d444 1
d651 6
a656 1
		else {
@


1.30
log
@Always force AbortProc to return true - Disabling Print Cancel
feature for now.  This will clear up all printing problems.
@
text
@d36 1
a36 1
 * $Id: wvprint.c 1.29 1994/11/29 01:36:14 dumoulin Exp $
d57 5
a61 1
BOOL CALLBACK 
@


1.29
log
@Fix printing selected text and GPF's for various printer drivers.
@
text
@d36 1
a36 1
 * $Id: wvprint.c 1.27 1994/11/10 01:51:58 rushing Exp $
d45 2
a46 2
BOOL PdlgAbort = FALSE;			/* TRUE if the user has aborted the print job	*/
HWND hwndPDlg = NULL;			/* Handle to the cancel print dialog			*/
d48 1
d60 9
a68 2
  MSG msg;
  char mes[40];
a69 2
  if (!hwndPDlg) return TRUE;   /* If the abort dialog isn't up yet */

d71 4
a74 4
	sprintf (mes, "AbortProc Error %d", (int) nCode);
	MessageBox (NULL, "Your Windows Print Driver CallBack \n procedure "
				"returned an error", mes, MB_OK | MB_ICONEXCLAMATION);
	return FALSE;
d76 2
a77 1
  else
d79 6
a84 6
	while (!PdlgAbort && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
	  if (hwndPDlg && !IsDialogMessage (hwndPDlg, &msg)) {
		TranslateMessage (&msg);
		DispatchMessage (&msg);
	  }
	}
d87 1
a87 1
	return FALSE;
d89 1
a89 1
	return TRUE;
a91 1

d96 4
a99 1
 *  PURPOSE    : Initializes Global Variables used by the Printing Code		*
d139 2
a140 1
 *		 		Device context.												*
d280 1
a280 1
	  if (hwndPDlg)
d282 2
a283 1
	  hwndPDlg = NULL;
d404 5
a408 5
 *									    *
 *  FUNCTION   : PrintFile ()						    *
 *									    *
 *  PURPOSE    : Prints the contents of the edit control.		    *
 *									    *
d661 1
a661 1
  }
d697 1
a697 1
	if (pd.hDC)
d699 2
d704 1
a704 2
  else {
	if (nPrintError < 0)
d706 4
a709 2
	EnableWindow (hwnd, TRUE);	/* ReEnable main procedure */
	if (hwndPDlg)
a714 1
  }
d716 2
a717 4
  if (lpfnPrintDlgProc)
	FreeProcInstance ((FARPROC) lpfnPrintDlgProc);
  if (lpfnAbortProc)
	FreeProcInstance ((FARPROC) lpfnAbortProc);
@


1.28
log
@Attempt to fix broken printing for some device drivers
@
text
@d1 33
a33 34
/***************************************************************************
 *									   *
 *  MODULE	: WVPRINT.C						   *
 *									   *
 *                  Jim Dumoulin  NASA/KSC                                 *
 *                                                                         *
 *                                                                         *
 *  PURPOSE	: Printing code for WinVN.                                 *
 *									   *
 *  FUNCTIONS	: FreePrinterMemory ()	   -  Frees all memory associated  *
 *                                            with a printer device context*
 *                                                                         *
 *  		: GetPrinterDC ()	   -  Creates a printer DC for the *
 *					      default device.		   *
 *									   *
 *  		: DeletePrinterDC ()	   -  Deletes a printer DC for the *
 *					      default device.		   *
 *									   *
 *		  AbortProc ()		   -  Export proc. for GDI to check*
 *									   *
 *					      print abort.		   *
 *									   *
 *		  PrintDlgProc ()	   -  Dialog function for the print*
 *					      cancel dialog.		   *
 *                                                                         *
 *                ReportPrintError ()     -  Decodes err codes for calls   *
 *                                            to Windows print functions   *
 *									   *
 *                PrintHeaderP ()          -  Determines if header string  *
 *                                            is one that gets printed     *
 *                                                                         *
 *		  PrintArticle ()          -  Prints the contents of the   *
 *					      an article window.	   *
 ***************************************************************************/
a43 1
#pragma optimize("",off) 
d45 2
a46 2
BOOL PdlgAbort = FALSE;			/* TRUE if the user has aborted the print job    */
HWND hwndPDlg = NULL;			/* Handle to the cancel print dialog         */
d49 3
a51 3
 *									    *          
 *  FUNCTION   : AbortProc()						    *
 *									    *
d54 1
a54 1
 *									    *
d60 3
a62 1
  char mes[180];
d72 1
a72 3
	//  while (!PdlgAbort && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
	while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
//	  if (!hwndPDlg || !IsDialogMessage (hwndPDlg, &msg)) {
d87 7
a93 7
 *									    *
 *  FUNCTION   : PrinterInit ()				   	            *
 *									    *
 *  PURPOSE    : Initializes Global Variables used by the Printing Code     *
 *									    *
 *  RETURNS    : TRUE if successful, FALSE if not                     	    *
 *									    *
d126 8
a133 9
 *									    *
 *  FUNCTION   : FreePrinterMemory ()					    *
 *									    *
 *  PURPOSE    : Frees any memory structures allocated for the Printer      *
 *		 Device context.                                            *
 *		 It also sets iPrinter to the supported level of printing.  *
 *									    *
 *  RETURNS    : TRUE if successful else FALSE                  	    *
 *									    *
d138 2
d141 1
a141 1
	GlobalFree (pd.hDevMode);
d143 1
a143 1
	GlobalFree (pd.hDevNames);
d145 1
a145 1
	DeletePrinterDC (pd.hDC);
d147 1
a147 1
  return TRUE;
d151 3
a153 3
 *									    *
 *  FUNCTION   : PrinterSetup ()					    *
 *									    *
d155 3
a157 5
 *		 As a side effect, it sets the szDevice and szPort variables*
 *		 It also sets iPrinter to the supported level of printing.  *
 *									    *
 *  RETURNS    : Zero if successful, 1 = cancel, else Extended Error Code   *
 *									    *
d190 8
a197 8
 *									    *
 *  FUNCTION   : GetPrinterDC ()					    *
 *									    *
 *  PURPOSE    : Finds or creates a printer display context for the         *
 *               selected printer.                                          *
 *									    *
 *  RETURNS    : HDC - A handle to printer DC or Null if error        	    *
 *									    *
d220 3
a222 3
 *									    *
 *  FUNCTION   : DeletePrinterDC ()					    *
 *									    *
d225 3
a227 3
 *									    *
 *  RETURNS    : 0 if Successful, 1 if Error                    	    *
 *									    *
d233 1
a233 2
  BOOL err1 = FALSE;
  BOOL err2 = FALSE;
d236 1
a236 1
	err1 = DeleteDC (pd.hDC);
d238 1
a238 1
  err2 = DeleteDC (hDC);
d240 1
a240 1
  return err1 & err2;
d245 8
a252 8
 *									    *
 *  FUNCTION   : PrintDlgProc ()					    *
 *									    *
 *  PURPOSE    : Dialog function for the print cancel dialog box.	    *
 *									    *
 *  RETURNS    : TRUE  - OK to abort/ not OK to abort			    *
 *		 FALSE - otherwise.					    *
 *									    *
d281 3
a283 3
 *									    *
 *  FUNCTION   : ReportPrintError ()					    *
 *									    *
d285 1
a285 1
 *									    *
d287 2
a288 2
 *		 short - Error code numbers (from Windows.H)                *
 *									    *
d360 5
a364 5
 *									    *
 *  FUNCTION   : PrintHeaderP ()					    *
 *									    *
 *  PURPOSE    : Determines if this is a header we are printing		    *
 *									    *
d370 1
a370 1
 *									    *
d408 5
a412 5
 *									    *
 *  FUNCTION   : PrintArticle ()					    *
 *									    *
 *  PURPOSE    : Prints the current article.             		    *
 *									    *
d442 1
d483 2
a484 2
  if (!found)
	lstrcpy (szTitle, "Subject: No Subject");
d509 15
d547 9
a555 1
	TextOut (pd.hDC, LEFTMARGIN * dx, TOPMARGIN * dy, szTitle, lstrlen (szTitle));
d564 8
a571 3
		   ((pd.Flags & PD_SELECTION) == 0)) ||
		  (((pd.nFromPage == 0) || (PageNum >= pd.nFromPage)) &&
		   ((pd.nToPage == 0) || (PageNum <= pd.nToPage)))) {
d579 1
a579 1
		  x = (nCharsPerLine / 2) * dx;		/* centered for page 1 */
d608 8
a615 3
		   ((pd.Flags & PD_SELECTION) == 0)) ||
		  (((pd.nFromPage == 0) || (PageNum >= pd.nFromPage)) &&
		   ((pd.nToPage == 0) || (PageNum <= pd.nToPage)))) {
d642 1
d644 3
a646 3
	  yExtSoFar += dy;
	  NextLine (&BlockPtr, &LinePtr);
	}
d658 1
a658 1
		 ((pd.Flags & PD_SELECTION) == 0)) ||
d660 5
a664 1
		 ((pd.nToPage == 0) || (PageNum <= pd.nToPage)))) {
d672 1
a672 1
		x = (nCharsPerLine / 2) * dx;	/* centered for page 1 */
d710 6
a715 1
#pragma optimize("",on)
@


1.27
log
@restart
@
text
@d45 1
d62 1
a62 1
  char mes[60];
d74 2
a75 1
	  if (!hwndPDlg || !IsDialogMessage (hwndPDlg, &msg)) {
d380 2
a381 2
  if (_strnicmp (str, "Relay-Version:", limit) == 0
	  || _strnicmp (str, "Path:", limit) == 0
d383 6
d407 1
a407 123
  HDC hdc;
  int yExtPage;
  char sz[32];
  WORD cch;
  WORD ich;
  char *pch;
  WORD iLine;
  WORD nLinesEc;
  char *pT;
  ABORTPROC lpfnAbort;
  DLGPROC lpfnPDlg;
//    WORD    dy;
  int dy;
  int yExtSoFar;
  WORD fError = TRUE;
  HWND hwndEdit;
  SIZE size;

  hwndEdit = (HWND) GetWindowWord (hwnd, GWW_HWNDEDIT);
  lstrcpy (sz, "WinVN Print Request");
  cch = lstrlen (sz);
  PdlgAbort = FALSE;

  /* Make instances of the Abort proc. and the Print dialog function */
  lpfnAbort = (ABORTPROC) MakeProcInstance ((FARPROC) AbortProc, hInst);
  if (!lpfnAbort)
	goto getout;
  lpfnPDlg = (DLGPROC) MakeProcInstance ((FARPROC) PrintDlgProc, hInst);
  if (!lpfnPDlg)
	goto getout4;

  /* Initialize the printer */
  hdc = GetPrinterDC (hwnd);
  if (!hdc)
	goto getout5;

  /* Disable the main application window and create the Cancel dialog */
  /*    EnableWindow (hwndFrame, FALSE); */
  hwndPDlg = CreateDialog (hInst, "PRINTDIALOG", hwnd, lpfnPDlg);
  if (!hwndPDlg)
	goto getout3;
  ShowWindow (hwndPDlg, SW_SHOW);
  UpdateWindow (hwndPDlg);

  /* Allow the app. to inform GDI of the escape function to call */
  if (Escape (hdc, SETABORTPROC, 0, (LPSTR) lpfnAbort, NULL) < 0)
	goto getout1;

  /* Initialize the document */
  if (Escape (hdc, STARTDOC, cch, (LPSTR) sz, NULL) < 0)
	goto getout1;

  /* Get the height of one line and the height of a page */
  GetTextExtentPoint (hdc, "CC", 2, &size);
  dy = size.cy;
  yExtPage = GetDeviceCaps (hdc, VERTRES);

  /* Get the lines in document and and a handle to the text buffer */
  iLine = 0;
  yExtSoFar = 0;
  nLinesEc = (WORD) SendMessage (hwndEdit, EM_GETLINECOUNT, 0, 0L);
//    hT      = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L);
  pT = GetEditText (hwndEdit);

  /* While more lines print out the text */
  while ((iLine < nLinesEc) && !PdlgAbort) {
	if (yExtSoFar + (int) dy > yExtPage) {
	  /* Reached the end of a page. Tell device driver to eject page */
	  if (Escape (hdc, NEWFRAME, 0, NULL, NULL) < 0 || PdlgAbort)
		goto getout2;
	  yExtSoFar = 0;
	}

	/* Get the length and position of the line in the buffer
	 * and lock from that offset into the buffer */
	ich = (WORD) SendMessage (hwndEdit, EM_LINEINDEX, iLine, 0L);
	cch = (WORD) SendMessage (hwndEdit, EM_LINELENGTH, ich, 0L);
//  pch = (char *)LocalLock(hT) + ich;
	pch = pT + ich;

	/* Print the line and unlock the text handle */
	TextOut (hdc, 0, yExtSoFar, (LPSTR) pch, cch);
//  LocalUnlock (hT);

	/* Move down the page */
	yExtSoFar += dy;
	iLine++;
  }
  GlobalFreePtr (pT);

  /* Eject the last page. */
  if (Escape (hdc, NEWFRAME, 0, NULL, NULL) < 0)
	goto getout2;

  /* Complete the document. */
  if (Escape (hdc, ENDDOC, 0, NULL, NULL) < 0) {
  getout2:
	/* Ran into a problem before NEWFRAME? Abort the document */
	Escape (hdc, ABORTDOC, 0, NULL, NULL);
  }
  else
	fError = FALSE;

getout3:
  /* Close the cancel dialog and re-enable main app. window */
  /*    EnableWindow (hwndFrame, TRUE);   */
  DestroyWindow (hwndPDlg);

getout1:
  DeleteDC (hdc);

getout5:
  /* Get rid of dialog procedure instances */
  FreeProcInstance ((FARPROC) lpfnPDlg);

getout4:
  FreeProcInstance ((FARPROC) lpfnAbort);

getout:

  /* Error? make sure the user knows... */
  if (fError)
	MessageBox (hwnd, "Printing Error", "Error", MB_OK);
d661 1
d663 3
d675 1
@
