I have a rather unusual application that isn't working the way I need, and I hope someone here will have some suggestions or at least a direction to investigate.
We have a museum exhibit that has a computer at the entrance driving two small receipt printers. There are two buttons on a console, wired to the left and right buttons of a disemboweled mouse. The two printers and associated buttons are for girls and boys, each button does a random selection from a database of names and prints a small ticket on the appropriate printer with a graphic image, a few words about the exhibit and the randomly chosen name.
Conceptually all is well, but it hangs quite often. I got the project at the last minute, because the original designer got bogged down and couldn't deliver, so the exhibit's author asked me the day before opening, whether I could write something that would work.
I did it in Word, since I am an experienced VBA programmer. Several other avenues I attempted first all lead to dead ends - one couldn't do graphics, another couldn't handle two printers, yet another couldn't change fonts and so on. The problem is that it simply isn't fast enough - Word can only drive one printer at a time and changing the active printer takes a long time. Not by office standards, where a second or two of delay before a printer starts working on your document is not an issue, but here I need more or less instant response. If kids press a button and nothing happens, they press it over and over until something does happen, resulting in maybe half a dozen commands being sent before the printer starts reacting. Sometimes it jams the program completely, since boys and girls will be pressing the two buttons simultaneously and Word locks up, and even when it doesn't jam, the printers then spit out a stream of tickets, making a mess. The kids start squabbling over which ticket is whose, pulling them out of the printers, snarling the paper tape, jamming the printer and generally making a mess of the whole affair, often necessitating the exhibit caretakers having to restart the computer and clear torn bits of paper out the printers.
What I need is some sort of fast programming language that can drive two printers *-simultaneously-*, not the MSOffice claptrap of having to switch the active printer, that can react to both left and right mouse button click events, can print a small graphic image and can print in different font sizes and styles and. I don't need many, but it's not all in one typeface.
Can anyone suggest what I might use for this? I don't even know if it's possible at all under Windows, whether the "single active printer" garbage is an Office artifact, or a Windows restriction. My little Commodore-64 twenty-five years ago had two printers attached to it and drove both simultaneously with no difficulties - it doesn't seem to me it should be such an impossible requirement today.
C++ is one of the most efficient and fastest languages. It is widely used by competitive programmers for its execution speed and Standard Template Libraries(STL). Even though C++ is more popular, it suffers from vulnerabilities like buffer error. C++ executes at more or less the same speed as its predecessor C.
Printer Command Language, more commonly referred to as PCL, is a page description language (PDL) developed by Hewlett-Packard as a printer protocol and has become a de facto industry standard.
C++ is compiled to binaries, and is faster than Java since Java codes must first be interpreted during run-time.
At the professional level, C++ is the far more common language worldwide. As mentioned earlier, many programming opportunities in the workforce require knowledge of C++ for consideration. More applications are written entirely in C++, and it's rare to find a program written in just C.
Being a Python programmer myself, I would use something like MSWinPrint.py, and render the documents directly using Python. It looks like it supports text and images, and you can easily select any printer in the system by name.
You would need to:
Then, you would need to write a program to do the printing. Something like the following.
#python
import sys
import Image, ImageWin
import MSWinPrint
# workaround for PIL namespace change
MSWinPrint.ImageWin = ImageWin
def print_name(name, printer_name):
doc = MSWinPrint.document(printer_name)
doc.begin_document('nametag for %s' % name)
# print the name at position 20,20
text_pos = 20, 20
doc.text(text_pos, name)
# add an image for this person
img_pos = 40, 40
img_size = 100, 100
doc.image(img_pos, get_image(), img_size)
doc.end_document()
def get_image():
image_filename = 'my image.jpg'
return Image.open(image_filename)
if __name__ == '__main__':
name, printer_name = sys.argv[1:]
print_name(name, printer_name)
If you save this as print_tag.py
, then you can execute it with two command line arguments, the name to be printed and the image filename.
print_tag.py Sally "EPSON Artisan 810"
I ran this code and it worked great. I didn't know creating a custom print job could be so easy.
You can of course run the program as often as you like on as many printers as you would like. There's certainly more you can do to customize when an how the print job is run. You could customize the code to always run and interpret the mouse clicks (for that you might need wxPython), or you might have another program that just executes the script.
As other have said, the programming language isn't going to make much difference. However (and this is a BIG however), the print libraries built into most scripting languages, such as VBA and .NET, either only support printing to the system default printer (most common, and cannot be worked around by having two instances open simultaneously, as the system default printer is a global setting) or require you to configure a global variable to specify the active printer (this only affects one process, so could be worked around using two instances).
Instead, you will have to invoke the windows API directly. It most certainly allows printing directly to any printer on the system. Here is an example of how to use the default printer. Note that only one line of code (calling the GetDefaultPrinter
function) ties this to the default printer. Supplying a different printer name to CreateDC
gets you a different printer.
If you instead call the EnumPrinters
function, you can find out ANY or ALL of the printer names, not just the default. Or have the administrator preconfigure the printer names to use in a registry setting or text file.
In any case, you can have device contexts for all printers open simultaneously. Of course, once you have the printer device context, you have to create a print job, send your content, and end the print job. There's a great deal of information available on MSDN.
All the examples are in C, which makes C++ the obvious language for printing to non-default printers, but as long as you know how to call WinAPI functions from your language, you can use it instead. In VBA, that'd require Declare Function XYZ Lib "gdi32" (params here)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With