Question :
I have to use a dot matrix printer (writing ASCII) on my program . The reason why I am using dot matrix printer is that program has to print a couple of line then wait for the next step. I have already access to printer with using BIOS (INT 17h) interrupt. Builder does not allow me to use DOS or BIOS interrupts. That is why I wrote a program on BC5 and I am calling it from Builder (using: ShellExcuteEx). It is working but I am wondering if you could suggest any other way to do the same job.
Answer :
Here is the skeleton of a function which can print text directly on any Windows printer (if it can print text, which many low-cost ink-jet "Windows only" printers can't do). It uses Windows API funcion calls and structures. With this code, you can send only text (with line feeds), or escape codes if the printer supports them. Note: The code almost functions as-is (if I have not made any mistakes when cutting-and-pasting), except for two undeclared boolean variables used as flags (add them as you need); and throws exceptions when any error occurs, but only with a constant string to illustrate what error has raised. You can substitute them for VCL exceptions or any error-handling mechanism you want. (Do use error handling when printing; it's one of the most error-prone areas of any program.)
Code:
// Printer port name or network printer name (e.g.: "\\SERVER\LASER")
String printerPort = "LPT1:";
HANDLE printerHandle = 0;
// Neccesary for network printers; Windows 9x ignores last member,
// but it's neccesary for NT
PRINTER_DEFAULTS printerOptions;
printerOptions.pDatatype = "RAW";
printerOptions.pDevMode = NULL;
printerOptions.DesiredAccess = PRINTER_ACCESS_USE;
if (!OpenPrinter(printerHandle.c_str(), &printerHandle, &printerOptions))
{
throw "Error when opening printer port";
}
DOC_INFO_1 docInfo;
docInfo.pDocName = "Document name";
docInfo.pOutputFile = NULL;
docInfo.pDatatype = "RAW";
if (!StartDocPrinter(printerHandle, 1, (LPBYTE)&docInfo)) {
throw "Error when starting printing";
}
if (!StartPagePrinter(printerHandle)) {
throw "Error when starting a new page";
}
// Main printing loop (assumed finishedPrinting is a boolean flag
// which becomes true when all the text is printed)
while (!finishedPrinting) {
// Print a sample line
char* lineToPrint = "This is a sample line printed used Windows API
calls\n";
DWORD numBytesWritten;
BOOL correct = WritePrinter(printerHandle, (LPVOID*)lineToPrint,
strlen(lineToPrint), &numBytesWritten);
// Check if line printed OK
if (!correct || numBytesWritten < DWORD(strlen(lineToPrint)))
throw "Error when printing a line";
// When a page is completed (EndPagePrinter sends a form feed):
if (endOfPageReached) {
if (!EndPagePrinter(printerHandle)) {
throw "Error when finishing a page";
}
}
}
if (!EndDocPrinter(printerHandle)) {
throw "Error when finishing printing";
}
ClosePrinter(printerHandle);