How to change print quality (i.e. DRAFT) ?

Hi everybody,

maybe I get help again here. Sorry, I don't have more points at the time.


Problem: Printing in print quality "DRAFT" with matrix printers does not run. The printer always works with the print quality "NEAR LETTER QUALITY".

We use a matrix printer with a EPSON-LQ-2550 emulation and the driver "Epson LQ-2550" on a Windows NT 4.0 system with service pack 3.
Notepad is able to print documents using the print quality "DRAFT" with that printer.

The sample code below shows the way, how we try to activate the draft mode. This way seems to be impossible because the flag "DM_PRINTQUALITY" of the DEVMODE structure member "dmPrintQuality" is clear. So, I have to assume, that
the printer driver does not support to change the print quality.

Is this assumption correct?

---

By the way, the SetPrinter function returns always "FALSE" and the returnvalue of GetLastError () ist 5. The printer is configured with "access to everyone". So I use the ResetDC () function to update the printer settings.  

Regards, Toni


---




/*
*/
#include <windows.h>
#include <winspool.h>
#include <wingdi.h>
#include <wtypes.h>
#include <string.h>
#include <stdio.h>

#define UNCLEN      256
int MyPrint(LPSTR);
      char        gszDevice[UNCLEN], gszDriver[UNCLEN], gszOutput[UNCLEN] ,gszDriverName[UNCLEN];

main(int argc , char ** argv)
{
/*
//code pages
      int i;
      UINT Page=atoi(argv[1]);
       if (SetConsoleOutputCP(Page))
            for (i=0;i<256;i++)
            {      printf("%3.3d=%c\r\n",i,i);
      
            }
*/

      MyPrint(argv[1]);

      return 0;
}

HDC GetPrinterDC (void)
{
      static char szPrinter [80] ;
      char        *szDevice, *szDriver, *szOutput ;

      GetProfileString ("windows", "device", ",,,", szPrinter, 80) ;

      if (NULL != (szDevice = strtok (szPrinter, "," )) &&
            NULL != (szDriver = strtok (NULL,      ", ")) &&
            NULL != (szOutput = strtok (NULL,      ", ")))
      {      strcpy(gszDevice,szDevice);
            strcpy(gszDriver,szDriver);
            strcpy(gszDriverName,szDriver);
          strcat(gszDriverName, ".DRV");
            strcpy(gszOutput,szOutput);
            return CreateDC (szDriver, szDevice, szOutput, NULL) ;
      }

      return 0 ;
}


/*****************************************************************************
 *
 *      Function:       SetDraft()
 *                      
 *                      
 *****************************************************************************
 *                      
 *      Parameter:      char *szDevice   Printer device
 *                      HDC   hPrnDC   Handle of the device context
 *                      
 *****************************************************************************
 *                      
 *      Return:         0  Printer settings available
 *                      <0   Task failed
 *                      
 ****************************************************************************/


DWORD SetDraft(char *szDevice, HDC hPrnDC)
{
  int status = 0;

  HANDLE  hPrinter;
  HGLOBAL hGlobal = NULL;
  PRINTER_INFO_2 *pi2 = NULL;

  DWORD dwNeed = 0;
  DWORD dwError = 0;
  DEVMODE *pDevModeOut = NULL,
        *pDevModeIn =NULL;

  LPBYTE p = NULL;             /* Returned area containing printer settings */


    if (!OpenPrinter (szDevice, &hPrinter, NULL))
    {
        MessageBox(NULL, "OpenPrinter failed!", NULL, MB_OK);
          status =  -1;
        return status;
    }

    GetPrinter(hPrinter, 2, 0, 0, &dwNeed);

    /* Allocate memory  */
    if ((hGlobal = GlobalAlloc(LPTR,dwNeed)) == NULL)
    {                                                   /* Not enough space */
      status =  -2;
      ClosePrinter(hPrinter);
      return(status);
    }
    if ((pi2 = (PRINTER_INFO_2 *)GlobalLock(hGlobal)) == NULL)
    {                                                   /* Not enough space */
      status =  -3;
      ClosePrinter(hPrinter);
      GlobalFree(hGlobal);
      return(status);
    }

    /* Get PRINTER_INFO_2 structure */
    if ( (! GetPrinter( hPrinter, 2, (LPBYTE)pi2, dwNeed, &dwNeed) ) )
    {
      status =  -4;
      ClosePrinter(hPrinter);
      GlobalUnlock(hGlobal);
      GlobalFree(hGlobal);
      return(status);
   }

    /* Set draft mode */
   
    if ( pi2->pDevMode != NULL )
      {
            printf("PRINTER: %s, YRes: %d, PrQ: %d, Draft: %d\n",pi2->pDevMode->dmDeviceName,
                                                        pi2->pDevMode->dmYResolution,
                                                        pi2->pDevMode->dmPrintQuality,
                                                                          (short) DMRES_DRAFT);

            if (pi2->pDevMode->dmFields & DM_PRINTQUALITY)
        {
             pi2->pDevMode->dmPrintQuality = DMRES_DRAFT;
          }
            else
            {
                  printf("Flag: DM_PRINTQUALITY not set\n");
            }
      }

    if ( DocumentProperties( NULL, hPrinter, szDevice, pi2->pDevMode,
                 pi2->pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER ) != IDOK)
    {
      status =  -5;
      ClosePrinter(hPrinter);
      GlobalUnlock(hGlobal);
      GlobalFree(hGlobal);
      return(status);
    }
    /* Update printer settings */
   
//  if ( SetPrinter( hPrinter, 2, (LPBYTE)pi2, 0) == FALSE )  /* returns always "FALSE" */
      if ( ResetDC(hPrnDC,pi2->pDevMode) == FALSE )
    {
        DWORD error;

        error = GetLastError ();
        printf("GetLastError( SetPrinter ): %d\n", error);
      status =  -6;
    }

    ClosePrinter(hPrinter);
    GlobalUnlock(hGlobal);
    GlobalFree(hGlobal);
    return(status);
}                                                    

int MyPrint(LPSTR FileName)
{      BOOL EndOfFile=FALSE;
      //printing variables
      int       JobNumber;
      HDC       hPrnDC;
    DOCINFO     di;
    HFONT       hOldFont=NULL;
    HFONT      hFont=NULL;
    HFONT      hFontBig=NULL;
    HFONT      hFontBold=NULL;
    HFONT      hFontUnderline=NULL;

    int         nxLogPix, nyLogPix, dxPrinter, dyPrinter;
    int            iPageNum=0;
    DWORD       dwOldColor=0;
    DWORD       status=0;

    char    szBuffer[256];
    int     nx;
    int     ny;
      static char szPrinter [80] ;
      char        *szDevice, *szDriver, *szOutput ;


    // get a handle to the default printer
/*      if (NULL == (hPrnDC = GetPrinterDC ()))         */
/*          return FALSE ;                                 */

    GetProfileString ("windows", "device", ",,,", szPrinter, 80) ;

      if (NULL != (szDevice = strtok (szPrinter, "," )) &&
            NULL != (szDriver = strtok (NULL,      ", ")) &&
            NULL != (szOutput = strtok (NULL,      ", ")))
      {      strcpy(gszDevice,szDevice);
            strcpy(gszDriver,szDriver);
            strcpy(gszDriverName,szDriver);
          strcat(gszDriverName, ".DRV");
            strcpy(gszOutput,szOutput);
            hPrnDC = CreateDC (szDriver, szDevice, szOutput, NULL) ;
      }
      else { return FALSE; }

      if ( hPrnDC == NULL ) { return FALSE; }

//       status = SetDraft ( szDevice, hPrnDC );

    di.cbSize      = sizeof(DOCINFO);
    di.lpszDocName = (LPSTR)"TESTPRINT";
    di.lpszOutput  = NULL;

    // issue STARTDOC
      JobNumber=StartDoc(hPrnDC, &di);
    if (JobNumber < 0)
    {    // "STARTDOC escape problem"
         DeleteDC(hPrnDC);
         return FALSE;
    }

/*
{

    PRINTDLG dlg;

    ZeroMemory(&dlg, sizeof(dlg));
    dlg.lStructSize = sizeof(dlg);
    dlg.hwndOwner = NULL;


    if (PrintDlg(&dlg) == IDOK)
    {
        LPDEVMODE   pdm;
        LPDEVMODE   pdm1;
        LPDEVNAMES  pdn;
        char        szText[80];

        SetPaperName(szDevice,"A4",hPrnDC);
        pdm1 = (LPDEVMODE)GetPrinterDevmode(szDevice);
       
        pdm = GlobalLock(dlg.hDevMode);
        pdn = GlobalLock(dlg.hDevNames);

        wsprintf(szText, "dmDefaultSource = %d", pdm->dmDefaultSource);
        MessageBox(NULL, szText, pdm->dmFormName, MB_OK);

        ResetDC (hPrnDC, pdm);

        GlobalUnlock(dlg.hDevMode);
        GlobalUnlock(dlg.hDevNames);

        GlobalFree(dlg.hDevMode);
        GlobalFree(dlg.hDevNames);
    }
}
*/


              // get any information
          // get logical pixels per inch
          nxLogPix  = GetDeviceCaps(hPrnDC, LOGPIXELSX);
          nyLogPix  = GetDeviceCaps(hPrnDC, LOGPIXELSY);

          // get page resolution
          dxPrinter = GetDeviceCaps(hPrnDC, HORZRES);
          dyPrinter = GetDeviceCaps(hPrnDC, VERTRES);

      // create font
      {      
#define BASEH      100
            int  nWidth=nxLogPix / 10;      // logical average character width
            int  nHeight=nWidth * 2;      // logical height of font
            int  nEscapement=0;                  // angle of escapement
            int  nOrientation=0;            // base-line orientation angle
            int  fnWeight=FW_DONTCARE;      // font weight
            DWORD  fdwItalic=0;                  // italic attribute flag
            DWORD  fdwUnderline=0;            // underline attribute flag
            DWORD  fdwStrikeOut=0;            // strikeout attribute flag
            DWORD  fdwCharSet=ANSI_CHARSET;// character set identifier
            DWORD  fdwOutputPrecision=0;// output precision
            DWORD  fdwClipPrecision=0;      // clipping precision
            DWORD  fdwQuality=DRAFT_QUALITY;      // output quality
                        // DRAFT_QUALITY
                        // PROOF_QUALITY
            DWORD  fdwPitchAndFamily=FIXED_PITCH | FF_MODERN;      // pitch and family
 
            hFont=CreateFont(nHeight,nWidth,nEscapement,nOrientation,fnWeight,fdwItalic,fdwUnderline
                                           ,fdwStrikeOut,fdwCharSet,fdwOutputPrecision,fdwClipPrecision,fdwQuality
                                           ,fdwPitchAndFamily,"Courier 10cpi");       

        }
    hOldFont = SelectObject(hPrnDC,hFont);       
                                                                   /* Set print mode = DRAFT */
      status = SetDraft ( szDevice, hPrnDC );

                      //      SetTextAlign(hPrnDC,TA_UPDATECP);
      
    nx=nxLogPix;
    ny=nyLogPix;
      // start printing a page
    StartPage(hPrnDC);
                    

    // write something to printer
    wsprintf(szBuffer, "This is a line of text on page %d", 2);

      // normal
    SelectObject(hPrnDC,hFont);
    TextOut(hPrnDC, nx, 2*ny, szBuffer, strlen(szBuffer));
            
    // end the page; resets the dc to normal defaults
    EndPage(hPrnDC);
            

      if (EndDoc(hPrnDC) < 0)    // end the document
      {
            //"EndDoc function problem"
            return FALSE;
      }

      // CLEANUP
    // deselect font
    SelectObject(hPrnDC, hOldFont);
    DeleteDC(hPrnDC);

      return TRUE;
}


LVL 1
moosachAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

moosachAuthor Commented:
I can't believe that nobody is able to help me :-((((((
0
belovCommented:
Didn't you try the following simple approach?

1. Obtain default DEVMODE for printer.
pd.Flags |= PD_RETURNDEFAULT;
 PrintDlg(&pd);

2. Obtain pointer to DEVMOVE
LPDEVMODE lpDevMode = GlobalLock(pd.hDevMode)
lpDevMode->dmPrintQuality = DMRES_DRAFT;
::GlobalUnlock(pd.hDevMode);

3. Now tell PrintDlg to init to values given
    in hDevMode field of PRINTDLG structure,
   and supply handle to modified structure.

I used this simple code to switch to landscape mode
instead of default portrait one.
0
moosachAuthor Commented:
Hi belov,

thanks for your comment. Make an answer from it and get the points, because your approach will most probably work.

I asked Microsoft directly in the meanwhile concerning my problem and got today following answer from the support guys :
 
.............................

This is a response regarding DRAFT printing mode.

 You are correct that if the DM_PRINTQUALITY field of
the DEVMODE is cleared, then that field is not supported. Therefore, your driver does not support  changing the print quality. Further, I suspect that even if it did support  such a change, you would not see much change in performance or output when  using a non-default font.

The reason Notepad seems to support draft mode is
that it does not create and select a font. It simply begins printing using the default font for the printer. You will probably see similar performance to Notepad if you remove  your font code and use the default font.

I hope this helps.

........................

So it is a problem of my printer and not from my code.

But your answer was nevertheless correct. So get your points ;-)

Regards

Toni
0
moosachAuthor Commented:
Hi belov,

thanks for your comment. Make an answer from it and get the points, because your approach will most probably work.

I asked Microsoft directly in the meanwhile concerning my problem and got today following answer from the support guys :
 
.............................

This is a response regarding DRAFT printing mode.

 You are correct that if the DM_PRINTQUALITY field of
the DEVMODE is cleared, then that field is not supported. Therefore, your driver does not support  changing the print quality. Further, I suspect that even if it did support  such a change, you would not see much change in performance or output when  using a non-default font.

The reason Notepad seems to support draft mode is
that it does not create and select a font. It simply begins printing using the default font for the printer. You will probably see similar performance to Notepad if you remove  your font code and use the default font.

I hope this helps.

........................

So it is a problem of my printer and not from my code.

But your answer was nevertheless correct. So get your points ;-)

Regards

Toni
0
belovCommented:
I suggest the following, more simple approach.

1. Obtain default DEVMODE values for printer.
pd.Flags |= PD_RETURNDEFAULT;
PrintDlg(&pd);

2. Obtain pointer to DEVMOVE
LPDEVMODE lpDevMode = GlobalLock(pd.hDevMode)
lpDevMode->dmPrintQuality = DMRES_DRAFT;
::GlobalUnlock(pd.hDevMode);

3. If hDevMode field of PRINTDLG is not NULL,
PrintDlg will attempt to initialize printer according
to given DEVMODE values, so you can supply
handle to modified structure. Even if your printer really
does not support that mode, it won't do any harm :)


0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.