none
Not Enough Memory for print operation RRS feed

  • Question

  • I'm getting an error from Windows -- "Not enough memory for this operation"

    I'm using the following code to get a dc to a printer, then I print text to the dc using DrawText, then close with the close function below.  Any ideas what is causing this??  The error comes up after clicking "ok" on the PrintDlg dialog box...


    HDC openprintr(HWND hparent)
    {
         LONG vprefshowdialog,pgwdth,pghght,fonthght,fontwdth,textwidth;  //,pr_landscape;
         std::string stxt;
         std::wstring wtxt;
         RECT rc;
         DOCINFO docinf;
         PRINTDLG lppd;
         DEVMODE dm;

         vprefshowdialog=0;

         dm.dmSize=sizeof(DEVMODE);
         dm.dmPaperSize=DMPAPER_LETTER;
         dm.dmCopies=1;
         dm.dmPrintQuality=DMRES_MEDIUM;  //DM_HIGH  DM_LOW  DM_DRAFT
         dm.dmDuplex=DMDUP_SIMPLEX;
         dm.dmNup=DMNUP_ONEUP;  // = application does page setup  //DMNUP_SYSTEM = system does page setup

         lppd.lStructSize=sizeof(PRINTDLG);
         lppd.hwndOwner=hparent;
         lppd.hDevMode=&dm;
         lppd.hDC=NULL;
         lppd.Flags=PD_RETURNDC | PD_NOSELECTION | PD_USEDEVMODECOPIESANDCOLLATE;
         lppd.nCopies=1;

         if(vprefshowdialog)
           lppd.Flags=lppd.Flags | PD_RETURNDEFAULT;

         //bring up dialog box to select printer  
         
         if(PrintDlg(&lppd) == FALSE)
           return NULL;

         hprinter=lppd.hDC;

         if(hprinter == INVALID_HANDLE_VALUE)
           return NULL;

         //pgwdth=dm.dmPaperWidth;  //in tenths of a millimeter
         //pghght=dm.dmPaperLength;  //in tenths of a millimeter
         //landscape=dm.dmOrientation;
         pgwdth=(long)GetDeviceCaps(hprinter,HORZRES);  //in pixels
         pghght=(long)GetDeviceCaps(hprinter,VERTRES);  //in pixels

         fonthght=16;
         fontwdth=8;

         while(fontwdth > 3)
         {
           hprinterfont=fontmaker("Courier New",fonthght,fontwdth,0);
           SelectObject(hprinter,(HGDIOBJ)hprinterfont);

           //test text size
           stxt=fillstring(96,"W");
           wtxt=strtowstr(stxt);

           rc.left=0;
           rc.top=0;
           rc.right=pgwdth;
           rc.bottom=pghght;
           
           DrawTextEx(hprinter,(LPWSTR)wtxt.c_str(),96,&rc,DT_LEFT | DT_NOCLIP | DT_CALCRECT,NULL);

           // Because we used DT_CALCRECT, the DrawTextEx call didn't draw anything,
           // but it did adjust the bottom of RECT rc to account for the actual height.
           textheight=(rc.bottom-rc.top);
           textwidth=(rc.right-rc.left);

           if(textwidth <= pgwdth)
             break;

           DeleteObject(hprinterfont);

           fontwdth--;
           fonthght=fontwdth*2;
         }

         pagelines=(long)floor((double)pghght/textheight)-1;
         pagecount=1;

         // Fill in the structure with info about this "document"
         docinf.cbSize=sizeof(DOCINFO);
         docinf.lpszDocName=TEXT("Print Job");
         docinf.lpszOutput=NULL;
         docinf.lpszDatatype=TEXT("RAW");

         // Inform the spooler the document is beginning.
         if(StartDoc(hprinter,&docinf) == 0)
         {
           DeleteDC(hprinter);
           return NULL;
         }

         // Start a page
         if(StartPage(hprinter) == 0)
         {
           EndDoc(hprinter);
           DeleteDC(hprinter);
           return NULL;
         }

         return hprinter;
    }

    VOID closeprintr()
    {
         DeleteObject(hprinterfont);
         EndPage(hprinter);
         EndDoc(hprinter);
         DeleteDC(hprinter);
         return;
    }

                


    • Edited by TallGuy63 Friday, September 18, 2015 10:06 PM
    Friday, September 18, 2015 8:06 PM

Answers

  • I'm getting an error from Windows -- "Not enough memory for this operation"

    I'm using the following code to get a dc to a printer, then I print text to the dc using DrawText, then close with the close function below.  Any ideas what is causing this??  The error comes up after clicking "ok" on the PrintDlg dialog box...


    HDC openprintr(HWND hparent)
    {
         LONG vprefshowdialog,pgwdth,pghght,fonthght,fontwdth,textwidth;  //,pr_landscape;
         std::string stxt;
         std::wstring wtxt;
         RECT rc;
         DOCINFO docinf;
         PRINTDLG lppd;
         DEVMODE dm;

    For starters, I recommend initializing *all* structures to zero when they are declared. e.g. -

    RECT rc = {0};
    DOCINFO docinf = {0};
    PRINTDLG lppd = {0};
    DEVMODE dm = {0};
    

    This prevents using a structure with an arbitrary value in one of its members, if each
    one isn't individually set.

    - Wayne

    • Marked as answer by TallGuy63 Saturday, September 19, 2015 3:41 AM
    Friday, September 18, 2015 10:50 PM

All replies

  • I'm getting an error from Windows -- "Not enough memory for this operation"

    I'm using the following code to get a dc to a printer, then I print text to the dc using DrawText, then close with the close function below.  Any ideas what is causing this??  The error comes up after clicking "ok" on the PrintDlg dialog box...


    HDC openprintr(HWND hparent)
    {
         LONG vprefshowdialog,pgwdth,pghght,fonthght,fontwdth,textwidth;  //,pr_landscape;
         std::string stxt;
         std::wstring wtxt;
         RECT rc;
         DOCINFO docinf;
         PRINTDLG lppd;
         DEVMODE dm;

    For starters, I recommend initializing *all* structures to zero when they are declared. e.g. -

    RECT rc = {0};
    DOCINFO docinf = {0};
    PRINTDLG lppd = {0};
    DEVMODE dm = {0};
    

    This prevents using a structure with an arbitrary value in one of its members, if each
    one isn't individually set.

    - Wayne

    • Marked as answer by TallGuy63 Saturday, September 19, 2015 3:41 AM
    Friday, September 18, 2015 10:50 PM
  • Amazing... that worked !

    Thanks

    Saturday, September 19, 2015 3:41 AM
  • If initializing the structures to 0 actually solved the problem, then somewhere in your code you are accessing a member of a struct that you never assigned a value to.  Solved is the wrong word; all you have done is camouflage the problem.  It is possible that 0 is the desired value for this member but you need to perform the analysis that confirms this.
    Saturday, September 19, 2015 11:10 PM
  • I agree with Barry-Schwarz observation that the OP should analyze why the code works after structures are initialized to zero. 

     

    Sunday, September 20, 2015 3:24 AM
  • I've seen similar odd symptoms before, numerous times, when programmers are using various
    operations from the Win API/SDK.

    They see structure members which are not needed for their current task, and the docs say
    something like "If this member is zero (or NULL)..." so they assign nothing to it. But of
    course that will only result in it being zero if:

    (1) The struct is a global.

    or

    (2) The struct is a static local.

    or

    (3) The struct is initialized to zero when declared or set via ZeroMemory(), memset(), etc.

    If the struct is an uninitialized local, it will contain arbitrary values in Release builds
    and in Debug builds it will be set to the "magic" value used by the debugger. When executed,
    since the struct member is not zero, the API attempts an operation using the contents with
    results that are unpredictable and often undesirable.

    - Wayne
    Sunday, September 20, 2015 5:25 AM
  • Point well taken.  Even so, it might be beneficial for the OP to confirm (if only for his own understanding) that the uninitialized data structure was the root cause.
    Sunday, September 20, 2015 1:43 PM
  • But of
    course that will only result in it being zero if:

    (1) The struct is a global.

    or

    (2) The struct is a static local.

    or

    (3) The struct is initialized to zero when declared or set via ZeroMemory(), memset(), etc.

    If the struct is an uninitialized local, it will contain arbitrary values in Release builds
    and in Debug builds it will be set to the "magic" value used by the debugger. When executed,
    since the struct member is not zero, the API attempts an operation using the contents with
    results that are unpredictable and often undesirable.

    There is a 4th case:

         Some structure members are explicitly initialized when declared.  All members omitted from the explicit initialization will be initialized to the appropriate from of 0 (0, '\0', 0.0, or NULL) depending on the type of the member.

    Tuesday, September 22, 2015 9:32 AM