Click to See Complete Forum and Search --> : Change property of a printer
leojose
November 30th, 2005, 10:37 AM
HI all,
I am looking for a method to change the Page Layout (Landscape or Portrait) property of a printer programmatically. I came across this api DocumentProperties(), but I'm unable to get it to work .i.e. I'm unable to load the DEVMODE structure with values. MSDN has also listed steps to change the printer property, but I think a sample API code will be helpful here.
Thanks.
leojose
November 30th, 2005, 10:50 AM
ok...I got this piece of code from somewhere which seems to run as expected. It sets the DEVMODE structure and exits without error. But when I check the property of the printer, it hasn't changed :( could somebody please verify if this code runs properly on their machines.
If you notice any flaws or errors do let me know
#include "stdafx.h"
#include <windows.h>
LPDEVMODE GetLandscapeDevMode(HWND hWnd, char *pDevice)
{
HANDLE hPrinter;
LPDEVMODE pDevMode;
DWORD dwNeeded, dwRet;
/* Start by opening the printer */
if (!OpenPrinter(pDevice, &hPrinter, NULL))
return NULL;
/*
* Step 1:
* Allocate a buffer of the correct size.
*/
dwNeeded = DocumentProperties(hWnd,
hPrinter, /* Handle to our printer. */
pDevice, /* Name of the printer. */
NULL, /* Asking for size, so */
NULL, /* these are not used. */
0); /* Zero returns buffer size. */
pDevMode = (LPDEVMODE)malloc(dwNeeded);
/*
* Step 2:
* Get the default DevMode for the printer and
* modify it for your needs.
*/
dwRet = DocumentProperties(hWnd,
hPrinter,
pDevice,
pDevMode, /* The address of the buffer to fill. */
NULL, /* Not using the input buffer. */
DM_OUT_BUFFER); /* Have the output buffer filled. */
if (dwRet != IDOK)
{
/* If failure, cleanup and return failure. */
free(pDevMode);
ClosePrinter(hPrinter);
return NULL;
}
/*
* Make changes to the DevMode which are supported.
*/
if (pDevMode->dmFields & DM_ORIENTATION)
{
/* If the printer supports paper orientation, set it.*/
pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
}
/*
* Step 3:
* Merge the new settings with the old.
* This gives the driver an opportunity to update any private
* portions of the DevMode structure.
*/
dwRet = DocumentProperties(hWnd,
hPrinter,
pDevice,
pDevMode, /* Reuse our buffer for output. */
pDevMode, /* Pass the driver our changes. */
DM_IN_BUFFER | /* Commands to Merge our changes and */
DM_OUT_BUFFER); /* write the result. */
/* Finished with the printer */
ClosePrinter(hPrinter);
if (dwRet != IDOK)
{
/* If failure, cleanup and return failure. */
free(pDevMode);
return NULL;
}
/* Return the modified DevMode structure. */
return pDevMode;
}
int main(void)
{
GetLandscapeDevMode(NULL,"Ghostscript PDF");
return 0;
}
leojose
December 2nd, 2005, 03:25 AM
Just had to post this reminder in case somebody can figure out why the above code fails to do what its supposed to do.
Another thing I have come to realize is that even if the property of a printer is set, the application that is open needs to be informed of the change else it will maintain the default settings till it is restarted.
I think PostMessage() will do the trick, but I'm not sure what parameters I must pass to it, especially the third and fourth parameters.
leojose
December 3rd, 2005, 10:34 AM
I am still pursuing this...hopefully I get a solution fast.
Is anybody aware any registry settings that can be modified to change the layout property of a printer?
leojose
December 5th, 2005, 01:40 AM
Ok...I managed to find a way to change the printer settings (layout) on the fly. :) Anybody interested can refer this for more details
Set up/change printer orientation (http://www.codeproject.com/printing/PrinterOrientation.asp?df=100&forumid=235615&select=1296658&msg=1296658#xxxx)
But unfortunately my problem doesn't end here. :sick: Although I change the printer settings, it doesn't seem to affect some 'open' applications. For e.g. if I have IE running and and printer settings are changed, IE keeps printing in the old format till it is re-started (unlike MS-Word which auto-updates its database on the fly). I used SendMessage(), PostMessage()...etc...but in vain. maybe I'm not sending the correct parameters.
Can somebody help me out here?
How do I inform an open application that a particular parameter of the printer has changed and it must update it in its database?
Thanks
leojose
December 5th, 2005, 08:06 AM
Needless to say...I have managed to jump the last hurdle. The problem I was facing was restricted to IE only. There seems to be an issue with it that prevents the use of WM_DEVMODECHANGE. Other applications like MS-Word etc. can auto-update its database, while Notepad will update on receiving a broadcast message.
If anybody wants to comment on any of my developments, they are free to do so.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.