GetTextExtentPoint32 fails on Printer...

If I call hdc = CreateCompatibleDC(hPrinterDC), assuming the printerDC is valid, and then call GetTextExtentPoint(hdc,...), this call crashes the computer everytime. GetTextExtentPoint32 also crashes, but I need to know the size (height and width) of a string for size it will be on the printer. This code works fine for the screen when I am not printing.

What am I doing wrong?

Jordan Pinsker
pinskerj@vu.union.edu
jordanpAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
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.

NickRepinCommented:
CreateCompatibleDC() can only be used with devices that support raster operations. You can determine whether a printer supports these operations by calling the GetDeviceCaps(hPrinterDC,RASTERCAPS) function. Do you check hdc!=NULL?Also, why do not to use GetTextExtentPoint32(hPrinterDC)?See also MS knowledge base article Q22553.
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
jordanpAuthor Commented:
Your proposed answer helped a little but did not solve my overall problem. Maybe this will explain things better.

I am creating a bitmap based on the PrinterDC. I draw text to this bitmap to rotate it, and then draw the bitmap to a certain portion of the printed page. Thus, for this to work just as it does for my print preview, I need to create a comaptibleDC for the printer.

I used your suggestion and only changed the GetTextExtentPoint32 to use hPrinterDC, and created the bitmap by calling createcompatiblebitmap(hPrinterDC), but for whatever reason the text is becoming corrupted when printing (it appears that the bitmap is too large and it is printing garbage after the text). I am not sure if this is caused by the differences between the printer and the page as it works fine on screen. Here is my function below:

HANDLE GetRotateText (char * TextName, HWND TitleText, BOOL      left)
     {
     static LOGFONT lf ;
     HBITMAP        hBitmap ;
     HDC            hdc, hdcMem ;
     HFONT          hFont ;
     SIZE           size ;
     CHARFORMAT         CF;
        BITMAPINFOHEADER      bi;
      
       if (gPrinter == true) // we are using the printer, not screen
               SetMapMode(hPrinterDC,MM_TEXT);
      
     CF.cbSize = sizeof(CF);
        SendMessage (TitleText,EM_GETCHARFORMAT, 1, (LPARAM)&CF);

     hdc = CreateIC ("DISPLAY", nil, nil, nil);
     hdcMem = CreateCompatibleDC (hdc);
     
     lf.lfUnderline = (CF.dwEffects & CFE_UNDERLINE);
     lf.lfStrikeOut =  (CF.dwEffects & CFE_STRIKEOUT);
     if (CF.dwEffects & CFE_BOLD)
       lf.lfWeight = 700;
     else
       lf.lfWeight = 400;
       lf.lfItalic = (CF.dwEffects & CFE_ITALIC);

            // Get the size of the text...
       if (false == gPrinter)
             lf.lfHeight = -MulDiv(CF.yHeight/20, GetDeviceCaps(hdcMem,
LOGPIXELSY), 72);
       else
             lf.lfHeight = -MulDiv(CF.yHeight/20, GetDeviceCaps(hPrinterDC,
LOGPIXELSY), 72);

     lstrcpy ((char *) lf.lfFaceName, CF.szFaceName) ;
         
 hFont = (HFONT) SelectObject (hdcMem, CreateFontIndirect (&lf));
     if (false == gPrinter)
           {
                 GetTextExtentPoint32 (hdcMem, TextName, strlen (TextName), &size);
                hBitmap = CreateCompatibleBitmap (hdcMem, size.cy, size.cx) ;//switch x,y for rotation...
            }
     else
           {
                 GetTextExtentPoint32 (hPrinterDC, TextName, strlen (TextName),
&size);
                  hBitmap = CreateCompatibleBitmap (hPrinterDC, size.cy, size.cx) ;//switch x,y for rotation...
            }
         
     if (left)
     lf.lfEscapement = lf.lfOrientation = 900 ;//90 degrees
     else
     lf.lfEscapement = lf.lfOrientation = 2700 ;//270 degrees
   
     SelectObject (hdcMem, hBitmap) ;
       hFont = (HFONT) SelectObject (hdcMem, CreateFontIndirect (&lf));

       if (left)
             TextOut (hdcMem, 0,size.cx, TextName, strlen (TextName));
       else
        TextOut (hdcMem, size.cy,0, TextName, strlen (TextName))      
     
DeleteObject (SelectObject (hdcMem, hFont)) ;
     DeleteDC (hdcMem) ;
     DeleteDC (hdc) ;
      
       if (gPrinter == true) // return to twips for the printer...
               SetMapMode(hPrinterDC,MM_TWIPS);
      
 // Now convert the bitmap to a dib and return it...
       bi.biSize = sizeof(BITMAPINFOHEADER);
       bi.biWidth = size.cy;
     bi.biHeight = size.cx;
     bi.biPlanes = 1;
     bi.biBitCount = 16;
     bi.biCompression = BI_RGB;
     bi.biSizeImage = 0;
     bi.biXPelsPerMeter = 0;
     bi.biYPelsPerMeter = 0;
     bi.biClrUsed = 0;
     bi.biClrImportant = 0;
      
       return (DibFromBitmap (hBitmap,BI_RGB,32,CreateBIPalette (&bi)));

           // must dipose of old bitmap before return hBitmap; not done yet
     }



0
NickRepinCommented:
It seems that you use Win95, don't you?
There is no problem to rotate text in WinNT.

As to your code,

1) you should select font on printerDC to call GetTextExtentPoint:

   hFont = (HFONT) SelectObject (hdcMem, CreateFontIndirect (&lf));
   hPrinterDC = (HFONT) SelectObject (hPrinterDC, CreateFontIndirect (&lf));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   if (false == gPrinter) {
      GetTextExtentPoint32 (hdcMem, TextName, strlen (TextName), &size);
      hBitmap = CreateCompatibleBitmap (hdcMem, size.cy, size.cx) ;//switch x,y for rotation...
   }
   else {
      GetTextExtentPoint32 (hPrinterDC, TextName, strlen (TextName),&size);
      hBitmap = CreateCompatibleBitmap (hPrinterDC, size.cy, size.cx) ;//switch x,y for rotation...
   }

2) in my opinion, you should swap lines with TextOut in following code:

   if (left)
      // 90 degrees, from top to bottom
      TextOut (hdcMem, 0,size.cx, TextName, strlen (TextName));
   else
      // 270 degrees, from bottom to top
      TextOut (hdcMem, size.cy,0, TextName, strlen (TextName));

3) why do not to print directly to hPrinterDC (or to screen) by TextOut  with lf.lfEscapement=lf.lfOrientation != 0 ?

0
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.