none
PrintDocument: Hooking into the "Print" event RRS feed

  • Question

  • I have this code...

                using (PrintDocument printDoc = new PrintDocument())
                {
                    printDoc.PrinterSettings.PrinterName = printDialog1.PrinterSettings.PrinterName;
                    printDoc.DocumentName = "Label";
                    printDoc.PrinterSettings = printDialog1.PrinterSettings;
    
                    PaperSize size = getPaperSize();
                    printDoc.DefaultPageSettings.PaperSize = new PaperSize("Label", size.Width, size.Height);
    
                    PrintPreviewDialog ppd = new PrintPreviewDialog();
    
                    printDoc.PrintPage += printPage;
                    printDoc.EndPrint += DonePrinting;
                    ppd.Document = printDoc;
                    ppd.ShowDialog();
                }

    This works amazingly, but I have a problem.

    I need to log the print event to a database.

    If I add the logging to the DonePrinting event (as shown), it logs when the preview is generated, AND when the job is sent to the printer (print button on the preview screen). 

    If I add it to this routine, it logs when the preview dialog is opened, whether or not it gets printed.

    What I need is to hook into the actual printing of the label and log it ONLY if printed on the printer.

    I tried to see if the EndPrint event had any indication if it was sending to a printer or a bitmap, but alas.


    I'd rather live with false hope than with false despair.

    Tuesday, August 20, 2019 1:14 AM

Answers

  • It's a tough situation.  Windows does its best to abstract away all of that, so the application doesn't have to worry about whether it is a real device or a preview.

    Have you tried looking at the PrintDocument.PrintSettings after the dialog returns?  I don't know that it fills in the printer name, but it's worth a quick check.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    • Marked as answer by Bryan Valencia Thursday, August 29, 2019 5:46 AM
    Wednesday, August 28, 2019 6:43 PM
  •         private void DonePrinting(object sender, PrintEventArgs e)
            {
                MessageBox.Show(e.PrintAction.ToString(), "Done Printing.");
                // this is PrintToPreview when printing to preview and PrintToPrinter - problem solved!
            }
    Looks like the EndPrint handler gets the data I need.  Thanks!

    I'd rather live with false hope than with false despair.

    • Marked as answer by Bryan Valencia Thursday, August 29, 2019 5:46 AM
    Thursday, August 29, 2019 5:46 AM

All replies

  • Hi Bryan,

    Thank you for posting here.

    >>I need to log the print event to a database.

    Could you have a specific database? If so, please provided about it. If not, I suggest that you could create a database, which contains the data you want to get.

    I hope that you could provide it, which will help us to solve your problem better.

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, August 20, 2019 5:37 AM
    Moderator
  • That's a baffling response.

    There is nothing wrong with the database.  It works perfectly.  I have a subroutine that logs the fact that the user printed.

    The problem is that the PrintDocument.EndPrint event fires when the document is printed to paper AND when the document is rendered to the preview (resulting in 2 entries in my database).

    Hooking into the opening of the PrintPreviewDialog logs the print job even if the user never prints to paper.  The whole point of preview is to inspect it and see if it looks right.

    What I need is a way to tell if the print job is actually going to the printer.  The only way I can think of is to pop a "Did This Print Correctly?" dialog and log it if the user clicks YES.

    But seriously.  There needs to be a way to tell if the preview dialog is rendering to the printer.


    I'd rather live with false hope than with false despair.

    Tuesday, August 20, 2019 2:52 PM
  • Hi Bryan,

    Thanks for the feedback.

    Based on my test, I could not reproduce your problem. Therefore, could you provide a completed code to reproduce your problem? It will be better for us to solve your problem better.

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, August 21, 2019 6:23 AM
    Moderator
  • You asked for it...

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Drawing.Printing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace PrinterIssue
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Button1_Click(object sender, EventArgs e)
            {
                using (PrintDocument PrintDoc = new PrintDocument())
                using (PrintPreviewDialog ppd = new PrintPreviewDialog())
                {
                    PrintDoc.PrintPage += Print;
                    PrintDoc.EndPrint += DonePrinting;
                    ppd.Document = PrintDoc;
                    ppd.ShowDialog(this);
                }
            }
    
            private void DonePrinting(object sender, PrintEventArgs e)
            {
                MessageBox.Show("I would be logging data to the database now, except I am also popping up when the preview dialog darws me.", "Done Printing.");
            }
    
            private void Print(object sender, PrintPageEventArgs e)
            {
                using (Brush textbrush = new SolidBrush(Color.Black))
                using (Font font = new Font("Calibri", 16f))
                {
                    e.Graphics.DrawString("Hi.", font, textbrush, 0f, 0f);
                }
            }
        }
    }
    
    Note that "DonePrinting" has no way of knowing if he's printing a preview or a printer page.

    This code will pop the dialog twice (once when the preview comes up, and once if the user clicks the print icon).

    My question is: how can I tell the difference, as I don't care to log it if they preview without printing.


    I'd rather live with false hope than with false despair.

    Wednesday, August 28, 2019 6:30 PM
  • It's a tough situation.  Windows does its best to abstract away all of that, so the application doesn't have to worry about whether it is a real device or a preview.

    Have you tried looking at the PrintDocument.PrintSettings after the dialog returns?  I don't know that it fills in the printer name, but it's worth a quick check.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    • Marked as answer by Bryan Valencia Thursday, August 29, 2019 5:46 AM
    Wednesday, August 28, 2019 6:43 PM
  •         private void DonePrinting(object sender, PrintEventArgs e)
            {
                MessageBox.Show(e.PrintAction.ToString(), "Done Printing.");
                // this is PrintToPreview when printing to preview and PrintToPrinter - problem solved!
            }
    Looks like the EndPrint handler gets the data I need.  Thanks!

    I'd rather live with false hope than with false despair.

    • Marked as answer by Bryan Valencia Thursday, August 29, 2019 5:46 AM
    Thursday, August 29, 2019 5:46 AM