Using DEVMODE to set custom paper size.
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4

Thread: Using DEVMODE to set custom paper size.

  1. #1
    Join Date
    Nov 2001
    Posts
    9

    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.

  2. #2
    Join Date
    Jul 2001
    Location
    Germany, near Frankfurt
    Posts
    135

    Re: Using DEVMODE to set custom paper size.

    Sorry I don't have a solution too. But did you find one?

  3. #3
    Join Date
    May 2005
    Posts
    399

    Re: Using DEVMODE to set custom paper size.

    Quote 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

  4. #4
    Join Date
    Nov 2010
    Posts
    5

    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
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center