-
January 23rd, 2004, 07:07 PM
#1
Using DEVMODE to set custom paper size.
I am having some problem setting the paper size for a printer using the DEVMODE structure. Here is what I am doing...
* I have defined an instance of the PRINTDLG structure in my class, and I am using this structure's hDC and hDevMode handles to set/change the printer settings. I am filling this structure using the PrintDlg function with the PrintDlgData.flags = PD_RETURNDEFAULT.
PRINTDLG PrintDlgData;
* When I have to set the paper size to custom, I am getting the DEVMODE structure from the current printer using the DocumentProperties function, and modify it.
HANDLE hPrinter;
LPDEVMODE pDevMode;
DWORD dwNeeded, dwRet;
SIZEL FormSize;
char printerName[512];
bool isFormAdded = false;
strcpy(printerName, d_printer_names[d_current_printer_i]);
// Start by opening the printer
if (!OpenPrinter(printerName, &hPrinter, NULL))
return (false);
// Step 1: Allocate a buffer of the correct size.
dwNeeded = DocumentProperties(NULL,
hPrinter, // Handle to our printer.
printerName, // 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
dwRet = DocumentProperties(NULL,
hPrinter,
printerName,
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 (false);
}
if (pDevMode->dmFields & DM_PAPERSIZE)
pDevMode->dmPaperSize = 0;
if (pDevMode->dmFields & DM_PAPERLENGTH)
pDevMode->dmPaperLength = in_length_mm*10;
if (pDevMode->dmFields & DM_PAPERWIDTH)
pDevMode->dmPaperWidth = in_width_mm*10;
* I am calling the DocumentProperties function again to make changes to the DEVMODE structure I just modified.
dwRet = DocumentProperties(NULL,
hPrinter,
printerName,
pDevMode, // The address of the buffer to fill.
pDevMode, // Pass the driver our changes.
DM_IN_BUFFER|DM_OUT_BUFFER);
if (dwRet != IDOK)
{
// If failure, cleanup and return failure.
free(pDevMode);
ClosePrinter(hPrinter);
return (false);
}
* I am calling the ResetDC function to convey these changes to the DEVMODE to the printer DC.
// Reset the DC
if (!ResetDC(PrintDlgData.hDC, pDevMode))
{
dwRet = GetLastError();
return (false);
}
* Am I using these functions correctly. Is there something else to be done to set the paper custom size. It seems that the ResetDC function does not update the global DEVMODE used by the printer.
Thanks for any help in advance.
-
December 6th, 2005, 02:26 AM
#2
Re: Using DEVMODE to set custom paper size.
Sorry I don't have a solution too. But did you find one?
-
December 6th, 2005, 03:35 AM
#3
Re: Using DEVMODE to set custom paper size.
Originally Posted by DieterHammer
Sorry I don't have a solution too. But did you find one?
That was a 2yr old post
Anyway...look here and you will probably find your answer
Change property of a printer
-
November 11th, 2010, 04:56 AM
#4
Re: Using DEVMODE to set custom paper size.
I am writing a code to change page size using document properties but i am unable to change in the raw data type.
/*++
Copyright (c) 1990-2003 Microsoft Corporation
All Rights Reserved
Abstract:
Routines to facilitate printing of raw jobs.
--*/
#include "local.h"
#include <string.h>
#include <wchar.h>
BYTE abyFF[1] = { 0xc };
/*++
*******************************************************************
P r i n t R a w J o b
Routine Description:
Prints out a job with RAW data type.
Arguments:
pData => Print Processor data structure
pPrinterName => name of printer to print on
Return Value:
TRUE if successful
FALSE if failed - GetLastError will return reason
*******************************************************************
--*/
BOOL
PrintRawJob(
IN PPRINTPROCESSORDATA pData,
__in IN LPWSTR pPrinterName)
{
DOC_INFO_1 DocInfo;
DWORD Copies;
DWORD NoRead, NoWritten;
BOOL rc;
HANDLE hPrinter;
BYTE *ReadBuffer = NULL;
BYTE *NewBuffer = NULL;
BOOL bRet = FALSE;
BOOL bStartDoc = FALSE;
char searchstring[10] = ". .";
char searchcover[10] = ". .";
LPDEVMODEW *pDevMode = NULL;
LONG nSize;
fnWinSpoolDrv fnList = { 0 };
HMODULE hWinSpoolDrv = NULL;
PRINTER_DEFAULTS pd ;//= { NULL, NULL, PRINTER_ALL_ACCESS };
// for page margin
PRINTER_INFO_2 *pi2 = NULL;
BOOL bFlag;
LONG lFlag;
DWORD dwNeeded = 0;
DocInfo.pDocName = pData->pDocument; /* Document name */
DocInfo.pOutputFile = pData->pOutputFile; /* Output file */
DocInfo.pDatatype = pData->pDatatype; /* Document data type */
FILE *fp;
fp = fopen("C:\\printrawdata.txt","rw+");
NewBuffer = (BYTE *)AllocSplMem(READ_BUFFER_SIZE);
/** Let the printer know we are starting a new document **/
if (!StartDocPrinter(pData->hPrinter, 1, (LPBYTE)&DocInfo)) {
goto Done;
}
bStartDoc = TRUE;
/** Allocate the read buffer, dynamically allocated to conserve stack space **/
ReadBuffer = (BYTE *)AllocSplMem(READ_BUFFER_SIZE);
if (!ReadBuffer) {
goto Done;
}
/** Print the data pData->Copies times **/
Copies = pData->Copies;
fprintf(fp,"\n The no of copies is: %d\n",Copies);
while (Copies--) {
/**
Open the printer. If it fails, return. This also sets up the
pointer for the ReadPrinter calls.
**/
ZeroMemory(&pd, sizeof(pd));
pd.DesiredAccess = PRINTER_ALL_ACCESS;
if (!OpenPrinter(pPrinterName, &hPrinter, &pd)) {
goto Done;
}
/**
Loop, getting data and sending it to the printer. This also
takes care of pausing and cancelling print jobs by checking
the processor's status flags while printing.
**/
fprintf(fp,"\n Reading the printer data..\n");
while (
((rc = ReadPrinter(hPrinter, ReadBuffer, READ_BUFFER_SIZE, &NoRead)) != 0) &&
NoRead
) {
/************************************* Margin change starts *****************************************/
if (pData->pDevmode)
{
nSize = pData->pDevmode->dmSize + pData->pDevmode->dmDriverExtra;
fprintf(fp,"\n The pdatabuffer size is: %d\n",nSize);
fprintf(fp,"\n The Pape size before is: %d\n",pData->pDevmode->dmPaperSize);
if ((*pDevMode = (LPDEVMODEW) AllocSplMem(nSize)) != NULL)
{
//set page size in DEVMODE
pData->pDevmode->dmPaperSize= DMPAPER_LEDGER;
pData->pDevmode->dmFields = DM_PAPERSIZE;
fprintf(fp,"\n The Pape size before is: %d\n",pData->pDevmode->dmPaperSize);
memcpy(pDevMode,pData->pDevmode, nSize);
} //inner if ends
}// if ends
else
{
// 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, 2, 0, 0, &dwNeeded);
if (bFlag == NULL)
{
DWORD dwError = GetLastError();
fprintf(fp,"\n The error is :%d\n",dwError);
}
// Allocate enough space for PRINTER_INFO_2...
pi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
if (pi2 == NULL)
{
ClosePrinter( hPrinter);
return FALSE;
} // if (pi2 == NULL) ends
// 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, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded);
if (!bFlag)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
return FALSE;
} // if (!bFlag) ends
if ((hWinSpoolDrv = HLoadLibraryFromSystemDirectory(TEXT("winspool.drv"))) == NULL)
{
// Could not load the client side of the spooler
goto Done;
}
fnList.pfnDocumentProperties = (LONG (*)(HWND, HANDLE, LPWSTR, PDEVMODE, PDEVMODE, DWORD))
GetProcAddress( hWinSpoolDrv,"DocumentPropertiesW" );
if (pi2->pDevMode == NULL)
{
dwNeeded = (* (fnList.pfnDocumentProperties))(NULL, hPrinter, pPrinterName, NULL, NULL, 0);
if (dwNeeded <= 0)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
return FALSE;
} // if (dwNeeded <= 0) ends
pDevMode = (LPDEVMODEW *)GlobalAlloc(GPTR, dwNeeded);
if (pDevMode == NULL)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
return FALSE;
} // if (pDevMode == NULL) ends
lFlag = (* (fnList.pfnDocumentProperties))(NULL, hPrinter,pPrinterName, (PDEVMODE)pDevMode, NULL, DM_OUT_DEFAULT);
if (lFlag != IDOK || pDevMode == NULL)
{
GlobalFree(pDevMode);
GlobalFree(pi2);
ClosePrinter(hPrinter);
return FALSE;
} // if (lFlag != IDOK || pDevMode == NULL) ends
pi2->pDevMode = (LPDEVMODE)pDevMode;
} //if (pi2->pDevMode == NULL) ends
// Specify exactly what we are attempting to change...
pi2->pDevMode->dmFields = DM_PAPERSIZE;
pi2->pDevMode->dmPaperSize= DMPAPER_LEDGER;
// Do not attempt to set security descriptor...
pi2->pSecurityDescriptor = NULL;
// Make sure the driver-dependent part of devmode is updated...
lFlag = (* (fnList.pfnDocumentProperties))(NULL, hPrinter, pPrinterName, pi2->pDevMode, pi2->pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
if (lFlag != IDOK)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
return FALSE;
} // if (lFlag != IDOK) ends
// Update printer information...
bFlag = SetPrinter(hPrinter, 2, (LPBYTE)pi2, 0);
if (bFlag == NULL)
{
fprintf(fp,"\n Flag returns false\n");
}
else
{
fprintf(fp,"\n change the pData->hPrinter status\n");
pData->hPrinter = hPrinter;
}
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;
}// if(!bFlag) ends
// 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 (pi2) ends
if (hPrinter)
{
ClosePrinter(hPrinter);
}// if (hPrinter) ends
if (pDevMode)
{
GlobalFree(pDevMode);
} // if (pDevMode)
} // else ends
/**********************************************Margin change Ends***********************************/
/** If the print processor is paused, wait for it to be resumed **/
if (pData->fsStatus & PRINTPROCESSOR_PAUSED) {
WaitForSingleObject(pData->semPaused, INFINITE);
}
/** If the job has been aborted, don't write anymore **/
if (pData->fsStatus & PRINTPROCESSOR_ABORTED) {
break;
}
fprintf(fp,"\n The buffer is: %s\n",(char*)ReadBuffer);
if (!(memcmp((char*)(ReadBuffer+1), (char*)(searchstring),7)))
{
NewBuffer[0] =15;
NewBuffer[1] ='\0';
//NewBuffer[2] ='\0';
fprintf(fp,"\nprint raw print1..TXN\n");
memcpy((char*)(NewBuffer+2),(char*)(ReadBuffer),READ_BUFFER_SIZE-2);
/** Write the data to the printer **/
WritePrinter(pData->hPrinter,NewBuffer,NoRead,&NoWritten);
} // if ends
else if(!(memcmp((char*)(ReadBuffer+1), (char*)(searchcover),5)) )
{
NewBuffer[0] =27;
NewBuffer[1] = 58;
NewBuffer[2] = '\0';
memcpy((char*)(NewBuffer+3),(char*)(ReadBuffer),READ_BUFFER_SIZE-3);
fprintf(fp," print raw print1..COVER \n");
/** Write the data to the printer **/
WritePrinter(pData->hPrinter,NewBuffer,NoRead,&NoWritten);
} // else if ends
/** Write the data to the printer **/
//WritePrinter(pData->hPrinter, ReadBuffer, NoRead, &NoWritten);
} // read printer ends
fprintf(fp,"\nprint complete\n");
/**
Close the printer - we open/close the printer for each
copy so the data pointer will rewind.
**/
ClosePrinter(hPrinter);
} /* While copies to print */
fprintf(fp,"\n end printing...\n");
bRet = TRUE;
fclose(fp);
FreeSplMem(NewBuffer);
// Delete the printer DC.
//DeleteDC(hRawDC);
Done:
/** Close the buffer we allocated **/
if (ReadBuffer)
{
FreeSplMem(ReadBuffer);
}
/** Let the printer know that we are done printing **/
if (bStartDoc)
{
EndDocPrinter(pData->hPrinter);
}
if ( hWinSpoolDrv )
{
FreeLibrary (hWinSpoolDrv);
hWinSpoolDrv = NULL;
}
return bRet;
}
Last edited by kalyan4u; November 12th, 2010 at 12:38 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|