Hello,

I have followed instructions in msdn to change at runtime a printer paper size configuration in my application (http://support.microsoft.com/?scid=k...40285&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...51130735465906).

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 :



// TestPrinterDocSettings.cpp : Defines the entry point for the console application.

//



#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"



// Function that enumerates all available paper forms:

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;


// get printer forms

_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

{

// report error

printf("ListPapers : Unable to open printer %s. Error = %d\n", PRINTER_NAME, GetLastError());

}

}



// MySetPrinter

//

// Demonstrates how to use the SetPrinter API.

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;



// Open printer handle (on Windows NT, you need full-access because you

// will eventually use SetPrinter)...

ZeroMemory(&pd, sizeof(pd));

pd.DesiredAccess = PRINTER_ALL_ACCESS;

bFlag = OpenPrinter(pPrinterName, &hPrinter, &pd);

if (!bFlag || (hPrinter == NULL))

return FALSE;



// The first GetPrinter tells you how big the buffer should be in

// order to hold all of PRINTER_INFO_2. Note that this should fail with

// ERROR_INSUFFICIENT_BUFFER. If GetPrinter fails for any other reason

// or dwNeeded isn't set for some reason, then there is a problem...

SetLastError(0);

bFlag = GetPrinter(hPrinter, Level, 0, 0, &dwNeeded);

if ((!bFlag) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||

(dwNeeded == 0))

{

ClosePrinter(hPrinter);

return FALSE;

}



// Allocate enough space for PRINTER_INFO_2...

pi2 = (BYTE *)GlobalAlloc(GPTR, dwNeeded);


if (pi2 == NULL)

{

ClosePrinter(hPrinter);

return FALSE;

}



// The second GetPrinter fills in all the current settings, so all you

// need to do is modify what you're interested in...

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 GetPrinter didn't fill in the DEVMODE, try to get it by calling

// DocumentProperties...

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;

}

}



// Driver is reporting that it doesn't support this change...

if (!(pDevMode->dmFields & DM_PAPERSIZE))

{

GlobalFree(pi2);

ClosePrinter(hPrinter);

if (pDevMode)

GlobalFree(pDevMode);

return FALSE;

}



// Specify exactly what we are attempting to change...

if(papersizenb <= _iPaperCount)

{

pDevMode->dmPaperSize = _pPapers[papersizenb];

}



if(Level == 2)

{

// Do not attempt to set security descriptor...

((PRINTER_INFO_2*)pi2)->pSecurityDescriptor = NULL;

}




// Make sure the driver-dependent part of devmode is updated...

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;

}



// Update printer information...

bFlag = SetPrinter(hPrinter, Level, (LPBYTE)pi2, 0);

if (!bFlag)

// The driver doesn't support, or it is unable to make the change...

{

GlobalFree(pi2);

ClosePrinter(hPrinter);

if (pDevMode)

GlobalFree(pDevMode);

return FALSE;

}



// Tell other apps that there was a change...

SendMessageTimeout(HWND_BROADCAST, WM_DEVMODECHANGE, 0L,

(LPARAM)(LPCSTR)pPrinterName,

SMTO_NORMAL, 1000, NULL);



// Clean up...

if (pi2)

GlobalFree(pi2);

if (hPrinter)

ClosePrinter(hPrinter);

if (pDevMode)

GlobalFree(pDevMode);



return TRUE;

}





int main(int argc, char* argv[])

{

// display all available papers size for the printer

ListPapers();

int papersizenb = 0;

printf("Saisir le numero du format de papier a configurer sur l'imprimante : ");

scanf("%d", &papersizenb);



// change current properties of the printer

MySetPrinter(PRINTER_NAME, papersizenb, 2);



// change default properties of the printer

MySetPrinter(PRINTER_NAME, papersizenb, 8);



// change current user properties of the printer

MySetPrinter(PRINTER_NAME, papersizenb, 9);



printf("Appuyer sur une lettre + \"Entree\" pour continuer");

scanf("%d", &papersizenb);



return 0;

}