Hello,
I have followed instructions in msdn to change at runtime a printer paper size configuration in my application (http://support.microsoft.com/?scid=kb;en-us;140285&x=12&y=8). I have replaced the dmOrientation option by the dmPaperSize to meet my need.
All seems to execute fine (no error), but my new paper size is not taken into account until I manually validate the paper size from the printer options dialog box opened from the control panel. (Step 4 on the image http://picasaweb.google.com/stephane.rzetelny/DropBox#5497051130735465906).
To try to understand what I have missed, I have spy what's happened in file and registry when I execute the code snippet from msdn and when I validate the printer options dialog box with the incredible procmonitor.exe tool from sysinternal. Result is: there is no difference !!
So I don't understand what I have missed !
Any suggestion would be very appreciated.
Regards.
-------------------------------
Here is the code sample :
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
int _iPaperCount = 0;
WORD* _pPapers = NULL;
char* _pPaperNames = NULL;
POINT* _pPaperSizes = NULL;
#define PRINTER_NAME "Receipt Printer"
void ListPapers()
{
HANDLE hPrinter = NULL;
if (_pPapers)
{
delete [] _pPapers;
_pPapers = NULL;
}
if (_pPaperNames)
{
delete [] _pPaperNames;
_pPaperNames = NULL;
}
if (_pPaperSizes)
{
delete [] _pPaperSizes;
_pPaperSizes = NULL;
}
if (OpenPrinter(PRINTER_NAME, &hPrinter, NULL))
{
DWORD dwNeeded = 0;
_iPaperCount = DeviceCapabilities(PRINTER_NAME, NULL, DC_PAPERS, NULL, NULL);
if (_iPaperCount)
{
_pPapers = new WORD[_iPaperCount];
ZeroMemory(_pPapers, sizeof(WORD)*_iPaperCount);
DeviceCapabilities(PRINTER_NAME, NULL, DC_PAPERS, (LPSTR) _pPapers, NULL);
_pPaperNames = new char[_iPaperCount*64];
ZeroMemory(_pPaperNames, sizeof(char)*64*_iPaperCount);
DeviceCapabilities(PRINTER_NAME, NULL, DC_PAPERNAMES, _pPaperNames, NULL);
for (int i = 0; i < _iPaperCount; i++)
{
printf("%d : %s\n", i, _pPaperNames+(i*64));
}
}
ClosePrinter(hPrinter);
}
else
{
printf("ListPapers : Unable to open printer %s. Error = %d\n", PRINTER_NAME, GetLastError());
}
}
BOOL MySetPrinter(LPTSTR pPrinterName, short papersizenb, DWORD Level)
{
HANDLE hPrinter = NULL;
DWORD dwNeeded = 0;
BYTE *pi2 = NULL;
DEVMODE *pDevMode = NULL;
PRINTER_DEFAULTS pd;
BOOL bFlag;
LONG lFlag;
ZeroMemory(&pd, sizeof(pd));
pd.DesiredAccess = PRINTER_ALL_ACCESS;
bFlag = OpenPrinter(pPrinterName, &hPrinter, &pd);
if (!bFlag || (hPrinter == NULL))
return FALSE;
SetLastError(0);
bFlag = GetPrinter(hPrinter, Level, 0, 0, &dwNeeded);
if ((!bFlag) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
(dwNeeded == 0))
{
ClosePrinter(hPrinter);
return FALSE;
}
pi2 = (BYTE *)GlobalAlloc(GPTR, dwNeeded);
if (pi2 == NULL)
{
ClosePrinter(hPrinter);
return FALSE;
}
bFlag = GetPrinter(hPrinter, Level, pi2, dwNeeded, &dwNeeded);
if (!bFlag)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
return FALSE;
}
if (Level == 2)
{
pDevMode = ((PRINTER_INFO_2*)pi2)->pDevMode;
}
else if( Level == 8)
{
pDevMode = ((PRINTER_INFO_8*)pi2)->pDevMode;
}
else if (Level = 9)
{
pDevMode = ((PRINTER_INFO_9*)pi2)->pDevMode;
}
else
{
pDevMode = NULL;
}
if (pDevMode == NULL)
{
dwNeeded = DocumentProperties(NULL, hPrinter,
pPrinterName,
NULL, NULL, 0);
if (dwNeeded <= 0)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
return FALSE;
}
pDevMode = (DEVMODE *)GlobalAlloc(GPTR, dwNeeded);
if (pDevMode == NULL)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
return FALSE;
}
lFlag = DocumentProperties(NULL, hPrinter,
pPrinterName,
pDevMode, NULL,
DM_OUT_BUFFER);
if (lFlag != IDOK || pDevMode == NULL)
{
GlobalFree(pDevMode);
GlobalFree(pi2);
ClosePrinter(hPrinter);
return FALSE;
}
}
if (!(pDevMode->dmFields & DM_PAPERSIZE))
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
return FALSE;
}
if(papersizenb <= _iPaperCount)
{
pDevMode->dmPaperSize = _pPapers[papersizenb];
}
if(Level == 2)
{
((PRINTER_INFO_2*)pi2)->pSecurityDescriptor = NULL;
}
lFlag = DocumentProperties(NULL, hPrinter,
pPrinterName,
pDevMode, pDevMode,
DM_IN_BUFFER | DM_OUT_BUFFER);
if (lFlag != IDOK)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
return FALSE;
}
bFlag = SetPrinter(hPrinter, Level, (LPBYTE)pi2, 0);
if (!bFlag)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
return FALSE;
}
SendMessageTimeout(HWND_BROADCAST, WM_DEVMODECHANGE, 0L,
(LPARAM)(LPCSTR)pPrinterName,
SMTO_NORMAL, 1000, NULL);
if (pi2)
GlobalFree(pi2);
if (hPrinter)
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
return TRUE;
}
int main(int argc, char* argv[])
{
ListPapers();
int papersizenb = 0;
printf("Saisir le numero du format de papier a configurer sur l'imprimante : ");
scanf("%d", &papersizenb);
MySetPrinter(PRINTER_NAME, papersizenb, 2);
MySetPrinter(PRINTER_NAME, papersizenb, 8);
MySetPrinter(PRINTER_NAME, papersizenb, 9);
printf("Appuyer sur une lettre + \"Entree\" pour continuer");
scanf("%d", &papersizenb);
return 0;
}</stdio.h></windows.h>