Example #1
0
BOOL CWinPrint::PrintDlg(HWND hOwner, LONG lCopies, LONG lFrom, LONG lTo, LONG lMin, LONG lMax)
{

// Use new version instead
//#if defined ( RULIB_USE_PRINTDLG )

//	return PrintDlgEx( hOwner, lCopies, lFrom, lTo, lMin, lMax );

//#endif

	Destroy();

	// Fill in print information
	m_pd.lStructSize = sizeof( m_pd ); 
	m_pd.Flags = PD_RETURNDC; 
	m_pd.hwndOwner = hOwner; 
	m_pd.nFromPage = (WORD)lFrom; 
	m_pd.nToPage = (WORD)lTo; 
	m_pd.nMinPage = (WORD)lMin; 
	m_pd.nMaxPage = (WORD)lMax; 
	m_pd.nCopies = (WORD)lCopies; 

	// Attempt to get printer
	if ( !::PrintDlg( &m_pd ) ) return FALSE;

	// Reset the abort flag
	m_bAbort = FALSE;

	// Set abort procedure
	SetAbortProc( m_pd.hDC, &CWinPrint::AbortProc );

	return TRUE;
}
Example #2
0
BOOL CWinPrint::PrintDlgEx(HWND hOwner, LONG lCopies, LONG lFrom, LONG lTo, LONG lMin, LONG lMax)
{
	Destroy();

	PRINTPAGERANGE ppr = { lFrom, lTo };

	// Fill in print information
	m_pdx.lStructSize = sizeof( m_pdx ); 
	m_pdx.hwndOwner = hOwner; 
	m_pdx.Flags = PD_ALLPAGES | PD_RETURNDC; 
	m_pdx.nMinPage = lMin; 
	m_pdx.nMaxPage = lMax; 
	m_pdx.nCopies = lCopies; 
	m_pdx.nStartPage = START_PAGE_GENERAL;

	// From to?
	if ( ( lFrom || lTo ) && lFrom != lTo )
	{	m_pdx.nMaxPageRanges = 1;
		m_pdx.lpPageRanges = &ppr;
	} // end if

	// Attempt to get printer
	if ( PD_RESULT_PRINT != ::PrintDlgEx( &m_pdx ) ) 
		return FALSE;

	// Reset the abort flag
	m_bAbort = FALSE;

	// Set abort procedure
	SetAbortProc( m_pdx.hDC, &CWinPrint::AbortProc );

	return TRUE;
}
Example #3
0
/**********************************************************************
 *           SetAbortProc   (GDI.381)
 */
INT16 WINAPI SetAbortProc16(HDC16 hdc, ABORTPROC16 abrtprc)
{
    DC *dc = DC_GetDCPtr( hdc );

    if (!dc) return FALSE;
    dc->pAbortProc16 = abrtprc;
    GDI_ReleaseObj( hdc );
    return SetAbortProc( hdc, call_abort_proc16 );
}
Example #4
0
//////////////////
// Do abort dialog
// 
int WPPrinter::doAbortDlg(WPWin *w)
{
	pwin = w;
	Abort = FALSE;
	assert(DlgAbort==NULL);
	DlgAbort = new WPDlgPrintAbort(pwin);
	if (pwin)
		pwin->enableWin(FALSE);
	return SetAbortProc(hdc, WPPrintAbortProc);
}
Example #5
0
void SimplePrint(int nPages)
{
	TCHAR temp[MAX_PATH];

	DWORD size = MAX_PATH;
	GetDefaultPrinter(temp, & size); // default printer name

	HDC hDC = CreateDC(NULL, temp, NULL, NULL); // DC with default setting
	
	if ( hDC )
	{
		nCall_AbortProc = 0;
		SetAbortProc(hDC, SimpleAbortProc);

		DOCINFO docinfo;
		docinfo.cbSize       = sizeof(docinfo);
		docinfo.lpszDocName  = _T("SimplePrint");
		docinfo.lpszOutput   = NULL; 
		docinfo.lpszDatatype = _T("EMF");
		docinfo.fwType		 = 0; 

		if ( StartDoc(hDC, & docinfo) > 0 )
		{
			for (int p=0; p<nPages; p++) // one page at a time
				if ( StartPage(hDC) <= 0 )
					break;
				else
				{
					int width  = GetDeviceCaps(hDC, HORZRES);
					int height = GetDeviceCaps(hDC, VERTRES);
					int dpix   = GetDeviceCaps(hDC, LOGPIXELSX);
					int dpiy   = GetDeviceCaps(hDC, LOGPIXELSY);
			
					wsprintf(temp, _T("Page %d of %d"), p+1, nPages);
					SetTextAlign(hDC, TA_TOP | TA_RIGHT );
					TextOut(hDC, width, 0, temp, _tcslen(temp));

					Rectangle(hDC, 0, 0, dpix, dpiy);
					Rectangle(hDC, width, height, width-dpix, height-dpiy);
				
					if ( EndPage(hDC)<0 )
						break;
				}
			
			EndDoc(hDC);
		}

		DeleteDC(hDC);
	}

	wsprintf(temp, "AbortProc called %d times", nCall_AbortProc);
	MessageBox(NULL, temp, "SimlePrint", MB_OK);	
}
Example #6
0
GPrintDC::GPrintDC(void *Handle, const char *PrintJobName, const char *PrinterName)
{
	d = new GPrintDCPrivate;
	hDC = (HDC) Handle;

	SetAbortProc(hDC, LgiAbortProc);
	
	// Start document
	if (hDC)
	{
		DOCINFO Info;

		ZeroObj(Info);
		Info.cbSize = sizeof(DOCINFO); 
		Info.lpszDocName = PrintJobName ? PrintJobName : "Lgi Print Job";
		
		if (PrinterName &&
			stristr(PrinterName, "XPS"))
		{
			GFile::Path p(LSP_USER_DOCUMENTS);
			GString FileName;
			FileName.Printf("%s.xps", PrintJobName);
			p += FileName;
			if (FileExists(p.GetFull()))
			{
				for (unsigned i=1; i<1000; i++)
				{
					p.Parent();
					FileName.Printf("%s%i.xps", PrintJobName, i);
					p += FileName;
					if (!FileExists(p.GetFull()))
						break;
				}
			}
			
			Info.lpszOutput = d->OutputFileName = p.GetFull();
		}

		d->DocOpen = StartDoc(hDC, &Info) > 0;
		if (!d->DocOpen)
		{
			DeleteDC(hDC);
			hDC = 0;
		}
	}
}
Example #7
0
wBool_t wPrintDocStart( const char * title, int fpageCount, int * copiesP )
{
	printStatus = FALSE;
	pageCount = fpageCount;
	pageNumber = 0;
	print_d.hDc = mswGetPrinterDC();
	if (print_d.hDc == (HDC)0) {
		return FALSE;
	}
		printStatus = TRUE;
		docInfo.cbSize = sizeof docInfo;
		docInfo.lpszDocName = title;
		docInfo.lpszOutput = NULL;
		lpAbortDlg = MakeProcInstance( (FARPROC)mswAbortDlg, mswHInst );
		lpAbortProc = MakeProcInstance( (FARPROC)mswAbortProc, mswHInst );
		SetAbortProc( print_d.hDc, (ABORTPROC)lpAbortProc );
		if (StartDoc( print_d.hDc, &docInfo ) < 0) {
			MessageBox( mswHWnd, "Unable to start print job",
						NULL, MB_OK|MB_ICONHAND );
			FreeProcInstance( lpAbortDlg );
			FreeProcInstance( lpAbortProc );
			DeleteDC( print_d.hDc );
			return FALSE;
		}
		printAbort = FALSE;
		hAbortDlgWnd = CreateDialog( mswHInst, "MswAbortDlg", mswHWnd,
						(DLGPROC)lpAbortDlg );
		/*SetDlgItemText( hAbortDlgWnd, IDM_PRINTAPP, title );*/
		SetWindowText( hAbortDlgWnd, title );
		ShowWindow( hAbortDlgWnd, SW_NORMAL );
		UpdateWindow( hAbortDlgWnd );
		EnableWindow( mswHWnd, FALSE );
		if (copiesP)
			*copiesP = printDlg.nCopies;
		if (printDlg.nCopies>1)
			pageCount *= printDlg.nCopies;
		if ( (GetDeviceCaps( printDlg.hDC, RASTERCAPS ) & RC_PALETTE) ) {
			newPrintPalette = mswCreatePalette();
			oldPrintPalette = SelectPalette( printDlg.hDC, newPrintPalette, 0 );
			RealizePalette( printDlg.hDC );
		}
		return TRUE;
}
Example #8
0
static int
winprint_start (struct winprint_data *wd, Tcl_Interp *interp, PRINTDLG *pd,
		const struct print_text_options *pto, int *cancelled)
{
  DOCINFO di;

  *cancelled = 0;

  wd->aborted = 0;

  /* We have no way to pass information to the abort function, so we
     need to use a global variable.  */
  abort_wd = wd;
  if (! SetAbortProc (pd->hDC, abort_function))
    {
      windows_error (interp, "SetAbortFunc");
      return TCL_ERROR;
    }

  di.cbSize = sizeof (DOCINFO);
  di.lpszDocName = pto->name;
  di.lpszOutput = NULL;
  di.lpszDatatype = NULL;
  di.fwType = 0;

  if (StartDoc (pd->hDC, &di) <= 0)
    {
      if (GetLastError () == ERROR_CANCELLED)
	*cancelled = 1;
      else
	{
	  windows_error (interp, "StartDoc");
	  return TCL_ERROR;
	}
    }

  return TCL_OK;
}
Example #9
0
void print_mswin(const char *file_name)
{
    HDC     hDC;
    DOCINFO di;
    short int width, height;

    HWND hWndParent = HWND_DESKTOP; /* would be better to be a real window */

    /* Need a printer DC to print to. */
    hDC = get_printer_dc(&width, &height);

    /* Did you get a good DC?, Cancel will return NULL also, so what to do? */
    if (!hDC) {
        return;
    }

    /* You always have to use an AbortProc(). */
    if (SetAbortProc(hDC, abort_proc) == SP_ERROR) {
        MessageBox(NULL, "Error setting up AbortProc",
                   "Error", MB_APPLMODAL | MB_OK);
        return;
    }

    /* Init the DOCINFO and start the document. */
    init_doc_struct(&di, "MyDoc");
    StartDoc(hDC, &di);

    /* Print one page. */
    StartPage(hDC);
    print_file(file_name, hDC, width, height);
    EndPage(hDC);

    /* Indicate end of document. */
    EndDoc(hDC);

    /* Clean up */
    DeleteDC(hDC);
}
Example #10
0
BOOL PrintMyPage (HWND hwnd)
{
     static DOCINFO di = { sizeof (DOCINFO), TEXT ("Print2: Printing") } ;
     BOOL           bSuccess = TRUE ;
     HDC            hdcPrn ;
     short          xPage, yPage ;
     
     if (NULL == (hdcPrn = GetPrinterDC ()))
          return FALSE ;
     
     xPage = GetDeviceCaps (hdcPrn, HORZRES) ;
     yPage = GetDeviceCaps (hdcPrn, VERTRES) ;
     
     EnableWindow (hwnd, FALSE) ;
     
     SetAbortProc (hdcPrn, AbortProc) ;
     
     if (StartDoc (hdcPrn, &di) > 0)
     {
          if (StartPage (hdcPrn) > 0)
          {
               PageGDICalls (hdcPrn, xPage, yPage) ;
               
               if (EndPage (hdcPrn) > 0)
                    EndDoc (hdcPrn) ;
               else
                    bSuccess = FALSE ;
          }
     }
     else
          bSuccess = FALSE ;
     
     EnableWindow (hwnd, TRUE) ;
     DeleteDC (hdcPrn) ;
     return bSuccess ;
}
Example #11
0
/************************************************************************
 *             Escape  [GDI32.@]
 */
INT WINAPI Escape( HDC hdc, INT escape, INT in_count, LPCSTR in_data, LPVOID out_data )
{
    INT ret;
    POINT *pt;

    switch (escape)
    {
    case ABORTDOC:
        return AbortDoc( hdc );

    case ENDDOC:
        return EndDoc( hdc );

    case GETPHYSPAGESIZE:
        pt = out_data;
        pt->x = GetDeviceCaps( hdc, PHYSICALWIDTH );
        pt->y = GetDeviceCaps( hdc, PHYSICALHEIGHT );
        return 1;

    case GETPRINTINGOFFSET:
        pt = out_data;
        pt->x = GetDeviceCaps( hdc, PHYSICALOFFSETX );
        pt->y = GetDeviceCaps( hdc, PHYSICALOFFSETY );
        return 1;

    case GETSCALINGFACTOR:
        pt = out_data;
        pt->x = GetDeviceCaps( hdc, SCALINGFACTORX );
        pt->y = GetDeviceCaps( hdc, SCALINGFACTORY );
        return 1;

    case NEWFRAME:
        return EndPage( hdc );

    case SETABORTPROC:
        return SetAbortProc( hdc, (ABORTPROC)in_data );

    case STARTDOC:
        {
            DOCINFOA doc;
            char *name = NULL;

            /* in_data may not be 0 terminated so we must copy it */
            if (in_data)
            {
                name = HeapAlloc( GetProcessHeap(), 0, in_count+1 );
                memcpy( name, in_data, in_count );
                name[in_count] = 0;
            }
            /* out_data is actually a pointer to the DocInfo structure and used as
             * a second input parameter */
            if (out_data) doc = *(DOCINFOA *)out_data;
            else
            {
                doc.cbSize = sizeof(doc);
                doc.lpszOutput = NULL;
                doc.lpszDatatype = NULL;
                doc.fwType = 0;
            }
            doc.lpszDocName = name;
            ret = StartDocA( hdc, &doc );
            HeapFree( GetProcessHeap(), 0, name );
            if (ret > 0) ret = StartPage( hdc );
            return ret;
        }

    case QUERYESCSUPPORT:
        {
            const INT *ptr = (const INT *)in_data;
            if (in_count < sizeof(INT)) return 0;
            switch(*ptr)
            {
            case ABORTDOC:
            case ENDDOC:
            case GETPHYSPAGESIZE:
            case GETPRINTINGOFFSET:
            case GETSCALINGFACTOR:
            case NEWFRAME:
            case QUERYESCSUPPORT:
            case SETABORTPROC:
            case STARTDOC:
                return TRUE;
            }
            break;
        }
    }

    /* if not handled internally, pass it to the driver */
    return ExtEscape( hdc, escape, in_count, in_data, 0, out_data );
}
Example #12
0
int Print(HWND win)
{
    BOOL rv = TRUE;
    int start, end;
    PRINTDLG pd;
    HWND hDlgCancel = 0;
    memset(&pd, 0, sizeof(pd));
    pd.lStructSize = sizeof(pd);
    pd.hwndOwner = hwndFrame;
    pd.Flags = PD_NOPAGENUMS | PD_RETURNDC | PD_COLLATE ;
    pd.hInstance = hInstance;
    SendDlgItemMessage(win, ID_EDITCHILD, EM_GETSEL, (WPARAM) &start, (LPARAM)
        &end);
    tabSetting = PropGetInt(NULL, "TAB_INDENT");
    leftmargin = PropGetInt(NULL, "PRINTER_LEFT");
    rightmargin = PropGetInt(NULL, "PRINTER_RIGHT");
    topmargin = PropGetInt(NULL, "PRINTER_TOP");
    bottommargin = PropGetInt(NULL, "PRINTER_BOTTOM");
    PropGetString(NULL, "PRINTER_HEADER", printHeader, sizeof(printHeader));
    PropGetString(NULL, "PRINTER_FOOTER", printFooter, sizeof(printFooter));
    if (tabSetting <= 0)
        tabSetting = 4;
    if (end != start)
        pd.Flags |= PD_SELECTION;
    if (PrintDlg(&pd))
    {
        DOCINFO di;
        HWND child;
        char *buf,  *pos,  *savepos1;
        if (pd.Flags &PD_SELECTION)
        {
            if (end <= start)
                return TRUE ;
        }
        child = GetDlgItem(win, ID_EDITCHILD);
        buf = GetEditData(child);
        if (!buf)
            return TRUE ;
        if (pd.Flags &PD_SELECTION)
        {
            savepos1 = pos = buf + start;
            buf[end] = 0;
        }
        else
            savepos1 = pos = buf;
        printing = TRUE;
        memset(&di, 0, sizeof(di));
        di.cbSize = sizeof(di);
        di.lpszDocName = (char*)SendMessage(win, WM_FILETITLE, 0, 0);
        if (pd.Flags &PD_PRINTTOFILE)
            di.lpszOutput = "FILE:";
        SetAbortProc(pd.hDC, &AbortProc);

        if (StartDoc(pd.hDC, &di) > 0)
        {
            int pelsx, pelsy;
            int width, height, rows, cols;
            int done = FALSE;
            char headerLeft[256],headerRight[256],headerCenter[256];
            char FooterLeft[256],FooterRight[256],FooterCenter[256];
            SIZE strsize ;
            HFONT hFont, oldhFont;

            pelsx = GetDeviceCaps(pd.hDC, LOGPIXELSX);
            pelsy = GetDeviceCaps(pd.hDC, LOGPIXELSY);

            fontdata.lfHeight =  - MulDiv(11, pelsx, 72);
            hFont = CreateFontIndirect(&fontdata);
            oldhFont = SelectObject(pd.hDC, hFont);
            GetTextExtentPoint32(pd.hDC, "A", 1, &strsize);

            width = GetDeviceCaps(pd.hDC, HORZRES);
            height = GetDeviceCaps(pd.hDC, VERTRES);
//            buf = GetEditData(win);

            rows = (height - (topmargin + bottommargin) *pelsy * 10 / 254) /
                strsize.cy ;
            cols = (width - (leftmargin + rightmargin) *pelsx * 10 / 254) /
                strsize.cx;

            if (rows <= 0 || cols <= 0)
            {
                AbortDoc(pd.hDC);
                free(buf);
                DeleteObject(hFont);
                if (pd.hDC != NULL)
                    DeleteDC(pd.hDC);
                if (pd.hDevMode != NULL)
                    GlobalFree(pd.hDevMode);
                if (pd.hDevNames != NULL)
                    GlobalFree(pd.hDevNames);
                return FALSE;
            }
            SelectObject(pd.hDC, oldhFont);
            if (printHeader[0])
                rows -= 2;
            if (printFooter[0])
                rows -= 2;
            total_pages = countPages(savepos1, rows, cols);
            setTimeFormats();
            split(printHeader, headerLeft, headerRight, headerCenter);
            split(printFooter, FooterLeft, FooterRight, FooterCenter);
            hDlgCancel = CreateDialog(hInstance, "PRINTABORTDLG", 0, (DLGPROC)
                CancelProc);
            EnableWindow(hwndFrame, FALSE);
            do
            {
                int colcount = pd.nCopies;
                int pagenum = 1;
                pos = savepos1;
                while (printing &&  *pos && StartPage(pd.hDC) > 0)
                {
                    int i, j, k;
                    int hdrlines = 0;
                    char line[512];
                    char *savepos2 = pos;
                    oldhFont = SelectObject(pd.hDC, hFont);
                    if (printHeader[0])
                    {
                        char buf[256];
                        int cx ;
                        int cy = topmargin * pelsy * 10/ 254;
                        cx = subs(pd.hDC, buf, headerLeft, di.lpszDocName, pagenum);
                        cx = leftmargin * pelsx * 10 / 254;
                        TextOut(pd.hDC, cx, cy, buf, strlen(buf));
                        cx = subs(pd.hDC, buf, headerCenter, di.lpszDocName, pagenum);
                        cx = (width - cx)/2 ;
                        TextOut(pd.hDC, cx, cy, buf, strlen(buf));
                        cx = subs(pd.hDC, buf, headerRight, di.lpszDocName, pagenum);
                        cx = width - cx - rightmargin * pelsx * 10 / 254;
                        TextOut(pd.hDC, cx, cy, buf, strlen(buf));
                        hdrlines = 2;
                    }
                    for (i = 0; i < rows; i++)
                    {
                        int count = 0;
                        if (*pos == '\n')
                        {
                            pos++;
                        }
                        else if (*pos == '\f')
                        {
                            pos += 2;
                            break;
                        }
                        else
                        {
                            for (j = 0; j < cols; j++)
                            {
                                if (*pos == '\t')
                                {
                                    int n = tabSetting - j % tabSetting;
                                    pos++;
                                    for (k = 0; k < n; k++)
                                        line[count++] = ' ';
                                    j += n - 1;
                                } 
                                else
                                {
                                    if (*pos < 32 ||  *pos > 126)
                                    {
                                        if (*pos == '\n')
                                            pos++;
                                        break;
                                    }
                                    line[count++] =  *pos++;
                                }
                            }
                            TextOut(pd.hDC, leftmargin *pelsx * 10 / 254, (i + hdrlines)
                                *strsize.cy + topmargin * pelsy * 10 / 254, line, count);
                        }
                        if (! *pos)
                            break;
                    }
                    if (printFooter[0])
                    {
                        char buf[256];
                        int cx ;
                        int cy = height - strsize.cy - bottommargin * pelsy * 10 / 254;
                        cx = subs(pd.hDC, buf, FooterLeft, di.lpszDocName, pagenum);
                        cx = leftmargin * pelsx * 10 / 254;
                        TextOut(pd.hDC, cx, cy, buf, strlen(buf));
                        cx = subs(pd.hDC, buf, FooterCenter, di.lpszDocName, pagenum);
                        cx = (width - cx) / 2;
                        TextOut(pd.hDC, cx, cy, buf, strlen(buf));
                        cx = subs(pd.hDC, buf, FooterRight, di.lpszDocName, pagenum);
                        cx = width - cx - rightmargin * pelsx * 10 / 254;
                        TextOut(pd.hDC, cx, cy, buf, strlen(buf));
                    }
                    SelectObject(pd.hDC, oldhFont);
                    if (printing)
                        if (EndPage(pd.hDC) <= 0)
                            goto doneprinting;
                    if (!(pd.Flags &PD_COLLATE))
                    {
                        if (--colcount)
                        {
                            pos = savepos2;
                        }
                        else
                        {
                            colcount = pd.nCopies;
                            pagenum++;
                        }
                    }
                    else
                    {
                        pagenum++;
                    }
                        
                }
            }
            while (printing && (pd.Flags &PD_COLLATE) && --pd.nCopies)
                ;
            if (!printing)
                AbortDoc(pd.hDC);
            doneprinting: if (printing)
                EndDoc(pd.hDC);
            EnableWindow(hwndFrame, TRUE);
            if (hDlgCancel)
                DestroyWindow(hDlgCancel);
            DeleteObject(hFont);
        }
        FreeEditData(buf);

    }
    if (pd.hDC != NULL)
        DeleteDC(pd.hDC);
    if (pd.hDevMode != NULL)
        GlobalFree(pd.hDevMode);
    if (pd.hDevNames != NULL)
        GlobalFree(pd.hDevNames);
    return rv;
}
Example #13
0
BOOL PrintWindowDriver(
  HINSTANCE hInst,
  HWND hwnd, 
  LPSTR szTitleName)
  {
   BOOL bSuccess, deleteFont = FALSE;
   LPCTSTR pstrBuffer ;
   int yChar, iLinesPerPage, iTotalLines = 0;
   long iCharsPerLine;
   int displayStart = 0;
   int iTotalPages;
   TEXTMETRIC tm ;
   HFONT hfont, ofont;
   HDC dc;
   LOGFONT lf;
   HWND hwndEdit;
   struct statusWindowData *theStatusData;
   struct displayWindowData *theDisplayData;
   
   /*===========================*/
   /* Display the print dialog. */
   /*===========================*/
   
   if (! PrintDlg(&PrintDialog))
     { return TRUE ; }

   /*===========================================*/
   /* If there is nothing to print then return. */
   /*===========================================*/
   
   if (((ATOM) GetClassLongPtr(hwnd,GCW_ATOM)) == EditAtomClass)
	 {
	  hwndEdit = GetDlgItem(hwnd,ID_EDIT_CONTROL);

	  iTotalLines = (short) SendMessage(hwndEdit,EM_GETLINECOUNT,0,0L);

	  ofont = GetWindowFont(hwndEdit);
	 }
   else if (((ATOM) GetClassLongPtr(hwnd,GCW_ATOM)) == StatusAtomClass)
     {   
      theStatusData = (struct statusWindowData *) GetWindowLongPtr(hwnd,GWLP_USERDATA);
   
      if (theStatusData == NULL) 
        { return TRUE; }

      iTotalLines = (*theStatusData->getCount)(GetCurrentEnvironment());
      
      memset(&lf,0,sizeof(LOGFONT));
      lf.lfHeight = -13;
      strcpy(lf.lfFaceName,"Courier New");
      ofont = CreateFontIndirect(&lf);
      deleteFont = TRUE;
     }
   else if (((ATOM) GetClassLongPtr(hwnd,GCW_ATOM)) == DisplayAtomClass)
     {
      theDisplayData = (struct displayWindowData *) GetWindowLongPtr(hwnd,GWLP_USERDATA);
   
      if (theDisplayData == NULL) 
        { return TRUE; }

      DisplayLineCountAndStart(hwnd,&iTotalLines,&displayStart);

      memset(&lf,0,sizeof(LOGFONT));
      lf.lfHeight = -13;
      strcpy(lf.lfFaceName,"Courier New");
      ofont = CreateFontIndirect(&lf);
      deleteFont = TRUE;
     }
   else
     { iTotalLines = 0; }

   if (iTotalLines == 0)
     { return TRUE; }
     
   /*=================================================*/
   /* Create a logical font for use with the printer. */
   /*=================================================*/
   
   memset(&lf,0,sizeof(LOGFONT));
   dc = GetDC(hwnd);
   SelectObject(dc,ofont);
   GetTextFace(dc,LF_FACESIZE,lf.lfFaceName);
   GetTextMetrics(dc,&tm);

   lf.lfHeight = tm.tmHeight * (GetDeviceCaps(PrintDialog.hDC,LOGPIXELSY) / GetDeviceCaps(dc,LOGPIXELSY));
   lf.lfPitchAndFamily = tm.tmPitchAndFamily;

   hfont = CreateFontIndirect(&lf);
   if (hfont != NULL)
     { SelectObject(PrintDialog.hDC,hfont); }
   
   ReleaseDC(hwnd,dc);
     
   if (deleteFont)
     { DeleteFont(ofont); }
     
   GetTextMetrics(PrintDialog.hDC,&tm);
   yChar = tm.tmHeight + tm.tmExternalLeading;

   iCharsPerLine = GetDeviceCaps(PrintDialog.hDC,HORZRES) / tm.tmAveCharWidth;
   iLinesPerPage = GetDeviceCaps(PrintDialog.hDC,VERTRES) / yChar;
   iTotalPages = (iTotalLines + iLinesPerPage - 1) / iLinesPerPage;

   pstrBuffer = (LPCTSTR) HeapAlloc(GetProcessHeap(), 
		                            HEAP_NO_SERIALIZE,
		                            (unsigned long) iCharsPerLine + 1);

   /*=============================================*/
   /* Disable the parent window of the dialog so  */
   /* all messages go to the cancel print dialog. */
   /*=============================================*/
   
   EnableWindow(hwnd,FALSE);

   /*=============================*/
   /* Set the success/abort flags */
   /* to their initial value.     */
   /*=============================*/
   
   bUserAbort = FALSE;

   /*=================================*/
   /* Create the cancel print dialog. */
   /*=================================*/
   
   hDlgPrint = CreateDialog(hInst,(LPCTSTR) "PrintDlgBox",hwnd,PrintDlgProc);
   SetDlgItemText(hDlgPrint,IDD_FNAME,szTitleName);

   /*=========================================*/
   /* Set the abort procedure which handles   */
   /* dispatching of messages while printing. */
   /*=========================================*/
   
   SetAbortProc(PrintDialog.hDC,AbortProc);

   GetWindowText(hwnd,(PTSTR) di.lpszDocName,sizeof (PTSTR));

   if (StartDoc (PrintDialog.hDC, &di) > 0)
     {
      bSuccess = PrintIt(iTotalPages,iLinesPerPage,iTotalLines,iCharsPerLine,
                         yChar,pstrBuffer,hwnd);
     }
   else
     { bSuccess = FALSE; }

   if (bSuccess)
     { EndDoc(PrintDialog.hDC); }

   if (! bUserAbort)
     {
      EnableWindow(hwnd,TRUE);
      DestroyWindow (hDlgPrint) ;
     }

   HeapFree(GetProcessHeap(),0,(LPVOID) pstrBuffer);
   DeleteDC(PrintDialog.hDC);

   if (hfont != NULL)
     { DeleteFont(hfont); }

   return (bSuccess && (! bUserAbort));
  }
Example #14
0
static void PrintPiecesThread(void* pv)
{
	CFrameWndEx* pFrame = (CFrameWndEx*)pv;
	CView* pView = pFrame->GetActiveView();
	CPrintDialog PD(FALSE, PD_ALLPAGES|PD_USEDEVMODECOPIES|PD_NOPAGENUMS|PD_NOSELECTION, pFrame);

	if (theApp.DoPrintDialog(&PD) != IDOK)
		return; 

	if (PD.m_pd.hDC == NULL)
		return;

	Project* project = lcGetActiveProject();
	ObjArray<lcPiecesUsedEntry> PiecesUsed;

	project->GetPiecesUsed(PiecesUsed);
	PiecesUsed.Sort(PiecesUsedSortFunc, NULL);

	// gather file to print to if print-to-file selected
	CString strOutput;
	if (PD.m_pd.Flags & PD_PRINTTOFILE)
	{
		CString strDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULTEXT));
		CString strPrintDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULT));
		CString strFilter(MAKEINTRESOURCE(AFX_IDS_PRINTFILTER));
		CString strCaption(MAKEINTRESOURCE(AFX_IDS_PRINTCAPTION));
		CFileDialog dlg(FALSE, strDef, strPrintDef,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, strFilter);
		dlg.m_ofn.lpstrTitle = strCaption;
		if (dlg.DoModal() != IDOK)
			return;
		strOutput = dlg.GetPathName();
	}

	CString DocName;
	char* Ext = strrchr(project->m_strTitle, '.');
	DocName.Format("LeoCAD - %.*s BOM", Ext ? Ext - project->m_strTitle : strlen(project->m_strTitle), project->m_strTitle);
	DOCINFO docInfo;
	memset(&docInfo, 0, sizeof(DOCINFO));
	docInfo.cbSize = sizeof(DOCINFO);
	docInfo.lpszDocName = DocName;
	CString strPortName;

	int nFormatID;
	if (strOutput.IsEmpty())
	{
		docInfo.lpszOutput = NULL;
		strPortName = PD.GetPortName();
		nFormatID = AFX_IDS_PRINTONPORT;
	}
	else
	{
		docInfo.lpszOutput = strOutput;
		AfxGetFileTitle(strOutput, strPortName.GetBuffer(_MAX_PATH), _MAX_PATH);
		nFormatID = AFX_IDS_PRINTTOFILE;
	}

	SetAbortProc(PD.m_pd.hDC, _AfxAbortProc);
	pFrame->EnableWindow(FALSE);
	CPrintingDialog dlgPrintStatus(NULL);

	CString strTemp;
	dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_DOCNAME, DocName);
	dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PRINTERNAME, PD.GetDeviceName());
	AfxFormatString1(strTemp, nFormatID, strPortName);
	dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PORTNAME, strTemp);
	dlgPrintStatus.ShowWindow(SW_SHOW);
	dlgPrintStatus.UpdateWindow();

	if (StartDoc(PD.m_pd.hDC, &docInfo) == SP_ERROR)
	{
		pFrame->EnableWindow(TRUE);
		dlgPrintStatus.DestroyWindow();
		AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT);
		return;
	}

	int ResX = GetDeviceCaps(PD.m_pd.hDC, LOGPIXELSX);
	int ResY = GetDeviceCaps(PD.m_pd.hDC, LOGPIXELSY);

	CRect RectDraw(0, 0, GetDeviceCaps(PD.m_pd.hDC, HORZRES), GetDeviceCaps(PD.m_pd.hDC, VERTRES));
	DPtoLP(PD.m_pd.hDC, (LPPOINT)(RECT*)&RectDraw, 2);
	RectDraw.DeflateRect((int)(ResX*(float)theApp.GetProfileInt("Default","Margin Left", 50)/100.0f),
	                     (int)(ResY*(float)theApp.GetProfileInt("Default","Margin Top", 50)/100.0f),
	                     (int)(ResX*(float)theApp.GetProfileInt("Default","Margin Right", 50)/100.0f),
	                     (int)(ResY*(float)theApp.GetProfileInt("Default","Margin Bottom", 50)/100.0f));

	CRect HeaderRect = RectDraw;
 	HeaderRect.top -= (int)(ResY*theApp.GetProfileInt("Default", "Margin Top", 50) / 200.0f);
	HeaderRect.bottom += (int)(ResY*theApp.GetProfileInt("Default", "Margin Bottom", 50) / 200.0f);

	int RowsPerPage = AfxGetApp()->GetProfileInt("Default", "Catalog Rows", 10);
	int ColsPerPage = AfxGetApp()->GetProfileInt("Default", "Catalog Columns", 3);
	int PicHeight = RectDraw.Height() / RowsPerPage;
	int PicWidth = RectDraw.Width() / ColsPerPage;
	int TotalRows = (PiecesUsed.GetSize() + ColsPerPage - 1) / ColsPerPage;
	int TotalPages = (TotalRows + RowsPerPage - 1) / RowsPerPage;
	int RowHeight = RectDraw.Height() / RowsPerPage;
	int ColWidth = RectDraw.Width() / ColsPerPage;

	PD.m_pd.nMinPage = 1;
	PD.m_pd.nMaxPage = TotalPages + 1;

	UINT EndPage = PD.m_pd.nToPage;
	UINT StartPage = PD.m_pd.nFromPage;
	if (PD.PrintAll())
	{
		EndPage = PD.m_pd.nMaxPage;
		StartPage = PD.m_pd.nMinPage;
	}

	lcClamp(EndPage, PD.m_pd.nMinPage, PD.m_pd.nMaxPage);
	lcClamp(StartPage, PD.m_pd.nMinPage, PD.m_pd.nMaxPage);
	int StepPage = (EndPage >= StartPage) ? 1 : -1;

	VERIFY(strTemp.LoadString(AFX_IDS_PRINTPAGENUM));

	// begin page printing loop
	BOOL bError = FALSE;

	// Creating Compatible Memory Device Context
	CDC *pMemDC = new CDC;
	if (!pMemDC->CreateCompatibleDC(pView->GetDC()))
		return;

	BITMAPINFO bi;
	ZeroMemory(&bi, sizeof(BITMAPINFO));
	bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bi.bmiHeader.biWidth = PicWidth;
	bi.bmiHeader.biHeight = PicHeight;
	bi.bmiHeader.biPlanes = 1;
	bi.bmiHeader.biBitCount = 24;
	bi.bmiHeader.biCompression = BI_RGB;
	bi.bmiHeader.biSizeImage = PicWidth * PicHeight * 3;
	bi.bmiHeader.biXPelsPerMeter = 2925;
	bi.bmiHeader.biYPelsPerMeter = 2925;
	bi.bmiHeader.biClrUsed = 0;
	bi.bmiHeader.biClrImportant = 0;
	
	LPBITMAPINFOHEADER lpbi[1];

	HBITMAP hBm, hBmOld;
    hBm = CreateDIBSection(pView->GetDC()->GetSafeHdc(), &bi, DIB_RGB_COLORS, (void **)&lpbi, NULL, (DWORD)0);
	if (!hBm)
		return;
	hBmOld = (HBITMAP)::SelectObject(pMemDC->GetSafeHdc(), hBm);

	PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI,
			PFD_TYPE_RGBA, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 };
	int pixelformat = ChoosePixelFormat(pMemDC->m_hDC, &pfd);
	DescribePixelFormat(pMemDC->m_hDC, pixelformat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
	SetPixelFormat(pMemDC->m_hDC, pixelformat, &pfd);
	HGLRC hmemrc = wglCreateContext(pMemDC->GetSafeHdc());
	wglMakeCurrent(pMemDC->GetSafeHdc(), hmemrc);

	GL_DisableVertexBufferObject();
	float Aspect = (float)PicWidth/(float)PicHeight;

	glViewport(0, 0, PicWidth, PicHeight);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(0.5f, 0.1f);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glClearColor(1, 1, 1, 1); 

	LOGFONT lf;
	memset(&lf, 0, sizeof(LOGFONT));
	lf.lfHeight = -MulDiv(12, ResY, 72);
	lf.lfWeight = FW_REGULAR;
	lf.lfCharSet = DEFAULT_CHARSET;
	lf.lfQuality = PROOF_QUALITY;
	strcpy (lf.lfFaceName , "Arial");

	HFONT HeaderFont = CreateFontIndirect(&lf);
	HFONT OldFont = (HFONT)SelectObject(PD.m_pd.hDC, HeaderFont);
	SetBkMode(PD.m_pd.hDC, TRANSPARENT);
	SetTextColor(PD.m_pd.hDC, 0x000000);
	SetTextAlign(PD.m_pd.hDC, TA_CENTER|TA_NOUPDATECP);

	DWORD PrintOptions = AfxGetApp()->GetProfileInt("Settings", "Print", PRINT_NUMBERS | PRINT_BORDER/*|PRINT_NAMES*/);
	bool DrawNames = 1;//(PrintOptions & PRINT_NAMES) != 0;
	bool Horizontal = 1;//(PrintOptions & PRINT_HORIZONTAL) != 0;

	pMemDC->SetTextColor(0x000000);
	pMemDC->SetBkMode(TRANSPARENT);
//	lf.lfHeight = -MulDiv(40, GetDeviceCaps(pMemDC->m_hDC, LOGPIXELSY), 72);
//	lf.lfWeight = FW_BOLD;
	HFONT CatalogFont = CreateFontIndirect(&lf);
	lf.lfHeight = -MulDiv(80, GetDeviceCaps(pMemDC->m_hDC, LOGPIXELSY), 72);
	HFONT CountFont = CreateFontIndirect(&lf);
	HFONT OldMemFont = (HFONT)SelectObject(pMemDC->m_hDC, CatalogFont);
	HPEN hpOld = (HPEN)SelectObject(pMemDC->m_hDC, GetStockObject(BLACK_PEN));

	for (UINT CurPage = StartPage; CurPage != EndPage; CurPage += StepPage)
	{
		TCHAR szBuf[80];
		wsprintf(szBuf, strTemp, CurPage);
		dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PAGENUM, szBuf);
		if (::StartPage(PD.m_pd.hDC) < 0)
		{
			bError = TRUE;
			break;
		}

		// Draw header and footer.
		SelectObject(PD.m_pd.hDC, HeaderFont);

		CString Header;
		UINT Align;

		FormatHeader(Header, Align, AfxGetApp()->GetProfileString("Default", "Catalog Header", ""), project->m_strTitle, project->m_strAuthor, project->m_strDescription, CurPage, TotalPages);
		Align |= DT_TOP|DT_SINGLELINE;

		DrawText(PD.m_pd.hDC, (LPCTSTR)Header, Header.GetLength(), HeaderRect, Align);

		FormatHeader(Header, Align, AfxGetApp()->GetProfileString("Default", "Catalog Footer", "Page &P"), project->m_strTitle, project->m_strAuthor, project->m_strDescription, CurPage, TotalPages);
		Align |= DT_BOTTOM|DT_SINGLELINE;

		DrawText(PD.m_pd.hDC, (LPCTSTR)Header, Header.GetLength(), HeaderRect, Align);

		int StartPiece = (CurPage - 1) * RowsPerPage * ColsPerPage;
		int EndPiece = lcMin(StartPiece + RowsPerPage * ColsPerPage, PiecesUsed.GetSize());

		for (int CurPiece = StartPiece; CurPiece < EndPiece; CurPiece++)
		{
			FillRect(pMemDC->m_hDC, CRect(0, PicHeight, PicWidth, 0), (HBRUSH)GetStockObject(WHITE_BRUSH));
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			PieceInfo* pInfo = PiecesUsed[CurPiece].Info;
			pInfo->ZoomExtents(30.0f, Aspect);

			pInfo->RenderPiece(PiecesUsed[CurPiece].ColorIndex);
			glFinish();

			// Draw description text at the bottom.
			CRect TextRect(0, 0, PicWidth, PicHeight);
	
			if (DrawNames)
			{
				SelectObject(pMemDC->m_hDC, CatalogFont);
				pMemDC->DrawText(pInfo->m_strDescription, strlen(pInfo->m_strDescription), TextRect, DT_CALCRECT | DT_WORDBREAK);

				TextRect.OffsetRect(0, PicHeight - TextRect.Height() - 5);
				pMemDC->DrawText(pInfo->m_strDescription, strlen(pInfo->m_strDescription), TextRect, DT_WORDBREAK);
			}

			// Draw count.
			SelectObject(pMemDC->m_hDC, CountFont);
			TextRect = CRect(0, 0, PicWidth, TextRect.top);
			TextRect.DeflateRect(5, 5);

			char CountStr[16];
			sprintf(CountStr, "%dx", PiecesUsed[CurPiece].Count);
			pMemDC->DrawText(CountStr, strlen(CountStr), TextRect, DT_BOTTOM | DT_LEFT | DT_SINGLELINE);

			LPBITMAPINFOHEADER lpbi[1];
			lpbi[0] = (LPBITMAPINFOHEADER)GlobalLock(MakeDib(hBm, 24));
			BITMAPINFO bi;
			ZeroMemory(&bi, sizeof(BITMAPINFO));
			memcpy (&bi.bmiHeader, lpbi[0], sizeof(BITMAPINFOHEADER));
			SetStretchBltMode(PD.m_pd.hDC, COLORONCOLOR);

			int CurRow, CurCol;

			if (Horizontal)
			{
				CurRow = (CurPiece - StartPiece) / ColsPerPage;
				CurCol = (CurPiece - StartPiece) % ColsPerPage;
			}
			else
			{
				CurRow = (CurPiece - StartPiece) % RowsPerPage;
				CurCol = (CurPiece - StartPiece) / RowsPerPage;
			}
			
			int Left = RectDraw.left + ColWidth * CurCol + (ColWidth - PicWidth) / 2;
			int Top = RectDraw.top + RowHeight * CurRow + (RowHeight - PicHeight) / 2;

			StretchDIBits(PD.m_pd.hDC, Left, Top, PicWidth, PicHeight, 0, 0, PicWidth, PicHeight, 
			              (LPBYTE)lpbi[0] + lpbi[0]->biSize + lpbi[0]->biClrUsed * sizeof(RGBQUAD), &bi, DIB_RGB_COLORS, SRCCOPY);
			if (lpbi[0])
				GlobalFreePtr(lpbi[0]);
		}

		if (::EndPage(PD.m_pd.hDC) < 0 || !_AfxAbortProc(PD.m_pd.hDC, 0))
		{
			bError = TRUE;
			break;
		}
	}

	SelectObject(pMemDC->m_hDC, hpOld);
	SelectObject(PD.m_pd.hDC, OldFont);
	DeleteObject(HeaderFont);
	SelectObject(pMemDC->m_hDC, OldMemFont);
	DeleteObject(CatalogFont);
	DeleteObject(CountFont);

	GL_EnableVertexBufferObject();
	wglMakeCurrent(NULL, NULL);
	wglDeleteContext(hmemrc);
	SelectObject(pMemDC->GetSafeHdc(), hBmOld);
	DeleteObject(hBm);
	delete pMemDC;

	if (!bError)
		EndDoc(PD.m_pd.hDC);
	else
		AbortDoc(PD.m_pd.hDC);

	pFrame->EnableWindow();
	dlgPrintStatus.DestroyWindow();

	if (PD.m_pd.hDC != NULL)
    {
		::DeleteDC(PD.m_pd.hDC);
		PD.m_pd.hDC = NULL;
    }
}
Example #15
0
static void test_abort_proc(void)
{
    HDC print_dc;
    RECT rect = {0, 0, 100, 100};
    DOCINFOA doc_info = {0};
    PRINTDLGA pd = {0};
    char filename[MAX_PATH];

    if (!GetTempFileNameA(".", "prn", 0, filename))
    {
        skip("Failed to create a temporary file name\n");
        return;
    }

    pd.lStructSize = sizeof(pd);
    pd.Flags = PD_RETURNDEFAULT | PD_ALLPAGES | PD_RETURNDC | PD_PRINTTOFILE;
    pd.nFromPage = 1;
    pd.nToPage = 1;
    pd.nCopies = 1;

    if (!PrintDlgA(&pd))
    {
        skip("No default printer available.\n");
        ok(DeleteFileA(filename), "Failed to delete temporary file\n");
        return;
    }

    ok(pd.hDC != NULL, "PrintDlg didn't return a DC.\n");
    if (!(print_dc = pd.hDC))
    {
        ok(DeleteFileA(filename), "Failed to delete temporary file\n");
        return;
    }

    ok(SetAbortProc(print_dc, abort_proc) > 0, "SetAbortProc failed\n");
    ok(!abort_proc_called, "AbortProc got called unexpectedly by SetAbortProc.\n");
    abort_proc_called = FALSE;

    doc_info.cbSize = sizeof(doc_info);
    doc_info.lpszDocName = "Some document";
    doc_info.lpszOutput = filename;

    ok(StartDocA(print_dc, &doc_info) > 0, "StartDocA failed\n");
    ok(abort_proc_called, "AbortProc didn't get called by StartDoc.\n");
    abort_proc_called = FALSE;

    ok(StartPage(print_dc) > 0, "StartPage failed\n");
    ok(!abort_proc_called, "AbortProc got called unexpectedly by StartPage.\n");
    abort_proc_called = FALSE;

    ok(FillRect(print_dc, &rect, (HBRUSH)(COLOR_BACKGROUND + 1)), "FillRect failed\n");
    ok(!abort_proc_called, "AbortProc got called unexpectedly by StretchBlt.\n");
    abort_proc_called = FALSE;

    ok(EndPage(print_dc) > 0, "EndPage failed\n");
    ok(!abort_proc_called, "AbortProc got called unexpectedly by EndPage.\n");
    abort_proc_called = FALSE;

    ok(EndDoc(print_dc) > 0, "EndDoc failed\n");
    ok(!abort_proc_called, "AbortProc got called unexpectedly by EndDoc.\n");
    abort_proc_called = FALSE;

    ok(DeleteDC(print_dc), "DeleteDC failed\n");
    ok(!abort_proc_called, "AbortProc got called unexpectedly by DeleteDC.\n");
    abort_proc_called = FALSE;

    ok(DeleteFileA(filename), "Failed to delete temporary file\n");
}
Example #16
0
/*
 * @unimplemented
 */
INT
WINAPI
Escape(
    _In_ HDC hdc,
    _In_ INT nEscape,
    _In_ INT cbInput,
    _In_ LPCSTR lpvInData,
    _Out_ LPVOID lpvOutData)
{
    INT retValue = SP_ERROR;
    ULONG ulObjType;

    ulObjType = GDI_HANDLE_GET_TYPE(hdc);

    if (ulObjType == GDILoObjType_LO_METADC16_TYPE)
    {
        return METADC16_Escape(hdc, nEscape, cbInput, lpvInData, lpvOutData);
    }

    switch (nEscape)
    {
        case ABORTDOC:
            /* Note: Windows checks if the handle has any user data for the ABORTDOC command
             * ReactOS copies this behavior to be compatible with windows 2003
             */
            if (GdiGetDcAttr(hdc) == NULL)
            {
                GdiSetLastError(ERROR_INVALID_HANDLE);
                retValue = FALSE;
            }
            else
            {
                retValue = AbortDoc(hdc);
            }
            break;

        case DRAFTMODE:
        case FLUSHOUTPUT:
        case SETCOLORTABLE:
            /* Note 1: DRAFTMODE, FLUSHOUTPUT, SETCOLORTABLE are outdated */
            /* Note 2: Windows checks if the handle has any user data for the DRAFTMODE, FLUSHOUTPUT, SETCOLORTABLE commands
             * ReactOS copies this behavior to be compatible with windows 2003
             */
            if (GdiGetDcAttr(hdc) == NULL)
            {
                GdiSetLastError(ERROR_INVALID_HANDLE);
            }
            retValue = FALSE;
            break;

        case SETABORTPROC:
            /* Note: Windows checks if the handle has any user data for the SETABORTPROC command
             * ReactOS copies this behavior to be compatible with windows 2003
             */
            if (GdiGetDcAttr(hdc) == NULL)
            {
                GdiSetLastError(ERROR_INVALID_HANDLE);
                retValue = FALSE;
            }
            retValue = SetAbortProc(hdc, (ABORTPROC)lpvInData);
            break;

        case GETCOLORTABLE:
            retValue = GetSystemPaletteEntries(hdc, (UINT)*lpvInData, 1, (LPPALETTEENTRY)lpvOutData);
            if (!retValue)
            {
                retValue = SP_ERROR;
            }
            break;

        case ENDDOC:
            /* Note: Windows checks if the handle has any user data for the ENDDOC command
             * ReactOS copies this behavior to be compatible with windows 2003
             */
            if (GdiGetDcAttr(hdc) == NULL)
            {
                GdiSetLastError(ERROR_INVALID_HANDLE);
                retValue = FALSE;
            }
            retValue = EndDoc(hdc);
            break;

        case GETSCALINGFACTOR:
            /* Note GETSCALINGFACTOR is outdated have been replace by GetDeviceCaps */
            if (ulObjType == GDI_OBJECT_TYPE_DC)
            {
                if (lpvOutData)
                {
                    PPOINT ptr = (PPOINT)lpvOutData;
                    ptr->x = 0;
                    ptr->y = 0;
                }
            }
            retValue = FALSE;
            break;

        case GETEXTENDEDTEXTMETRICS:
            retValue = GetETM(hdc, (EXTTEXTMETRIC *)lpvOutData) != 0;
            break;

        case STARTDOC:
        {
            DOCINFOA di;

            /* Note: Windows checks if the handle has any user data for the STARTDOC command
             * ReactOS copies this behavior to be compatible with windows 2003
             */
            if (GdiGetDcAttr(hdc) == NULL)
            {
                GdiSetLastError(ERROR_INVALID_HANDLE);
                retValue = FALSE;
            }

            di.cbSize = sizeof(DOCINFOA);
            di.lpszOutput = 0;
            di.lpszDatatype = 0;
            di.fwType = 0;
            di.lpszDocName = lpvInData;

            /* NOTE : doc for StartDocA/W at msdn http://msdn2.microsoft.com/en-us/library/ms535793(VS.85).aspx */
            retValue = StartDocA(hdc, &di);

            /* Check if StartDocA failed */
            if (retValue < 0)
            {
                {
                    retValue = GetLastError();

                    /* Translate StartDocA error code to STARTDOC error code
                     * see msdn http://msdn2.microsoft.com/en-us/library/ms535472.aspx
                     */
                    switch(retValue)
                    {
                    case ERROR_NOT_ENOUGH_MEMORY:
                        retValue = SP_OUTOFMEMORY;
                        break;

                    case ERROR_PRINT_CANCELLED:
                        retValue = SP_USERABORT;
                        break;

                    case ERROR_DISK_FULL:
                        retValue = SP_OUTOFDISK;
                        break;

                    default:
                        retValue = SP_ERROR;
                        break;
                    }
                }
            }
        }
        break;

        default:
            UNIMPLEMENTED;
            SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    }

    return retValue;
}
Example #17
0
static void test_abort_proc(void)
{
    HDC print_dc;
    RECT rect = {0, 0, 100, 100};
    DOCINFOA doc_info = {0};
    PRINTDLGA pd = {0};
    char filename[MAX_PATH];
    int job_id;

    if (!GetTempFileNameA(".", "prn", 0, filename))
    {
        skip("Failed to create a temporary file name\n");
        return;
    }

    pd.lStructSize = sizeof(pd);
    pd.Flags = PD_RETURNDEFAULT | PD_ALLPAGES | PD_RETURNDC | PD_PRINTTOFILE;
    pd.nFromPage = 1;
    pd.nToPage = 1;
    pd.nCopies = 1;

    if (!PrintDlgA(&pd))
    {
        skip("No default printer available.\n");
        goto end;
    }
    GlobalFree(pd.hDevMode);
    GlobalFree(pd.hDevNames);

    ok(pd.hDC != NULL, "PrintDlg didn't return a DC.\n");
    if (!(print_dc = pd.hDC))
        goto end;

    ok(SetAbortProc(print_dc, abort_proc) > 0, "SetAbortProc failed\n");
    ok(!abort_proc_called, "AbortProc got called unexpectedly by SetAbortProc.\n");
    abort_proc_called = FALSE;

    doc_info.cbSize = sizeof(doc_info);
    doc_info.lpszDocName = "Some document";
    doc_info.lpszOutput = filename;

    job_id = StartDocA(print_dc, &doc_info);

    ok(job_id > 0 ||
       GetLastError() == ERROR_SPL_NO_STARTDOC, /* Vista can fail with this error when using the XPS driver */
       "StartDocA failed ret %d gle %d\n", job_id, GetLastError());

    if(job_id <= 0)
    {
        skip("StartDoc failed\n");
        goto end;
    }

    /* StartDoc may or may not call abort proc */

    abort_proc_called = FALSE;
    ok(StartPage(print_dc) > 0, "StartPage failed\n");
    ok(!abort_proc_called, "AbortProc got called unexpectedly by StartPage.\n");
    abort_proc_called = FALSE;

    /* following functions sometimes call abort proc too */
    ok(FillRect(print_dc, &rect, (HBRUSH)(COLOR_BACKGROUND + 1)), "FillRect failed\n");
    ok(EndPage(print_dc) > 0, "EndPage failed\n");
    ok(EndDoc(print_dc) > 0, "EndDoc failed\n");

    abort_proc_called = FALSE;
    ok(DeleteDC(print_dc), "DeleteDC failed\n");
    ok(!abort_proc_called, "AbortProc got called unexpectedly by DeleteDC.\n");
    abort_proc_called = FALSE;

end:
    SetLastError(0xdeadbeef);
    if(!DeleteFileA(filename))
        trace("Failed to delete temporary file (err = %x)\n", GetLastError());
}
Example #18
0
static void PrintCatalogThread (CWnd* pParent, CFrameWndEx* pMainFrame)
{
	CCADView* pView = (CCADView*)pMainFrame->GetActiveView();
	CPrintDialog* PD = new CPrintDialog(FALSE, PD_ALLPAGES|PD_USEDEVMODECOPIES|PD_NOSELECTION|PD_ENABLEPRINTHOOK, pParent);
	lcPiecesLibrary *pLib = lcGetPiecesLibrary();

	int bricks = 0;
	for (int j = 0; j < pLib->mPieces.GetSize(); j++)
		if (pLib->mPieces[j]->m_strDescription[0] != '~')
			bricks++;
	int rows = theApp.GetProfileInt("Default", "Catalog Rows", 10);
	int cols = theApp.GetProfileInt("Default", "Catalog Columns", 3);
	PD->m_pd.lpfnPrintHook = PrintHookProc;
	PD->m_pd.nFromPage = PD->m_pd.nMinPage = 1; 
	PD->m_pd.nMaxPage = bricks/(rows*cols);
	if (bricks%(rows*cols) != 0) PD->m_pd.nMaxPage++;
	PD->m_pd.nToPage = PD->m_pd.nMaxPage;
	PD->m_pd.lCustData= (LONG)pMainFrame;

	// bring up the print dialog and allow user to change things
	if (theApp.DoPrintDialog(PD) != IDOK) return; 
	if (PD->m_pd.hDC == NULL) return;

	// update page range
	rows = theApp.GetProfileInt("Default","Catalog Rows", 10);
	cols = theApp.GetProfileInt("Default","Catalog Columns", 3);
	PD->m_pd.nMaxPage = bricks/(rows*cols);
	if (bricks%(rows*cols) != 0) PD->m_pd.nMaxPage++;

	// gather file to print to if print-to-file selected
	CString strOutput;
	if (PD->m_pd.Flags & PD_PRINTTOFILE)
	{
		// construct CFileDialog for browsing
		CString strDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULTEXT));
		CString strPrintDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULT));
		CString strFilter(MAKEINTRESOURCE(AFX_IDS_PRINTFILTER));
		CString strCaption(MAKEINTRESOURCE(AFX_IDS_PRINTCAPTION));
		CFileDialog dlg(FALSE, strDef, strPrintDef,
			OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, strFilter);
		dlg.m_ofn.lpstrTitle = strCaption;

		if (dlg.DoModal() != IDOK)
			return;

		// set output device to resulting path name
		strOutput = dlg.GetPathName();
	}

	DOCINFO docInfo;
	memset(&docInfo, 0, sizeof(DOCINFO));
	docInfo.cbSize = sizeof(DOCINFO);
	docInfo.lpszDocName = "LeoCAD pieces catalog";
	CString strPortName;
	int nFormatID;
	if (strOutput.IsEmpty())
	{
		docInfo.lpszOutput = NULL;
		strPortName = PD->GetPortName();
		nFormatID = AFX_IDS_PRINTONPORT;
	}
	else
	{
		docInfo.lpszOutput = strOutput;
		AfxGetFileTitle(strOutput, strPortName.GetBuffer(_MAX_PATH), _MAX_PATH);
		nFormatID = AFX_IDS_PRINTTOFILE;
	}

	// setup the printing DC
	SetAbortProc(PD->m_pd.hDC, _AfxAbortProc);

	// disable main window while printing & init printing status dialog
	pParent->EnableWindow(FALSE);
	CPrintingDialog dlgPrintStatus(NULL);

	CString strTemp;
	dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_DOCNAME, "LeoCAD parts catalog");
	dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PRINTERNAME, PD->GetDeviceName());
	AfxFormatString1(strTemp, nFormatID, strPortName);
	dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PORTNAME, strTemp);
	dlgPrintStatus.ShowWindow(SW_SHOW);
	dlgPrintStatus.UpdateWindow();

	// start document printing process
	if (StartDoc(PD->m_pd.hDC, &docInfo) == SP_ERROR)
	{
		pParent->EnableWindow(TRUE);
		dlgPrintStatus.DestroyWindow();
		AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT);
		return;
	}

	// Guarantee values are in the valid range
	UINT nEndPage = PD->m_pd.nToPage;
	UINT nStartPage = PD->m_pd.nFromPage;

	if (PD->PrintAll())
	{
		nEndPage = PD->m_pd.nMaxPage;
		nStartPage = PD->m_pd.nMinPage;
	}

	if (nEndPage < PD->m_pd.nMinPage) nEndPage = PD->m_pd.nMinPage;
	if (nEndPage > PD->m_pd.nMaxPage) nEndPage = PD->m_pd.nMaxPage;
	if (nStartPage < PD->m_pd.nMinPage) nStartPage = PD->m_pd.nMinPage;
	if (nStartPage > PD->m_pd.nMaxPage) nStartPage = PD->m_pd.nMaxPage;

	int nStep = (nEndPage >= nStartPage) ? 1 : -1;
	nEndPage = nEndPage + nStep;

	VERIFY(strTemp.LoadString(AFX_IDS_PRINTPAGENUM));

	// begin page printing loop
	BOOL bError = FALSE;

	// set up drawing rect to entire page (in logical coordinates)
	CRect rectDraw (0, 0, GetDeviceCaps(PD->m_pd.hDC, HORZRES), GetDeviceCaps(PD->m_pd.hDC, VERTRES));
	DPtoLP(PD->m_pd.hDC, (LPPOINT)(RECT*)&rectDraw, 2);
	rectDraw.DeflateRect(
		GetDeviceCaps(PD->m_pd.hDC, LOGPIXELSX)*theApp.GetProfileInt("Default","Margin Left", 50)/100, 
		GetDeviceCaps(PD->m_pd.hDC, LOGPIXELSY)*theApp.GetProfileInt("Default","Margin Top", 50)/100,
		GetDeviceCaps(PD->m_pd.hDC, LOGPIXELSX)*theApp.GetProfileInt("Default","Margin Right", 50)/100, 
		GetDeviceCaps(PD->m_pd.hDC, LOGPIXELSY)*theApp.GetProfileInt("Default","Margin Bottom", 50)/100);
	int w = rectDraw.Width()/cols;
	int h = rectDraw.Height()/rows;

	// Creating Compatible Memory Device Context
	CDC *pMemDC = new CDC;
	if (!pMemDC->CreateCompatibleDC(pView->GetDC()))
		return;

	// Preparing bitmap header for DIB section
	BITMAPINFO bi;
	ZeroMemory(&bi, sizeof(BITMAPINFO));
	
	bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bi.bmiHeader.biWidth = w;
	bi.bmiHeader.biHeight = h;
	bi.bmiHeader.biPlanes = 1;
	bi.bmiHeader.biBitCount = 24;
	bi.bmiHeader.biCompression = BI_RGB;
	bi.bmiHeader.biSizeImage = w * h * (24/8);
	bi.bmiHeader.biXPelsPerMeter = 2925;
	bi.bmiHeader.biYPelsPerMeter = 2925;
	bi.bmiHeader.biClrUsed = 0;
	bi.bmiHeader.biClrImportant = 0;
	
	LPBITMAPINFOHEADER lpbi[1];

	// Creating a DIB surface
	HBITMAP hBm, hBmOld;
	hBm = CreateDIBSection(pView->GetDC()->GetSafeHdc(), &bi, DIB_RGB_COLORS, 
		(void **)&lpbi, NULL, (DWORD)0);
	if (!hBm)
		return;

	// Selecting the DIB Surface
	hBmOld = (HBITMAP)::SelectObject(pMemDC->GetSafeHdc(), hBm);
	if (!hBmOld)
		return;

	// Setting up a Pixel format for the DIB surface
	PIXELFORMATDESCRIPTOR pfd = {
		sizeof(PIXELFORMATDESCRIPTOR),
			1,PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI,
			PFD_TYPE_RGBA, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,
			0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 };
	int pixelformat = ChoosePixelFormat(pMemDC->m_hDC, &pfd);
	DescribePixelFormat(pMemDC->m_hDC, pixelformat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
	SetPixelFormat(pMemDC->m_hDC, pixelformat, &pfd);
	
	// Creating a OpenGL context
	HGLRC hmemrc = wglCreateContext(pMemDC->GetSafeHdc());
	
	// Setting up the current OpenGL context
	GL_DisableVertexBufferObject();
	wglMakeCurrent(pMemDC->GetSafeHdc(), hmemrc);
	double aspect = (float)w/(float)h;
	glMatrixMode(GL_MODELVIEW);
	glViewport(0, 0, w, h);

	// Sort pieces by description
	struct BRICKSORT {
		char name[64];
		int actual;
		struct BRICKSORT *next;
	} start, *node, *previous, *news;

	start.next = NULL;
	
	for (int j = 0; j < pLib->mPieces.GetSize(); j++)
	{
		char* desc = pLib->mPieces[j]->m_strDescription;

		if (desc[0] != '~')
			continue;

		// Find the correct location
		previous = &start;
		node = start.next;
		while ((node) && (strcmp(desc, node->name) > 0))
		{
			node = node->next;
			previous = previous->next;
		}
		
		news = (struct BRICKSORT*) malloc(sizeof(struct BRICKSORT));
		news->next = node;
		previous->next = news;
		strcpy(news->name, desc);
		news->actual = j;
	}
	
	node = start.next;

	if (PD->PrintRange())
	{
		for (int j = 0; j < (int)(nStartPage - 1)*rows*cols; j++)
			if (node)
				node = node->next;
	}

	LOGFONT lf;
	memset(&lf, 0, sizeof(LOGFONT));
	lf.lfHeight = -MulDiv(12, GetDeviceCaps(PD->m_pd.hDC, LOGPIXELSY), 72);
	lf.lfWeight = FW_REGULAR;
	lf.lfCharSet = DEFAULT_CHARSET;
	lf.lfQuality = PROOF_QUALITY;
	strcpy (lf.lfFaceName , "Arial");
	HFONT HeaderFont = CreateFontIndirect(&lf);
	HFONT OldFont = (HFONT)SelectObject(PD->m_pd.hDC, HeaderFont);
	SetBkMode(PD->m_pd.hDC, TRANSPARENT);
	SetTextColor(PD->m_pd.hDC, 0x000000);
	SetTextAlign (PD->m_pd.hDC, TA_TOP|TA_LEFT|TA_NOUPDATECP);

	SetTextColor (pMemDC->m_hDC, 0x000000);
	lf.lfHeight = -MulDiv(10, GetDeviceCaps(pMemDC->m_hDC, LOGPIXELSY), 72);
	lf.lfWeight = FW_BOLD;
	HFONT CatalogFont = CreateFontIndirect(&lf);
	HFONT OldMemFont = (HFONT)SelectObject(pMemDC->m_hDC, CatalogFont);
	HPEN hpOld = (HPEN)SelectObject(pMemDC->m_hDC,(HPEN)GetStockObject(BLACK_PEN));

	for (UINT nCurPage = nStartPage; nCurPage != nEndPage; nCurPage += nStep)
	{
		// write current page
		TCHAR szBuf[80];
		wsprintf(szBuf, strTemp, nCurPage);
		dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_PAGENUM, szBuf);

		// attempt to start the current page
		if (StartPage(PD->m_pd.hDC) < 0)
		{
			bError = TRUE;
			break;
		}

		int printed = 0;
		// page successfully started, so now render the page
		for (int r = 0; r < rows; r++)
		for (int c = 0; c < cols; c++)
		{
			if (node == NULL) continue;
			printed++;
			glDepthFunc(GL_LEQUAL);
			glClearColor(1,1,1,1); 
			glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
			glEnable(GL_COLOR_MATERIAL);
			glDisable(GL_DITHER);
			glShadeModel(GL_FLAT);

			lcSetColor(lcGetActiveProject()->GetCurrentColor());

//			dlgPrintStatus.SetDlgItemText(AFX_IDC_PRINT_DOCNAME, node->name);
			node = node->next;
			PieceInfo* pInfo = pLib->mPieces[node->actual];
			pInfo->ZoomExtents(30.0f, (float)aspect);

			float pos[4] = { 0, 0, 10, 0 };
			glLightfv(GL_LIGHT0, GL_POSITION, pos);

			glEnable(GL_LIGHTING);
			glEnable(GL_LIGHT0);
			glEnable(GL_DEPTH_TEST);

			FillRect(pMemDC->m_hDC, CRect(0,h,w,0), (HBRUSH)GetStockObject(WHITE_BRUSH));
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			pInfo->RenderPiece(lcGetActiveProject()->GetCurrentColor());
			glFlush();

			TextOut (pMemDC->m_hDC, 5, 5, pInfo->m_strDescription, strlen(pInfo->m_strDescription));
//			BitBlt(PD->m_pd.hDC, rectDraw.left+(w*c), rectDraw.top+(h*r), w, h, pMemDC->m_hDC, 0, 0, SRCCOPY);

			LPBITMAPINFOHEADER lpbi[1];
			lpbi[0] = (LPBITMAPINFOHEADER)GlobalLock(MakeDib(hBm, 24));
			BITMAPINFO bi;
			ZeroMemory(&bi, sizeof(BITMAPINFO));
			memcpy (&bi.bmiHeader, lpbi[0], sizeof(BITMAPINFOHEADER));
			SetStretchBltMode(PD->m_pd.hDC, COLORONCOLOR);
			StretchDIBits(PD->m_pd.hDC, rectDraw.left+(w*c), rectDraw.top+(h*r), 
				w, h, 0, 0, w, h, (LPBYTE) lpbi[0] + lpbi[0]->biSize + lpbi[0]->biClrUsed * sizeof(RGBQUAD),
				&bi, DIB_RGB_COLORS, SRCCOPY);
			if (lpbi[0]) GlobalFreePtr(lpbi[0]);
		}

		DWORD dwPrint = theApp.GetProfileInt("Settings","Print", PRINT_NUMBERS|PRINT_BORDER);
		if (dwPrint & PRINT_BORDER)
		for (int r = 0; r < rows; r++)
		for (int c = 0; c < cols; c++)
		{
			if (printed == 0) continue;
			printed--;
			if (r == 0)
			{
				MoveToEx(PD->m_pd.hDC, rectDraw.left+(w*c), rectDraw.top+(h*r), NULL);
				LineTo(PD->m_pd.hDC, rectDraw.left+(w*(c+1)), rectDraw.top+(h*r));
			}
			if (c == 0)
			{
				MoveToEx(PD->m_pd.hDC, rectDraw.left+(w*c), rectDraw.top+(h*r), NULL);
				LineTo(PD->m_pd.hDC, rectDraw.left+(w*c), rectDraw.top+(h*(r+1)));
			}
			
			MoveToEx(PD->m_pd.hDC, rectDraw.left+(w*(c+1)), rectDraw.top+(h*r), NULL);
			LineTo(PD->m_pd.hDC, rectDraw.left+(w*(c+1)), rectDraw.top+(h*(r+1)));
			MoveToEx(PD->m_pd.hDC, rectDraw.left+(w*c), rectDraw.top+(h*(r+1)), NULL);
			LineTo(PD->m_pd.hDC, rectDraw.left+(w*(c+1)), rectDraw.top+(h*(r+1)));
		}

		CRect r2 = rectDraw;
		r2.top -= GetDeviceCaps(PD->m_pd.hDC, LOGPIXELSY)*theApp.GetProfileInt("Default","Margin Top", 50)/200;
		r2.bottom += GetDeviceCaps(PD->m_pd.hDC, LOGPIXELSY)*theApp.GetProfileInt("Default","Margin Bottom", 50)/200;
		pView->PrintHeader(FALSE, PD->m_pd.hDC, r2, nCurPage, nEndPage, TRUE);
		pView->PrintHeader(TRUE, PD->m_pd.hDC, r2, nCurPage, nEndPage, TRUE);

		if (EndPage(PD->m_pd.hDC) < 0 || !_AfxAbortProc(PD->m_pd.hDC, 0))
		{
			bError = TRUE;
			break;
		}
	}

	SelectObject(pMemDC->m_hDC, hpOld);
	SelectObject(PD->m_pd.hDC, OldFont);
	DeleteObject(HeaderFont);
	SelectObject(pMemDC->m_hDC, OldMemFont);
	DeleteObject(CatalogFont);

	node = start.next;
	while (node)
	{
		previous = node;
		node = node->next;
		free(previous);
	}

	GL_EnableVertexBufferObject();
	wglMakeCurrent(NULL, NULL);
	wglDeleteContext(hmemrc);
	SelectObject(pMemDC->GetSafeHdc(), hBmOld);
	DeleteObject(hBm);
	delete pMemDC;

	// cleanup document printing process
	if (!bError)
		EndDoc(PD->m_pd.hDC);
	else
		AbortDoc(PD->m_pd.hDC);

	pParent->EnableWindow();
	dlgPrintStatus.DestroyWindow();

    if (PD != NULL && PD->m_pd.hDC != NULL)
    {
        ::DeleteDC(PD->m_pd.hDC);
        PD->m_pd.hDC = NULL;
    }
    delete PD;
}
Example #19
0
/* GetWindowLong(hwnd, 4) must be available for use */
void WDPROC
DumpPrinter(HWND hwnd, LPSTR szAppName, LPSTR szFileName)
{
    HDC printer;
    PRINTDLG pd;
    GP_PRINT pr;
    DOCINFO di;
    char *buf;
    WORD *bufcount;
    int count;
    FILE *f;
    long lsize;
    long ldone;
    char pcdone[10];

    memset(&pd, 0, sizeof(PRINTDLG));
    pd.lStructSize = sizeof(PRINTDLG);
    pd.hwndOwner = hwnd;
    pd.Flags = PD_PRINTSETUP | PD_RETURNDC;

    if ((f = fopen(szFileName, "rb")) == (FILE *)NULL)
	return;
    fseek(f, 0L, SEEK_END);
    lsize = ftell(f);
    if (lsize <= 0)
	lsize = 1;
    fseek(f, 0L, SEEK_SET);
    ldone = 0;

    if (PrintDlg(&pd)) {
	printer = pd.hDC;
	if (printer != (HDC)NULL) {
	    pr.hdcPrn = printer;
	    SetWindowLong(hwnd, 4, (LONG)((GP_LPPRINT)&pr));
	    PrintRegister((GP_LPPRINT)&pr);
	    if ( (buf = malloc(4096+2)) != (char *)NULL ) {
	    	bufcount = (WORD *)buf;
		EnableWindow(hwnd,FALSE);
		pr.bUserAbort = FALSE;
/* is parent set correctly */
		pr.hDlgPrint = CreateDialogParam(hdllInstance,
						 "CancelDlgBox",
						 hwnd, PrintDlgProc,
						 (LPARAM) szAppName);
		SetAbortProc(printer, PrintAbortProc);
		di.cbSize = sizeof(DOCINFO);
		di.lpszDocName = szAppName;
		di.lpszOutput = NULL;
		if (StartDoc(printer, &di) > 0) {
		    while ( pr.hDlgPrint && !pr.bUserAbort
			    && (count = fread(buf+2, 1, 4096, f)) != 0 ) {
			*bufcount = count;
			Escape(printer, PASSTHROUGH, count+2, (LPSTR)buf, NULL);
	    		ldone += count;
	    		sprintf(pcdone, "%d%% done",
				(int) (ldone * 100 / lsize));
	    		SetWindowText(GetDlgItem(pr.hDlgPrint, CANCEL_PCDONE),
				      pcdone);
			if (pr.bUserAbort)
			    AbortDoc(printer);
			else
			    EndDoc(printer);
		    }
		    if (!pr.bUserAbort) {
			EnableWindow(hwnd,TRUE);
			DestroyWindow(pr.hDlgPrint);
		    }
		    free(buf);
		}
	    }
	    DeleteDC(printer);
	    SetWindowLong(hwnd, 4, (LONG)(0L));
	    PrintUnregister((GP_LPPRINT)&pr);
	}
    }
    fclose(f);
}
Example #20
0
/* Open the win_pr2 driver */
static int
win_pr2_open(gx_device * dev)
{
    int code;
    int depth;
    PRINTDLG pd;
    POINT offset;
    POINT size;
    float m[4];
    FILE *pfile;
    DOCINFO docinfo;
    float ratio = 1.0;
    
    win_pr2_copy_check(wdev);

    /* get a HDC for the printer */
    if ((wdev->win32_hdevmode) &&
	(wdev->win32_hdevnames)) {
	/* The user has already had the opportunity to choose the output */
	/* file interactively. Just use the specified parameters. */
	
	LPDEVMODE devmode = (LPDEVMODE) GlobalLock(wdev->win32_hdevmode);
	LPDEVNAMES devnames = (LPDEVNAMES) GlobalLock(wdev->win32_hdevnames);
	
	const char* driver = (char*)(devnames)+(devnames->wDriverOffset);
	const char* device = (char*)(devnames)+(devnames->wDeviceOffset);
	const char* output = (char*)(devnames)+(devnames->wOutputOffset);
	
	wdev->hdcprn = CreateDC(driver, device, output, devmode);
	
	GlobalUnlock(wdev->win32_hdevmode);
	GlobalUnlock(wdev->win32_hdevnames);
	
	if (wdev->hdcprn == NULL) {
	    return gs_error_Fatal;
	}
	
    } else if (!win_pr2_getdc(wdev)) {
	/* couldn't get a printer from -sOutputFile= */
	/* Prompt with dialog box */
	
	LPDEVMODE devmode = NULL;
	memset(&pd, 0, sizeof(pd));
	
	pd.lStructSize = sizeof(pd);
	pd.hwndOwner = PARENT_WINDOW;
	pd.Flags = PD_RETURNDC;
	pd.nMinPage = wdev->doc_page_begin;
	pd.nMaxPage = wdev->doc_page_end;
	pd.nFromPage = wdev->user_page_begin;
	pd.nToPage = wdev->user_page_end;
	pd.nCopies = wdev->user_copies;
	
	if (!PrintDlg(&pd)) {
	    /* device not opened - exit ghostscript */
	    return gs_error_Fatal;	/* exit Ghostscript cleanly */
	}
	
	devmode = GlobalLock(pd.hDevMode);
	win_pr2_update_dev(wdev,devmode);
	GlobalUnlock(pd.hDevMode);
	
	if (wdev->win32_hdevmode)
	    GlobalFree(wdev->win32_hdevmode);
	if (wdev->win32_hdevnames)
	    GlobalFree(wdev->win32_hdevnames);
	
	wdev->hdcprn = pd.hDC;
	wdev->win32_hdevmode = pd.hDevMode;
	wdev->win32_hdevnames = pd.hDevNames;
	
	pd.hDevMode = NULL;
	pd.hDevNames = NULL;
    }
    if (!(GetDeviceCaps(wdev->hdcprn, RASTERCAPS) != RC_DIBTODEV)) {
	errprintf(dev->memory, "Windows printer does not have RC_DIBTODEV\n");
	DeleteDC(wdev->hdcprn);
	return gs_error_limitcheck;
    }
    /* initialise printer, install abort proc */
    wdev->lpfnAbortProc = (DLGPROC) AbortProc2;
    SetAbortProc(wdev->hdcprn, (ABORTPROC) wdev->lpfnAbortProc);

    /*
     * Some versions of the Windows headers include lpszDatatype and fwType,
     * and some don't.  Since we want to set these fields to zero anyway,
     * we just start by zeroing the whole structure.
     */
    memset(&docinfo, 0, sizeof(docinfo));
    docinfo.cbSize = sizeof(docinfo);
    docinfo.lpszDocName = wdev->doc_name;
    /*docinfo.lpszOutput = NULL;*/
    /*docinfo.lpszDatatype = NULL;*/
    /*docinfo.fwType = 0;*/

    if (docinfo.lpszDocName[0] == 0) {
	docinfo.lpszDocName = "Ghostscript output";
    }

    if (StartDoc(wdev->hdcprn, &docinfo) <= 0) {
	errprintf(dev->memory,
                  "Printer StartDoc failed (error %08x)\n", GetLastError());
	DeleteDC(wdev->hdcprn);
	return gs_error_limitcheck;
    }
    
    dev->x_pixels_per_inch = (float)GetDeviceCaps(wdev->hdcprn, LOGPIXELSX);
    dev->y_pixels_per_inch = (float)GetDeviceCaps(wdev->hdcprn, LOGPIXELSY);
    
    wdev->ratio = 1;
    
    if (wdev->max_dpi > 50) {
	
	float dpi_x = dev->x_pixels_per_inch;
	float dpi_y = dev->y_pixels_per_inch;
	
	while ((dev->x_pixels_per_inch > wdev->max_dpi)
	    || (dev->y_pixels_per_inch > wdev->max_dpi)) {
	    ratio += 1.0;
	    wdev->ratio ++;
	    dev->x_pixels_per_inch = dpi_x / ratio;
	    dev->y_pixels_per_inch = dpi_y / ratio;
	}
    }
    
    size.x = GetDeviceCaps(wdev->hdcprn, PHYSICALWIDTH);
    size.y = GetDeviceCaps(wdev->hdcprn, PHYSICALHEIGHT);
    gx_device_set_width_height(dev, (int)(size.x / ratio), (int)(size.y / ratio));
    offset.x = GetDeviceCaps(wdev->hdcprn, PHYSICALOFFSETX);
    offset.y = GetDeviceCaps(wdev->hdcprn, PHYSICALOFFSETY);
    
    /* m[] gives margins in inches */
    m[0] /*left   */ = offset.x / dev->x_pixels_per_inch / ratio;
    m[3] /*top    */ = offset.y / dev->y_pixels_per_inch / ratio;
    m[2] /*right  */ = (size.x - offset.x - GetDeviceCaps(wdev->hdcprn, HORZRES)) / dev->x_pixels_per_inch / ratio;
    m[1] /*bottom */ = (size.y - offset.y - GetDeviceCaps(wdev->hdcprn, VERTRES)) / dev->y_pixels_per_inch / ratio;
    gx_device_set_margins(dev, m, true);
    
    depth = dev->color_info.depth;
    if (depth == 0) {
	/* Set parameters that were unknown before opening device */
	/* Find out if the device supports color */
	/* We recognize 1, 4 (but use only 3), 8 and 24 bit color devices */
	depth = GetDeviceCaps(wdev->hdcprn, PLANES) * GetDeviceCaps(wdev->hdcprn, BITSPIXEL);
    }
    win_pr2_set_bpp(dev, depth);

    /* gdev_prn_open opens a temporary file which we don't want */
    /* so we specify the name now so we can delete it later */
    wdev->fname[0] = '\0';
    pfile = gp_open_scratch_file(dev->memory,
                                 gp_scratch_file_name_prefix,
				 wdev->fname, "wb");
    fclose(pfile);
    code = gdev_prn_open(dev);
    if ((code < 0) && wdev->fname[0])
        unlink(wdev->fname);

    if (!wdev->nocancel) {
	/* inform user of progress with dialog box and allow cancel */
	wdev->lpfnCancelProc = (DLGPROC) CancelDlgProc;
	wdev->hDlgModeless = CreateDialog(phInstance, "CancelDlgBox",
				    PARENT_WINDOW, wdev->lpfnCancelProc);
	ShowWindow(wdev->hDlgModeless, SW_HIDE);
    }
    return code;
};
Example #21
0
BOOL PopPrntPrintFile (HINSTANCE hInst, HWND hwnd, HWND hwndEdit, 
                                                   LPSTR szTitleName)
     {
     static DOCINFO  di = { sizeof (DOCINFO), "", NULL } ;
     static PRINTDLG pd ;
     BOOL            bSuccess ;
     LPCTSTR         pstrBuffer ;
     int             yChar, iCharsPerLine, iLinesPerPage, iTotalLines,
                     iTotalPages, iPage, iLine, iLineNum ;
     TEXTMETRIC      tm ;
     WORD            iColCopy, iNoiColCopy ;

     pd.lStructSize         = sizeof (PRINTDLG) ;
     pd.hwndOwner           = hwnd ;
     pd.hDevMode            = NULL ;
     pd.hDevNames           = NULL ;
     pd.hDC                 = NULL ;
     pd.Flags               = PD_ALLPAGES | PD_COLLATE | PD_RETURNDC ;
     pd.nFromPage           = 0 ;
     pd.nToPage             = 0 ;
     pd.nMinPage            = 0 ;
     pd.nMaxPage            = 0 ;
     pd.nCopies             = 1 ;
     pd.hInstance           = NULL ;
     pd.lCustData           = 0L ;
     pd.lpfnPrintHook       = NULL ;
     pd.lpfnSetupHook       = NULL ;
     pd.lpPrintTemplateName = NULL ;
     pd.lpSetupTemplateName = NULL ;
     pd.hPrintTemplate      = NULL ;
     pd.hSetupTemplate      = NULL ;

     if (!PrintDlg (&pd))
          return TRUE ;

//     iTotalLines = (short) SendMessage (hwndEdit, EM_GETLINECOUNT, 0, 0L) ;
	 iTotalLines = (short)FootyGetLines(activeFootyID);
     
     if (iTotalLines == 0)
          return TRUE ;

     GetTextMetrics (pd.hDC, &tm) ;
     yChar = tm.tmHeight + tm.tmExternalLeading ;

     iCharsPerLine = GetDeviceCaps (pd.hDC, HORZRES) / tm.tmAveCharWidth ;
     iLinesPerPage = GetDeviceCaps (pd.hDC, VERTRES) / yChar ;
     iTotalPages   = (iTotalLines + iLinesPerPage - 1) / iLinesPerPage ;

     EnableWindow (hwnd, FALSE) ;

     bSuccess   = TRUE ;
     bUserAbort = FALSE ;

     hDlgPrint = CreateDialog (hInst, (LPCTSTR) "PrintDlgBox", hwnd, (DLGPROC)PrintDlgProc) ;
     SetDlgItemText (hDlgPrint, IDD_FNAME, szTitleName) ;

     SetAbortProc (pd.hDC, (ABORTPROC)AbortProc) ;

	 di.lpszDocName = szTitleName;

     if (StartDoc (pd.hDC, &di) > 0)
          {
          for (iColCopy = 0 ;
               iColCopy < ((WORD) pd.Flags & PD_COLLATE ? pd.nCopies : 1) ;
               iColCopy++)
               {
               for (iPage = 0 ; iPage < iTotalPages ; iPage++)
                    {
                    for (iNoiColCopy = 0 ;
                         iNoiColCopy < (pd.Flags & PD_COLLATE ? 1 : pd.nCopies) ;
                         iNoiColCopy++)
                         {

                         if (StartPage (pd.hDC) < 0)
                              {
                              bSuccess = FALSE ;
                              break ;
                              }

                         for (iLine = 0 ; iLine < iLinesPerPage ; iLine++)
                              {
                              iLineNum = iLinesPerPage * iPage + iLine ;

                              if (iLineNum >= iTotalLines)
                                   break ;

//                              TextOut (pd.hDC, 0, yChar * iLine, pstrBuffer,
//                                   (int) SendMessage (hwndEdit, EM_GETLINE,
//                                   (WPARAM) iLineNum, (LPARAM) pstrBuffer)) ;
							  pstrBuffer = FootyGetLineData(activeFootyID, iLineNum+1);
							  TextOut(pd.hDC, 0, yChar * iLine, pstrBuffer, 
								  FootyGetLineLen(activeFootyID, iLineNum+1));
                              }

                         if (EndPage (pd.hDC) < 0)
                              {
                              bSuccess = FALSE ;
                              break ;
                              }

                         if (bUserAbort)
                              break ;
                         }

                    if (!bSuccess || bUserAbort)
                         break ;
                    }

               if (!bSuccess || bUserAbort)
                    break ;
               }
          }
     else
          bSuccess = FALSE ;

     if (bSuccess)
          EndDoc (pd.hDC) ;

     if (!bUserAbort)
          {
          EnableWindow (hwnd, TRUE) ;
          DestroyWindow (hDlgPrint) ;
          }

     DeleteDC (pd.hDC) ;

     return bSuccess && !bUserAbort ;
     }
Example #22
0
/* GetWindowLong(hwnd, 4) must be available for use */
void WDPROC
DumpPrinter(HWND hwnd, LPSTR szAppName, LPSTR szFileName)
{
	HDC printer;
	PRINTDLG pd;
	/* FIXME: share these with CopyPrint */
	static DEVNAMES * pDevNames = NULL;
	static DEVMODE * pDevMode = NULL;
	LPCTSTR szDriver, szDevice, szOutput;
	GP_PRINT pr;
	DOCINFO di;
	char *buf;
	WORD *bufcount;
	int count;
	FILE *f;
	long lsize;
	long ldone;
	char pcdone[10];

	if ((f = fopen(szFileName, "rb")) == NULL)
		return;
	fseek(f, 0L, SEEK_END);
	lsize = ftell(f);
	if (lsize <= 0)
		lsize = 1;
	fseek(f, 0L, SEEK_SET);
	ldone = 0;

	/* Print Setup Dialog */

	/* See http://support.microsoft.com/kb/240082 */
	memset(&pd, 0, sizeof(pd));
	pd.lStructSize = sizeof(pd);
	pd.hwndOwner = hwnd;
	pd.Flags = PD_PRINTSETUP;
	pd.hDevNames = pDevNames;
	pd.hDevMode = pDevMode;

	if (PrintDlg(&pd)) {
		pDevNames = (DEVNAMES *) GlobalLock(pd.hDevNames);
		pDevMode = (DEVMODE *) GlobalLock(pd.hDevMode);

		szDriver = (LPCTSTR)pDevNames + pDevNames->wDriverOffset;
		szDevice = (LPCTSTR)pDevNames + pDevNames->wDeviceOffset;
		szOutput = (LPCTSTR)pDevNames + pDevNames->wOutputOffset;

		printer = CreateDC(szDriver, szDevice, szOutput, pDevMode);

		GlobalUnlock(pd.hDevMode);
		GlobalUnlock(pd.hDevNames);

		/* We no longer free these structures, but preserve them for the next time
		GlobalFree(pd.hDevMode);
		GlobalFree(pd.hDevNames);
		*/

		if (printer == NULL)
			return;	/* abort */

		pr.hdcPrn = printer;
		SetWindowLongPtr(hwnd, 4, (LONG_PTR)((GP_LPPRINT)&pr));
		PrintRegister((GP_LPPRINT)&pr);
		if ((buf = malloc(4096 + 2)) != NULL) {
			bufcount = (WORD *)buf;
			EnableWindow(hwnd,FALSE);
			pr.bUserAbort = FALSE;
			pr.hDlgPrint = CreateDialogParam(hdllInstance, "CancelDlgBox",
							 hwnd, PrintDlgProc, (LPARAM)szAppName);
			SetAbortProc(printer, PrintAbortProc);

			memset(&di, 0, sizeof(DOCINFO));
			di.cbSize = sizeof(DOCINFO);
			di.lpszDocName = szAppName;
			if (StartDoc(printer, &di) > 0) {
				while (pr.hDlgPrint && !pr.bUserAbort &&
					   (count = fread(buf + 2, 1, 4096, f)) != 0 ) {
					int ret;
					*bufcount = count;
					ret = Escape(printer, PASSTHROUGH, count + 2, (LPSTR)buf, NULL);
					ldone += count;
					if (ret != SP_ERROR) {
						sprintf(pcdone, "%d%% done", (int)(ldone * 100 / lsize));
						SetWindowText(GetDlgItem(pr.hDlgPrint, CANCEL_PCDONE), pcdone);
					} else {
						SetWindowText(GetDlgItem(pr.hDlgPrint, CANCEL_PCDONE), "Passthrough Error!");
					}
					if (pr.bUserAbort)
						AbortDoc(printer);
					else
						EndDoc(printer);
				}
				if (!pr.bUserAbort) {
					EnableWindow(hwnd, TRUE);
					DestroyWindow(pr.hDlgPrint);
				}
				free(buf);
			}
		}
		DeleteDC(printer);
		SetWindowLong(hwnd, 4, 0L);
		PrintUnregister((GP_LPPRINT)&pr);
	}

	fclose(f);
}
Example #23
0
int Printer_print (void (*draw) (void *boss, Graphics g), void *boss) {
	#if defined (UNIX)
		structMelderFile tempFile = { 0 };
		char tempPath_utf8 [] = "/tmp/picXXXXXX";
		close (mkstemp (tempPath_utf8));
		Melder_pathToFile (Melder_peekUtf8ToWcs (tempPath_utf8), & tempFile);
		thePrinter. graphics = Graphics_create_postscriptjob (& tempFile, thePrinter. resolution,
			thePrinter. spots, thePrinter. paperSize, thePrinter. orientation, thePrinter. magnification);
		if (! thePrinter. graphics) return Melder_error1 (L"Cannot create temporary PostScript file for printing.");
		draw (boss, thePrinter. graphics);
		forget (thePrinter. graphics);
		char command [500];
		sprintf (command, Melder_peekWcsToUtf8 (Site_getPrintCommand ()), tempPath_utf8);
		system (command);
		MelderFile_delete (& tempFile);
	#elif defined (_WIN32)
		int postScriptCode = POSTSCRIPT_PASSTHROUGH;
		DOCINFO docInfo;
		DEVMODE *devMode;
		initPrinter ();
		if (! theWinPrint. hDevMode) {
			memset (& theWinPrint, 0, sizeof (PRINTDLG));
			theWinPrint. lStructSize = sizeof (PRINTDLG);
			theWinPrint. Flags = PD_RETURNDEFAULT;
			if (! PrintDlg (& theWinPrint)) return Melder_error1 (L"Cannot initialize printer.");
		}
		if (Melder_backgrounding) {
			theWinPrint. Flags = PD_RETURNDEFAULT | PD_RETURNDC;
			if (! PrintDlg (& theWinPrint) || theWinPrint. hDC == NULL) {
				return Melder_error1 (L"Cannot print from a script on this computer.");
			}
		} else {
			theWinPrint. Flags &= ~ PD_RETURNDEFAULT;
			theWinPrint. Flags |= PD_RETURNDC;
			if (! PrintDlg (& theWinPrint)) return 1;
		}
		theWinDC = theWinPrint. hDC;
		thePrinter. postScript = thePrinter. allowDirectPostScript &&
			Escape (theWinDC, QUERYESCSUPPORT, sizeof (int), (LPSTR) & postScriptCode, NULL);
		/*
		 * The HP colour inkjet printer returns in dmFields:
		 * 0, 1, 8, 9, 10, 11, 12, 13, 14, 15, 23, 24, 25, 26 = DM_ORIENTATION |
		 *    DM_PAPERSIZE | DM_COPIES | DM_DEFAULTSOURCE | DM_PRINTQUALITY |
		 *    DM_COLOR | DM_DUPLEX | DM_YRESOLUTION | DM_TTOPTION | DM_COLLATE |
		 *    DM_ICMMETHOD | DM_ICMINTENT | DM_MEDIATYPE | DM_DITHERTYPE
		 */
		devMode = * (DEVMODE **) theWinPrint. hDevMode;
		thePrinter. resolution = devMode -> dmFields & DM_YRESOLUTION ? devMode -> dmYResolution :
			devMode -> dmFields & DM_PRINTQUALITY ?
			( devMode -> dmPrintQuality > 0 ? devMode -> dmPrintQuality : 300 ) : 300;
		if (devMode -> dmFields & DM_PAPERWIDTH) {
			thePrinter. paperWidth = devMode -> dmPaperWidth * thePrinter. resolution / 254;
			thePrinter. paperHeight = devMode -> dmPaperLength * thePrinter. resolution / 254;
		} else if (devMode -> dmFields & DM_PAPERSIZE) {
			static struct { float width, height; } sizes [] = { { 0, 0 }, { 8.5, 11 }, { 8.5, 11 }, { 11, 17 },
				{ 17, 11 }, { 8.5, 14 }, { 5.5, 8.5 }, { 7.25, 10.5 }, { 297/25.4, 420/25.4 },
				{ 210/25.4, 297/25.4 }, { 210/25.4, 297/25.4 }, { 148.5/25.4, 210/25.4 },
				{ 250/25.4, 354/25.4 }, { 182/25.4, 257/25.4 }, { 8.5, 13 },
				{ 215/25.4, 275/25.4 }, { 10, 14 }, { 11, 17 }, { 8.5, 11 }, { 3.875, 8.875 },
				{ 4.125, 9.5 }, { 4.5, 10.375 } };
			int paperSize = devMode -> dmPaperSize;
			if (paperSize <= 0 || paperSize > 21) paperSize = 1;
			thePrinter. paperWidth = sizes [paperSize]. width * thePrinter. resolution;
			thePrinter. paperHeight = sizes [paperSize]. height * thePrinter. resolution;
			if (devMode -> dmOrientation == DMORIENT_LANDSCAPE) {
				long dummy = thePrinter. paperWidth;
				thePrinter. paperWidth = thePrinter. paperHeight;
				thePrinter. paperHeight = dummy;
			}
		} else {
			thePrinter. paperWidth = 1000;
			thePrinter. paperHeight = 1000;
		}
		EnableWindow ((HWND) XtWindow (theCurrentPraatApplication -> topShell), FALSE);
		SetAbortProc (theWinDC, AbortFunc);
		memset (& docInfo, 0, sizeof (DOCINFO));
		docInfo. cbSize = sizeof (DOCINFO);
		docInfo. lpszDocName = L"Praatjes";
		docInfo. lpszOutput = NULL;
		if (thePrinter. postScript) {
			StartDoc (theWinDC, & docInfo);
			StartPage (theWinDC);
			initPostScriptPage ();
			thePrinter. graphics = Graphics_create_postscriptprinter ();
			if (! thePrinter. graphics) return Melder_error1 (L"Cannot open printer.");
			draw (boss, thePrinter. graphics);
			forget (thePrinter. graphics);
			exitPostScriptPage ();
			EndPage (theWinDC);
			EndDoc (theWinDC);
		} else {
			StartDoc (theWinDC, & docInfo);
			StartPage (theWinDC);
			thePrinter. graphics = Graphics_create_screenPrinter (NULL, (unsigned long) theWinDC);
			if (! thePrinter. graphics) return Melder_error1 (L"Cannot open printer.");
			draw (boss, thePrinter. graphics);
			forget (thePrinter. graphics);
			if (EndPage (theWinDC) < 0) {
				Melder_error1 (L"Cannot print page.");
			} else {
				EndDoc (theWinDC);
			}
		}
		EnableWindow ((HWND) XtWindow (theCurrentPraatApplication -> topShell), TRUE);
		DeleteDC (theWinDC), theWinDC = NULL;
	#elif defined (macintosh)
		Boolean result;
		initPrinter ();
		if (Melder_backgrounding) {
			PMSessionValidatePageFormat (theMacPrintSession, theMacPageFormat, & result);
			PMSessionValidatePrintSettings (theMacPrintSession, theMacPrintSettings, & result);
		} else {
			Boolean accepted;
			PMSessionPrintDialog (theMacPrintSession, theMacPrintSettings, theMacPageFormat, & accepted);
			if (! accepted) return 1;   /* Normal cancelled return. */
		}
		PMSessionValidatePageFormat (theMacPrintSession, theMacPageFormat, & result);
		PMSessionValidatePrintSettings (theMacPrintSession, theMacPrintSettings, & result);
		PMResolution res;
		PMGetResolution (theMacPageFormat, & res);
		thePrinter. resolution = res. hRes;
		PMGetAdjustedPaperRect (theMacPageFormat, & paperSize);
		thePrinter. paperWidth = paperSize. right - paperSize. left;
		thePrinter. paperHeight = paperSize. bottom - paperSize. top;
		Boolean isPostScriptDriver = FALSE;
		//PMSessionIsDocumentFormatSupported (theMacPrintSession,
		//	kPMDocumentFormatPICTPS, & isPostScriptDriver);
		CFArrayRef supportedFormats;
		PMSessionGetDocumentFormatGeneration (theMacPrintSession, & supportedFormats);
		CFIndex numberOfSupportedFormats = CFArrayGetCount (supportedFormats);
		if (Melder_debug == 21) {
			MelderInfo_open ();
			MelderInfo_writeLine1 (L"Supported document formats:");
		}
		for (CFIndex i = 0; i < numberOfSupportedFormats; i ++) {
			CFStringRef supportedFormat = CFArrayGetValueAtIndex (supportedFormats, i);
			if (CFStringCompare (supportedFormat, kPMDocumentFormatPICTPS, 0) == 0) {
				isPostScriptDriver = TRUE;
			}
			if (Melder_debug == 21) {
				MelderInfo_writeLine3 (Melder_integer (i), L": ",
					Melder_peekUtf8ToWcs (CFStringGetCStringPtr (supportedFormat, kCFStringEncodingUTF8)));
			}
		}
		if (Melder_debug == 21) {
			MelderInfo_close ();
		}
		CFRelease (supportedFormats);
		isPostScriptDriver = FALSE;   // OVERRIDE, because from 10.4 on we have something better: we'll be sending PDF
		thePrinter. postScript = thePrinter. allowDirectPostScript && isPostScriptDriver;
		if (thePrinter. postScript) {
			CFStringRef strings [1];
			strings [0] = kPMGraphicsContextQuickdraw;
			CFArrayRef array = CFArrayCreate (kCFAllocatorDefault, (const void **) strings, 1, & kCFTypeArrayCallBacks);
			OSStatus err = PMSessionSetDocumentFormatGeneration (theMacPrintSession, kPMDocumentFormatPICTPS, array, NULL);
			CFRelease (array);
			if (err != 0) {
				return Melder_error2 (L"PMSessionSetDocumentFormatGeneration: error ", Melder_integer (err));
			}
		}
		PMOrientation orientation;
		PMGetOrientation (theMacPageFormat, & orientation);
		thePrinter. orientation = orientation == kPMLandscape ||
			orientation == kPMReverseLandscape ? kGraphicsPostscript_orientation_LANDSCAPE : kGraphicsPostscript_orientation_PORTRAIT;
		PMSessionBeginDocument (theMacPrintSession, theMacPrintSettings, theMacPageFormat);
		PMSessionBeginPage (theMacPrintSession, theMacPageFormat, NULL);
		PMSessionGetGraphicsContext (theMacPrintSession, kPMGraphicsContextQuickdraw, (void **) & theMacPort);
		/*
		 * On PostScript, the point (0, 0) is the bottom left corner of the paper, which is fine.
		 * On the screen, however, the point (0, 0) is the top left corner of the writable page.
		 * Since we want paper-related margins, not writable-page-related margins,
		 * we require that this point gets the coordinates (250, 258) or so,
		 * so that the top left corner of the paper gets coordinates (0, 0).
		 * The "left" and "top" attributes of rPaper are negative values (e.g. -250 and -258),
		 * so multiply them by -1.
		 *
		 * Under Carbon, the port has to be set inside the page.
		 */
		SetPort (theMacPort);
		if (! thePrinter. postScript) SetOrigin (- paperSize. left, - paperSize. top);
		if (thePrinter. postScript) {
			if (! openPostScript ()) error1 (L"Cannot print PostScript.")
			thePrinter. graphics = Graphics_create_postscriptprinter ();
			if (! thePrinter. graphics) goto end;
			draw (boss, thePrinter. graphics);
			forget (thePrinter. graphics);
			closePostScript ();
		} else {
			thePrinter. graphics = Graphics_create_screenPrinter (NULL, (unsigned long) theMacPort);
			draw (boss, thePrinter. graphics);
			forget (thePrinter. graphics);
		}
	end:
		if (theMacPort) {
			PMSessionEndPage (theMacPrintSession);
			PMSessionEndDocument (theMacPrintSession);
			theMacPort = NULL;
		}
	#endif
	iferror return 0;
	return 1;
}