Link to home
Start Free TrialLog in
Avatar of spetrowitsch
spetrowitsch

asked on

printing on different printers

Hi,


I have to print some TIF-Images on different printers. Which printer I have to use, depends on how full the printer-queue already is. Additionally I have to decide, whether I use the shaft for  DIN A 3 or DIN A 4 paper. And I don´t have to show the printer-options sheet.

So:
1. How to detect, how many pages are to print on a printer?
2. How to tell a printer, which shaft to use?
3. How to print without showing the printer-options sheet?

Please give a detailed answer, some sample code would be great!!
Avatar of Zoppo
Zoppo
Flag of Germany image

Hi spetrowitsch,

1. you can use EnumPrinters()/OpenPrinter() to enumerate through all available printers and then use EnumJobs() (or simplier GetPrinter() with level 2) to determine the number of jobs actually in queue of the printer.

2. The shaft to be used can be specified when creating the printer dc using the DEVMODE's dmDefaultSource member. To recieve available shafts you can use DeviceCapabilities function with the DC_BINS flag.

3. Simply create a printer dc (i.e. with CreateDC()), call StartDoc() and StartPage() angainst this dc, do the outpunt used for printing and call EndPage() and EndDoc() for the dc.

hope that helps,

ZOPPO
Avatar of spetrowitsch
spetrowitsch

ASKER

This question has a deletion request Pending
mistake
Please post an answer, zoppo, if you want to get the points.
This question no longer is pending deletion
ASKER CERTIFIED SOLUTION
Avatar of Zoppo
Zoppo
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks, Zoppo.

Do you know, whether (and how) it´s possible not only to get the number of jobs, but the number of pages of all this jobs?
With EnumJobs() you can recieve an array of PRINT_JOB_x structures (x is 1 or 2, depending on level parameter passed). Both structures have members TotalPages and PagesPrinted. PRINT_JOB_2 also has a member Size which holds the size in bytes of the print job.

hope that helps,

ZOPPO
Call OpenPrinter like this:

if (OpenPrinter((pPrtInfo1 + j)->pName, phPrinter, NULL) == ERROR_SUCCESS)
....


leads to an unchanged phPrinter??

Hi spetrowitsch,

see MSDN about OpenPrinter:

....
Return Values:
If the function succeeds, the return value is a nonzero value.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
....

ERROR_SUCCESS is defined in WINERROR.H as zero, so your call to OpenPrinter is anyhow not successful ... check error code with GetLastError().

ZOPPO
Thanks,


but I tried it first with OpenPrinter((pPrtInfo1 + j)->pName, phPrinter, NULL) != 0, and it always fails, (Error Code 87 - The Parameter is incorrect). But I take the (pPrtInfo1+j)->pName from

EnumPrinters (gdwEnumFlags, NULL, 1, (LPBYTE) pPrtInfo1,
                       dwBytesNeeded, &dwBytesNeeded, &dwPrtRet1)

and phPrinter is defined as:

      LPHANDLE phPrinter;
?????
Hi spetrowitsch,

you'll have to pass a pointer to an existing handle which then will be set, i.e.:

HANDLE hPrinter;
OpenPrinter( (pPrtInfo + j)->pName, &hPrinter, NULL )...

ZOPPO
Thanks, that´s it. I hope, I will not have problems with the CreateDC, StartDoc, etc.pp.
That's fine...

>I hope, I will not have problems with the CreateDC, StartDoc, etc.pp.
feel free to post here further questions if you're having problems with these...

ZOPPO
Hi Zoppo,

I feel free:

1. I used StartDocPrinter, because I wanted to use the Windows-Spooler.
My StartDocPrinter-function-call gives an error back: the handle is invalid.


DOC_INFO_1 docInfo1;

// I´m not sure about pDatatype and pOutputFile, what to put in these parameters??
docInfo1.pDatatype = "raw";
docInfo1.pOutputFile = "WINSPOOL";
docInfo1.pDocName = strDocument;
nPrintJobID = StartDocPrinter(hPrinter, 1, (LPBYTE) &docInfo1);
if (nPrintJobID == 0) { // Error!! }


2. I think, after StartPagePrinter, I have to call WritePrinter:

LPDWORD pcWritten = 0;
WritePrinter(hPrinter, pBuffer, sizeof(pBuffer), pcWritten);

But - how to fill pBuffer with a tif-image, or is it much more complicated to print a tif-file?


3. How to change the shaft during a print-session? (Means, I have to print some DIN A 4 pages, then a DIN A 3, then again some DIN A 4)?? I think I can specify it only at the time of the CreateDC??
Hi spetrowitsch,

sorry for delay but I had some problems to open any EE pages...

1. I think you don't need to do any specific to use the windows-spooler unless you want to use the spooler even if spooling is disabled through the printer's settings. StartDoc() simply starts a new print job via spooler or directly depending on the settings for the printer. I don't know exactly if it's possible to print via spooler if the printer is set to print directly to the port.

2. I even don't think it's a good idea to send the data directly to the printer as 'raw' data, cause you'll then need to implement printer specific code (i.e. initialization codes). Better way would be to let windows create the printer dc and then simply draw the image to the dc. I assume you already have code which allows you to draw the TIF-image to a dc. Simply use CDC::StretchBlt() (or similar command you use to draw image to a window) to draw the image to the printer dc. BTW, you should previously check if the printer supports StretchBlt() somehow like:

if( !(printerDC->GetDeviceCaps( RASTERCAPS ) & RC_STRETCHBLT ) )
{
 AfxMessageBox( "Printer doesn't support printing of stretched bitmaps!" );
 return;
}

3. I think you're right, it's not possible to change shaft without creating a new dc, because the dc's attributes (size, colors, resolution) may change with changing papersize (i.e. my HP Color LaserJet can print color for small papers (DIN A4 format in germany) but not on large papers (DIN A3).

ZOPPO
Thanks, Zoppa, don´t mind because of delay!! It´s not the first time I get answers from you, and I am always very satisfied!!

Your assumption was wrong, I don´t have yet code to draw tif´s to a dc, also I don´t have code to read the tif-header (to determine the size of the tif, whether it´s A4 or A3), and I don´t have code to rotate a tif-image for 90 degrees. If you would have the necessary knowledge, we have to find a way to give you more points, otherwise I will make another question in E.E.
So, if you agree, I'd suggest you to download some code to load/save/draw tif-format images. Only code I know (but I think not a bad one, it supports nearly all image file formats I know) can be found at http://www.paintlib.de

I think it's a outrageous hard peace of work to implement drawing/printing of tif-format by yourself.


BTW, thanks for the compliment       :)

cu,

ZOPPO
Hi Zoppo,


how to use that DeviceCapabilities-function?

With

LPTSTR  pOutput;
DEVMODE devMode;

DeviceCapabilities(strPrinter, strPrinter (or NULL), DC_BINS, pOutput, &devMode)

I get error 87 with one printer (The parameter is incorrect - o.k., but how is it correct?), and error 1114 (A dynamic link library (DLL) initialization routine failed. ????) with the other printer.


Thanks!!
Hi spetrowitsch,

I never used this function, but MSDN say that second parameter passed must be the port's name (i.e. LPT1) and I don't know if this could be NULL.

I would guess that the second error only occurs with network printers. Am I right? If so, this might be solved by passing the port's name correctly too.

BTW, did you see MSDN article 'HOWTO: Determine Available PaperBins with DeviceCapabilities API ID: Q194789'. Although it's for VBasiv I think it might be helpful for you too.

ZOPPO
Hi zoppo,


our company (1 1/4 years old, medicine sector, very interesting tasks in VB, VC, Java (JBuilder), located near Augsburg) is looking for a very good programmer.

Young, but excellent team. Mother company is very successfull noticed in the new market in Frankfurt, and wants to have us also noticed in 1 - 2 years. The company leaders of the mother company planned to give 20 % of the shares of the IPO to our company leader, but he wants to share it even to everybody who works in the company. So maybe the earnings are not too high, but the chance is great.

Hi spetrowitsch,

thanks for offering this, but for some different reasons (which I really can't explain satisfactory in english language, perhaps we can talk german later:) I want to stay here near Munich. My home is about 50 km from munich in the south-east, so I think it's nearly 100 km to Augsburg.

My plans for future are to still work employed somewhere the next one or two years and then I want to try to become self-employed anyhow.

I hope we stay in contact here (or even per eMail, mine is zoppo@cdsgmbh.de), maybe in half a year (or so) anything has changed and I would like to go to Augsburg or anywhere. One could never know...

regards,

have a nice time,

ZOPPO