C++ Redirect output to a printer or PDF

Please, read the updated version here: http://www.matejtomcik.com/Public/Projects/CPPPrinterStream

I have been wondering quite a long time if there is a way how one can redirect C++ cout to a printer. STD does not support such a method so if you need this behavior, you have to create your own output stream just like I did. And I want to share my source code with you, so start by downloading printerstream class.

This small handy template class is an extension of a standard output stream (std::basic_ostream) class which provides the functionality to output whatever you want to a printer instead of console window. To make it work, first download the printerstream class. Unzip and add printerstream.h and printerstream.cpp to your project. Note that printerstream is implemented for a Windows platform only. Then you can create an instance of the printerstream class in several ways:

  • printerstream<char> output(bool useDefaultPrinter = false);
    will create an instance of the printerstream asking user to choose the printer using standard print dialog. First parameter to this constructor is omited, but if you set it to true, the default printer will be choosen instead of showing print dialog.
  • printerstream<char> output(“PDFCreator”);
    will initialize printerstream using the printer specified by its name. To enumerate local printers on your PC call printerstream<char>::enumerate_printers.
  • printerstream<char> output(handle to a drawing context);
    will initialize printerstream using an already open handle to a drawing context (HDC). You can create a HDC using CreateDC function. Thats how the previous constructor creates a handle to the printer.

Once the printerstream object is initialized you have to call begin(const char * documentName = 0) method to start a new document. Without this call the printerstream will ignore any output written to it. This method basically creates a new print job, so if you need to split your report to multiple documents (PDFs for example), call begin everytime you wish to start a new print job. Specifying a document name is optional.

To explicitly finish the print job, call end method. To abort the print job, call abort method. If a previous call to a begin method was made, printerstream will implicitly call end in its destructor finishing the print job and sending it to the printer. It is also possible to set the page margins calling margins method.
REMEMBER: printerstream class translates page size into pixels, so to set margins to a 5% of the document size, you can use this method:

printer.margins(page_margins((printer.page_width() / 100) * 5));

Click “Read more” for an example code.
Čítať ďalej

Reklamy

Interface Flight Gear using .Net and C#

Please, read the updated version here: http://www.matejtomcik.com/Public/Projects/FlightGear

This topic extends the previous post “FlightGear Simulator”. Here, you will learn how to write a C# application to interface Flight Gear simulator. The method is very simple.

As I described in the previous post, Flight Gear can communicate with the outside world using TCP or UDP sockets. To create your application that will intercept the output from Flight Gear, you have to:

  1. Create a protocol definition file to tell Flight Gear that we want it to output it’s internal variables or accept variables to alter the simulation. Such a file looks like this:

    <?xml version="1.0"?>
    <PropertyList>
      <generic>
        <output>
          <line_separator>#</line_separator>
          <var_separator>;</var_separator>
          <chunk>
            <name>altitude-ft</name>
            <type>float</type>
            <format>%f</format>
            <node>/position/altitude-ft</node>
          </chunk>
        </output>
      </generic>
    </PropertyList>

    The output datagram will contain only one variable, which is the altitude in feets. If you add more variables, they will be separated by a semicolon and the datagram will end with # character. For a complete list of available variables to input/output see the Property Tree/Reference. Then you place your xml file in data\Protocol folder.

  2. Create a UDP or TCP server on a localhost and start receiving datagrams. This can be achieved easily with the System.Net.Sockets.UdpClient class. Just choose a port number.
  3. Start the Flight Gear with additional parameters telling it to work with your protocol definition file and do variables input/output from/to the outside world. Such a command looks like this:
    fgfs.exe –fg-root=”..\..\data” –generic=socket,out,10,localhost,1234,udp,myprotocol
    Explanation:

    1. fg-root sets the root directory, this should be the same in most of the installation
    2. generic creates a pipe between Flight Gear and an outside world application. In this example, we told Flight Gear to create a socket output pipe, firing new datagrams 10 times per seconds to an UDP server at localhost port 1234 using myprotocol.xml file definition.
  4. Process the received datagrams according to the protocol definition file.
    Depending on the rate of incoming datagrams you may face a problem if a previously received datagram is not yet processed but another one is being received. So creating a non-blocking receiver is essential.

Čítať ďalej