Why Migrate from Btrieve to PostgreSQL and other Relational Databases?
Introduction Many independent software vendors (ISV) and corporate users still rely on applications that use a category of database collective called...
3 min read
Oliver Nelson
:
Mar 6, 2017 2:16:00 PM
One of our products, Flex2Crystal, is used extensively by developers to print reports to a wide variety of printers. All manners of printers are used from the diminutive Zebra Label Printer, all the way up to large high end department printers like the Xerox C60 or HP A3 MFP and everything in between.
One of the things we often see as a result of this is problems from developers related to printouts not pulling from the tray (paper source) they expect. This can be really frustrating because Windows defines the paper source in such a way that it SHOULD handle most common printers easily.
Our internal testing has mostly focused on Brother printers since that's what we use in-house. But our findings while researching this problem show that the actual cause of the problem can be found across multiple brands of printers. So no matter what brand of printer or type of printer you're using, it's quite possible that you'll stumble across this problem if you're trying to automate print jobs. That's one of the keys here. In general this problem rears its ugly head when a developer is trying to programmatically select the source tray for a print job. It also tends to happen more often on Terminal Servers, RDP connections and Virtual Machines.
So, now, what is the actual cause of this issue? The problem all comes down to printer manufacturers (and in fact Microsoft as well) not playing nice with the Windows GDI DEVMODE structure. Well, that along with us developers having an idealistic view of the world. In our nice, well defined, logical world of 1s and 0s, if I want my printout to come from the manual tray, I set the paper source to DMBIN_MANUAL (in the case of the direct DEVMODE structure), or PaperSourceKind.Manual (in the case of System.Drawing.Printing) or CrystalDecisions.Shared.PaperSource.Manual in the case of Crystal Reports. All of these are in fact mapping to the same constant: 0x04. They're all the same constant because underneath it all, they're using the Windows DEVMODE structure.
But, as we recently discovered, our nice simple logical conclusion is utterly wrong. To give you just a small example of this, on one of our VMs we use for testing, we have the same printer installed 4 times. It's a Brother MFC-L8850CDW. It has a manual tray (or as Brother refers to it, a "multi-purpose tray"), and a 250-sheet tray below that. There is also an optional 500-sheet tray that can be added on below that. Our printer doesn't even have this optional tray. This is a pretty simple printer, and yet, like I mentioned, we have it installed 4 times, and yet when we query the devices list of trays (using the DeviceCapabilities API call or System.Drawing.Printing.PrinterSettings.PaperSources collection) each and every printer returns a different list of trays!
Even more interesting and worrisome than the wide variety of supported trays for this one printer on this one computer are the varying ways in which the trays are identified. On all of the printers that even list the manual tray (or MP Tray), instead of mapping to DMBIN_MANUAL (0x04), this tray is defined with an ID of 0x0102! All trays starting from 0x0100 and up are considered "User" or "Custom" trays. For one of the printers, Tray 1, which justifiably should be listed as either 0x000F (Automatic) or 0x0001 (Upper), it is instead listed as 0x0101!
So how can you go about finding out what Paper Source IDs are in use on your system or for that matter, your customer's computer? The easiest way that should work on most modern systems is a simple PowerShell script. The following script will output a nicely formatted list that shows the name of each paper source and it's associated ID for each printer. You should be able to paste this script directly into a PowerShell window and run it:
Add-Type -AssemblyName System.Drawing
$printers = [System.Drawing.Printing.PrinterSettings]::InstalledPrinters
$printersettings = New-Object System.Drawing.Printing.PrinterSettings
foreach ($printer in $printers) {
Write-Output "`n";
$printersettings.PrinterName = $printer
Write-Output $printer "------------------------------------------------";
foreach ($source in $printersettings.PaperSources) {
Write-Output ([string]$source.RawKind + " - " + $source.SourceName);
}
}
The implication of unpredictable and non-standard tray numbering is that your application probably needs to make tray selection configurable beyond just the standard paper sources that are defined in Windows. You can't assume that DMBIN_MANUAL will actually be the manual tray on any given printer. It is of course possible to enumerate the available trays for all installed printers programmatically, the code above is doing just this. Unfortunately, from what we've seen of tray configurations, there is NOT a way to use this information to determine which tray is which. The only information about the tray that is readily available is the tray name, and different manufacturers choose wildly different names.
Additionally, if you ever come across a printer that enumerates with no trays that actually does have multiple paper sources, the most likely cause is the printer driver being used. Try changing from a generic driver to a most specific driver and the odds are that all of the installed trays will be seen by the driver.
If you haven't yet tried Flex2Crystal and you'd like more information about upgrading from an old version of Crystal Reports to Flex2Crystal, watch our Flex2Crystal training videos.
Introduction Many independent software vendors (ISV) and corporate users still rely on applications that use a category of database collective called...
COBOL applications are the foundation of numerous essential business functions, especially within the banking, insurance, and government sectors....
Imagine breaking free from the constraints of old, monolithic systems and embracing the agility and innovation of cloud-based solutions.