locked
Creating and printing a document RRS feed

  • Question

  • The purpose is to create a template containing a table with some text given by user and then print it. Intermediate file is not required if it can be done without it.

    I see 2 steps here:

    0) Generating document data

    It can be performed in at least 4 ways:

      0.0) Automating Word for creating table and filling in the fields. COM and Office automation knowledges required, needs more time and resources for quite simple task;

      0.1) Creating an RTF document manually (or not) for further processing with RichTextBox control. Requires less time and resources for programming;

      0.2) Generating an HTML page. Easiest way for making document itself, but I don't know how to print it then.

      0.3) Rendering a table with text into vector image. Average time for coding.

    1) Printing the data

    Terra incognita for me :D I've never made it, so if simple printing of plain text or image doesn't seem to be a heavy task, trying to output something more complicated (RTF/HTML/WMF) can be very difficult for me.

    Can you comment each variant (except Word maybe) and help me how to output prepared data to printer?


    If I fall I will arise on my way to paradise

    • Edited by apixosoft Wednesday, December 10, 2014 7:48 AM
    Wednesday, December 10, 2014 7:45 AM

Answers

  • You can definitely do anything that managed code does in native code as managed code always eventually boils down to calling native APIs.  WebBrowser is actually just an ieframe wrapper for instance; 2a is the native way to do what 2b does. 

    Here are the general sequences for printing depending on how you'll be formatting the content:

    PlainText

    OpenPrinter

    StartDocPrinter

    for each page {

    StartPagePrinter

    WritePrinter

    EndPagePrinter

    }

    EndDocPrinter

    ClosePrinter

    GDI Printing: Sample program linked at url here - http://msdn.microsoft.com/en-us/library/windows/desktop/gg263344(v=vs.85).aspx

    CreateDC //Document created and printer opened in one call

    for each page {

    StartPage

    //Any GDI drawing functions you want; PrintWindow to tell a window to just render its contents to the page

    EndPage

    }

    DeleteDC //Document ends at this point and printer is closed

    Print Ticket API / Print Document API

    CoCreateInstance for IPrintDocumentPackageTargetFactory or PTOpenProviderEx

    IPrintDocumentPackageTargetFactory->CreateDocumentPackageTargetForPrintJob

    //All COM Based - see making an XPS document as it uses the same API at this point


    WinSDK Support Team Blog: http://blogs.msdn.com/b/winsdk/


    Friday, December 12, 2014 2:08 PM

All replies

  • There are many other ways you could send the data to the printer besides those that you mentioned.

    0.1) Printing from a RichTextBox control is covered here: http://msdn.microsoft.com/en-us/library/aa970917(v=vs.110).aspx.

    0.2a) Assuming you already have the HTML open in Internet Explorer, send the desired print or print preview command to it via  IOleCommandTarget::Exec. 

    0.2b) Assuming that you're using managed code, use a WebBrowserControl.  The navigate method will cause it to load a specified html file, and you can then either call Print(), ShowPrintDialog(), or ShowPrintPreview().

    0.3) For GDI rendering, CreateDC can open a printer for a print job directly.  You can then render to the DC as you normally would.  If you prefer, you can also format as an XpsDocument object and then print it that way. 


    WinSDK Support Team Blog: http://blogs.msdn.com/b/winsdk/

    Wednesday, December 10, 2014 5:24 PM
  • 0.1) The sample that you gave to me is for .Net FW, not WinAPI (sorry for my miss). Anyway, I think in my case RichTextBox also will be able to print its contents using API calls and messages :)
    BTW, can I format text and create tables directly in RTB?

    0.2a) So I cant create a temporary .htm, then ShellExecute() it and send printing command to it? Seems quite easy comparing to other ways ☺

    0.2b) No, I'm using only native code :)
    0.3) This way seems to be quite easy to, but I have few questions:
     • correct API calls order for opening printer, drawing and printing itself,
     • I can suppose how to scale text that it looks like after .doc/.htm printing, but how will I scale lines representing table borders?
    If you have an example of printing such data or something like this, I would like to see it/

    Thanks in advance!


    If I fall I will arise on my way to paradise

    Friday, December 12, 2014 1:55 PM
  • You can definitely do anything that managed code does in native code as managed code always eventually boils down to calling native APIs.  WebBrowser is actually just an ieframe wrapper for instance; 2a is the native way to do what 2b does. 

    Here are the general sequences for printing depending on how you'll be formatting the content:

    PlainText

    OpenPrinter

    StartDocPrinter

    for each page {

    StartPagePrinter

    WritePrinter

    EndPagePrinter

    }

    EndDocPrinter

    ClosePrinter

    GDI Printing: Sample program linked at url here - http://msdn.microsoft.com/en-us/library/windows/desktop/gg263344(v=vs.85).aspx

    CreateDC //Document created and printer opened in one call

    for each page {

    StartPage

    //Any GDI drawing functions you want; PrintWindow to tell a window to just render its contents to the page

    EndPage

    }

    DeleteDC //Document ends at this point and printer is closed

    Print Ticket API / Print Document API

    CoCreateInstance for IPrintDocumentPackageTargetFactory or PTOpenProviderEx

    IPrintDocumentPackageTargetFactory->CreateDocumentPackageTargetForPrintJob

    //All COM Based - see making an XPS document as it uses the same API at this point


    WinSDK Support Team Blog: http://blogs.msdn.com/b/winsdk/


    Friday, December 12, 2014 2:08 PM
  • I assume that COM-based things are difficult for me, so I will use it only if I'll be unsuccessful with something more simpler :)

    As far as I know, PrintWindow will pring its contents as bitmap which means that text won't be smooth as like on document printing, so I will draw it in memory DC.

    Thank you very much! Hope I won't face many difficulties and bother you ☺


    If I fall I will arise on my way to paradise

    Friday, December 12, 2014 2:13 PM
  • 0.2a) Assuming you already have the HTML open in Internet Explorer, send the desired print or print preview command to it via  IOleCommandTarget::Exec.

    Hello again!
    I'm sorry but I'm OLE & COM noob ☺ So I can't even imagine where from should I call this method and which code will precede that call :( Reading of MSDN article around IOleCommandTarget::Exec didn't help, and I didn't find any information how to use it (I found only something about using it from IE plugins).

    Could you show some sample code how can I print web-pape opened by me in IE from my program?


    If I fall I will arise on my way to paradise

    Thursday, December 18, 2014 6:23 AM
  • Hello apixosoft,

    If you want some code sample, you coudl post a code sample request to:

    http://code.msdn.microsoft.com/windowsapps/site/requests

    And i would mark a reply from Chris Lewis since i think it is helpful from this issue, if you think it is not helpful, please unmark it.

    Thanks for your understanding and support.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, December 23, 2014 9:07 AM
  • Thank you for anwser!
    I decided to use this way but faced some troubles. Here is my code for calculating scale factors and setting font parameters:

    float fBPI=dm->dmPrintQuality,fTextScale=fBPI/72.f,fLineScale=fBPI/25.4f;
    …
    HFONT hFont=CreateFont(fTextScale*14,0,0,0,0,0,0,0,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS,0,PROOF_QUALITY,VARIABLE_PITCH,"Times New Roman");

    dm is of DEVMODE type received from PRINTDLG structure. Questions are:

    0) how to make a correct conversion from DPIs to mm? AFAIK 1 in=25.4 mm, so I think my calcs are correct,

    1) what is character unit size? In MS sample it is DPI/96, in their article about page units it is DPI/72. Who's right? :)

    2) how to choose Times New Roman font? My sample chooses something like Tahoma regardless of my experiments with flags. What's wrong?

    WBR, me ☺


    If I fall I will arise on my way to paradise


    • Edited by apixosoft Thursday, December 25, 2014 7:20 AM
    Wednesday, December 24, 2014 8:08 AM
  • Small update: problem 2 fixed, I was a bit unnattentive and have forgot that I've commented SelectObject() call for created font. But now I have another trouble.

    When drawing multiline text with DrawText, I point containing rectangle located inside drawn table. When I draw text with DrawText(hDC,szBuf,-1,&r,DT_TOP|DT_WORDBREAK|DT_NOCLIP), its 1st line is drawn upon table line (top border of rectangle). Why is it so? Have no idea how to fix it.


    If I fall I will arise on my way to paradise


    • Edited by apixosoft Thursday, December 25, 2014 7:30 AM
    Thursday, December 25, 2014 7:27 AM
  • Hello again! There is a new trouble =(

    Previously I was printnig in XPS document, and it worked fine. But then I tried to print to a real printer and got an error. Well, it is not error I have in my code — no functions returning any error code present. CreateDC(), StartDoc(), StartPage() etc. are finishing successfully, but there is a status message in print manager window that indicates an error in sent document.

    Here is my code. What's wrong there? I checked returns of functions but didn't find any problems.

    P.S. How to add attaches here?


    If I fall I will arise on my way to paradise

    Wednesday, February 4, 2015 7:38 AM