views:

473

answers:

1

I have a chart (in bitmap format) that I'm trying to render to a printer using StretchBlt. When drawing to the screen, StretchBlt works fine. When drawing to a CutePDF printer, it returns 0, sets the last error to ERROR_INVALID_HANDLE, and works anyway. When drawing to a PDF995 printer or a physical HP printer, it returns 0, sets the last error to ERROR_INVALID_HANDLE, and fails to draw anything.

What would cause StretchBlt to fail for certain devices? I've verified that the source bitmap is a DIB and that the destination supports StretchBlt by calling GetDeviceCaps.

Here's my code, in case it's relevant: (It's written in C++Builder, so it uses Delphi's VCL; TCanvas wraps an HDC, and TBitmap wraps an HBITMAP. VCL provides its own StretchDraw function which does not support HALFTONE; I'm getting the same problems with it.)

void PrettyStretchDraw(TCanvas *dest, const TRect& rect, TGraphic *source)
{
  if (dynamic_cast<Graphics::TBitmap*>(source) && !source->Transparent) {
    POINT pt;
    GetBrushOrgEx(dest->Handle, &pt);
    SetStretchBltMode(dest->Handle, HALFTONE);
    SetBrushOrgEx(dest->Handle, pt.x, pt.y, NULL);
    StretchBlt(
      dest->Handle,
      rect.Left,
      rect.Top,
      rect.Width(),
      rect.Height(),
      dynamic_cast<Graphics::TBitmap*>(source)->Canvas->Handle,
      0,
      0,
      source->Width,
      source->Height,
      SRCCOPY);
  } else {
    DrawItSomeOtherWay(dest, rect, source);
  }
}
+2  A: 

StretchBlt is broken on some printer drivers (PDF995 is notable example).

I once encontered this error happening on Windows 2003 Server only (it worked on XP).

Try to reproduce the problem on other OS, and it it does not, consider it OS specific and use StretchDIBits instead on this OS.

Quassnoi
StretchDIBits works, and http://www.codeproject.com/KB/printing/printingtricksandtips.aspx offers code to create a DIB from a GDI bitmap for passing to StretchDIBits. Thanks!
Josh Kelley