I need to print documents in a specific order.
To do that,i use shellExecute api to print documents.
Some documents may be quicker to print , so i have to wait for the document to be in the spooler before calling another shellExecute.
For that, i use FindFirstPrinterChangeNotification, waitForSingleObject and FindNextPrinterChangeNotification.
It works fine.
But if the application started by shellExecute is already open, it's possible that it prints on another printer that the windows default printer. (if default printer has been changed )
I could watch all printers, but, i'd prefer to know wich printer uses the started process and watch this printer.
With shellExecuteEx, i can get a handle to the process started by this api.
So, is there a way to know the printer used by default by a process ?
So, is there a way to know the printer used by default by a process?
No there is not. Programs are entitled to use whatever logic they choose to determine their default printer. So in general, you've no way to ask a process which printer it will use, without having more specific knowledge of the process in question.
Related
I need to assign a printer for each of three different printing functions, labels, receipts and "standard" (e.g. A4). I have identified all of the printers available using listbox1.assign(printer.printers) but there doesn't appear to be a way to use this to establish the printer's PrinterIndex. I want to store the printername and index value in a file so that I can use printer.printerindex to assign a printer to each type of print job without asking the user to choose a printer using a dialog.
Am I going about this the wrong way, and if so, could someone please tell me the right way to do it, please? I've not had to use the printers unit directly before.
Save the printer name in the file, not the index.
When you restart the program and read back the printer name. Then loop thru all printers to find which one has the saved name (It could have been removed or renamed) and use that printer.
Working with a Konica Minolta, I am sending PostScript commands to it. Most of the time everything works correctly and I am able to switch trays using the MediaPosition command. The printer has 4 trays and the Paper Tray Settings from the printer display are set to "Letterhead", "Letterhead", "Letterhead" and "Plain".
I am successfully switching between trays using this:
<</ManualFeed false /MediaPosition 0>> setpagedevice
One of the ps files creates a job which prints from the from the third tray, the forth tray and then tries print from the first tray. However, at this point the printer freezes and asks you to put "Plain" paper in Tray 1. I am assuming this happens because the last print came from a "Plain" paper tray but I am just guessing. Going from 3 to 4 works but then to 1 does not.
I have tried to use /MediaType (letterhead) but it seems that this command is ignored as it comes along with some settings of Duplex which are incompatible with it:
<</Duplex true /Tumble false>> setpagedevice
Any idea what is actually causing this problem and even more so, how to fix it so the printer continues without freezing and asking to change the tray paper setting?
I cannot see what this has to do with Ghostscript, where is Ghostscript used in the described process ?
Page device parameters are, to some extent, device dependent and are usually treated as requests. For example you can set /Duplex, and the device will generally ignore it if it does not have a duplexer. (ie the request is ignored).
However, certain page device requests can have other effects, these are documented in Section 6.2.7 Unsatisfied Parameter Requests of the 3rd Edition PostScript Language Reference Manual (p446 in my copy).
The interpreter can respond to such an unsatisfied parameter request in a variety
of ways, such as by ignoring it, raising a PostScript error, or displaying a message
on the front panel of the device requesting intervention by the human operator.
Without seeing the exact PostScript program, it's not possible to tell exactly what's going on, but I would guess that the interpreter thinks, for whatever reason, that it cannot satisfy the request for tray 1 because it's MediaType does not match (it wants Plain and you have defined it as Letterhead). It's likely that switching tray the way you are doing changes the current MediaType (or possibly some other parameter but MediaType makes sense). I imagine that initially the MediaType is not present in the dictionary, so you can change to any other tray. When you change the tray, because you've defined the media type on the control panel, it picks up the new MediaType. When you try to switch back the current MediaType doesn't match the MediaType of the tray you are trying to switch to.
Most likely the reason that adding /MediaType (letterhead) doesn't work is because you say you've defined the tray as containing Letterhead. PostScript is case-sensitive so letterhead is not the same as Letterhead.
Or it could be that the paper tray setting simply isn't the same as the MediaType. I'm afraid that this sort of device-dependency is highly specific to each manufacturer, the only people who can probably tell you what you need to send for certain are the printer manufacturers' own engineers.
I have a software that prints labels. It generates many pages with n columns to be printed in a label printer (commonly Argox or Zebra). I use report builder to do so, meaning I send the jobs through the windows driver and not directly to the printer.
I have this one customer that is having a really hard time printing her labels. The printer pauses for 15-20 seconds between one page and another.
I´ve reviewed each and every configuration I could and did not find anything.
To make my problem worse, my customer uses the Bartender software (wich comes with Argox) and when printing there it has not this delay. Bartender uses the windows driver as well.
Well, from the point of view of my client, the problem is with my software, I don´t blame her.
From my point of view I can´t control such a thing (pause between pages) once I am using the driver.
Am I wrong? Is there anything I could do to avoid such a delay?
Important Info
Argox OS 214 TT - PPLA
Drivers updated to the last version (7.2)
Serial Cable being used
Does the report software you use create ZPL output, or a bitmap? You can check this by setting your printer driver to print to a file. If the file is huge, >1MB, it's probably creating a bitmap and that could take a long time to send to the printer.
Bartender would create ZPL if using internal fonts and barcodes, so the output will be tiny and the printer is optimized to print native ZPL. If your software uses fonts not on the printer (Arial, Times new roman, etc), it will send the label down as a graphic instead of using the printer's built in fonts, which would result in a HUGE file even for a small amount of text. Same thing goes for graphics, inlined vs. recalled graphics
In a Delphi 7 console application, how can I check whether stdin holds a character, without blocking until one is entered?
My plan is that this console program will be executed by a GUI program, and its stdin will be written to by the GUI program.
So I want my console app to periodically check stdin, but I can't find a way of doing this without blocking.
I have looked at this answer, which gets me a stream pointing to stdin, but there's still no way to "peek" as far as I can see.
I think you have already found the right way to read stdin. It is meant to block when there's nothing more to be read.
The standard way to handle this is to use a separate thread to handle the pipe. When it receives new data from stdin it signals this to the processing thread, for example with a message passing mechanism.
Having said all that, if you really want to poll you can call PeekNamedPipe to check if there is data in the pipe.
You could as the other answer says use threads, but even then you might have problems (using the threading method) unless you also investigate overlapped IO.
I normally use overlapped IO with serial ports rather than stdin, where "read a character if one is ready" is commonly needed, and where non-blocking IO is a usual way of working. You should be able to adapt the technique shown here. However, if I was writing an application that was keyboard driven (instead of purely driven by say, a file redirected to standard input) I would let go of StdIN, and use a CRT type unit. So, if you don't mind letting go of StdIn, and simply want to have a keyboard-driven input model, you could look at console based APIs and abandon the very limiting StdIn capabilities. For an example of a "kbhit" function that uses the Win32 Console APIs see here.
There is no other way (as far as i know), as reading from a pipe inside a separate thread. Otherwise as you already have seen, the readfile operation will block. I wrote an example how to do this, an example project is also available: redirect stdoutput
Edit: Well, reading your question another time, i understand that your problem lies within the console program, not the calling application. I wonder what your console application expects, normally a console application knows when it needs input and cannot proceede until the user enters this information. Do you need to check for an exit?
For a Stream if you .Read() the function result is the number of bytes read which will be zero if there was nothing there even if you asked for more. From the Delphi help for Classes.TStream.Read:
Read is used in cases where the number of bytes to read from the stream is not necessarily fixed. It attempts to read up to Count bytes into buffer and returns the number of bytes actually read.
I am writing a program using Delphi 2006 and storing data in XML files and a Firebird database. I create reports using either FastReports, Excel or QuickPDF. I allow my users to package several reports together and be directed to a destination of their choice, whether it is a PDF file, a printer, the screen, or email.
I want my users to be able to configure their printer choices for the reports they send to printers. To do this, I will use the printer dialog to choose a printer and set the properties of that printer. I want to be able to capture those properties and store them so that when they run their package of reports, they will all go to the correct printer using the configurations they have chosen.
I know different printers have different configuration possibilities. For example, one that I use will allow me to choose to print booklet style so you can produce a 5 1/2 X 8 1/2 booklet from a report. It's possible that a user might choose an option like that when they are configuring a report in their package and expect that report to print in that manner. There are probably lots of possibilities that I am not aware of but would like to allow if that is possible. I just don't know how to capture that configuration from the printer dialog, store it in a database and then use that information to configure the printer when it's time to print the report.
How can I translate the information stored in the printer dialog into something I can store (even in a blob) in a database and then use that information to configure the printer?
Thank you for your help.
AFAIK, that isn't possible. The printer setup dialog is standard, but quite often is replaced (or modified) to include additional printer specific setup information (eg., the booklet information you mentioned). Since there's no way for anyone other than the printer driver publisher to know what's there, there's no way to reliably get the information in a generic fashion.
The GetPrinterDataEx() API function Jeroen mentioned won't work, either, as it requires you to know ahead of time the name of the registry key that was used to store information via the SetPrinterDataEx() procedure, and that may or may not have been used by the printer driver. If it was used, you'd have to manually look at the registry to see where the driver publisher decided to store the info; I'd suspect that varies between printer manufacturers as well.
FOLLOWUP: I just ran a quick check and I'm pretty sure the above is correct. If I use the Printer Setup dialog from a Delphi app to access printer settings (for example, the duplex setting before running a report), no changes are written to the registry. However, if I go into the Control Panel Printer applet and change settings there, the registry is updated. This seems to confirm that per-report setting selections made on the fly by the user would be hard to save, as they're probably not accessible anywhere except to the printer driver. Permanent type settings (those made in the control panel applet) are made by the user and the user opts to make them permanent on a system-wide basis, and therefore they're saved to the registry. This seems to preclude saving those types of options on a per-report basis, at least from the printer setup dialog changes.
This is all possible, but for a specific printer on a specific computer. Basically, you ask the printer driver for its custom config data, and store that exactly as is. You can then pass it back later to print with.
Check out the following Windows API functions. If you want C code for this, ask in a comment. Actually, I'll copy a chunk here of the code I use, sorry it isn't translated to Delphi! This is from real working code though, hard fought over. Hopefully it will give you some clues.
bGood = OpenPrinter(pcDeviceName, &hPrinter, NULL);
int sBuffSize = DocumentProperties(hDlg, hPrinter, pcDeviceName, NULL, NULL, 0);
PDEVMODE pxDevMode = (PDEVMODE)malloc(sBuffSize);
gl_memset(pxDevMode, '\0', sBuffSize);
pxDevMode->dmSize = sBuffSize;
DocumentProperties(hDlg, hPrinter, pcDeviceName, pxDevMode, pxDevMode, DM_PROMPT | DM_COPY);
DocumentProperties(hDlg, hPrinter, pcDeviceName, pxDevMode, NULL, DM_COPY);
DocumentProperties(hDlg, hPrinter, pcDeviceName, pxDevMode, pxDevMode, DM_PROMPT | DM_COPY);
DocumentProperties(hDlg, hPrinter, pcDeviceName, pxDevMode, pxDevMode, DM_UPDATE | DM_MODIFY);
ClosePrinter(hPrinter);
I know this should be possible with GetPrinterDataEx, but I could not find information about people having this used.
--jeroen
The documentation for the Windows API PRINTDLGEX Structure might contain some hints. In particular I think the hDevMode handle gives you the bits that are specific to a printer driver, even though they're undocumented. I don't know how you would use this information from Delphi.
It appears that a similar question was answered with information that may solve my problem for me. Thanks for your responses.