What I have done is similar to
http://groups.google.com/group/microsoft.public.win32.programmer.directx/browse_thread/thread/79faf1222abafdce/08ee4eb61ed97ce1?lnk=gst&q=printing&rnum=58#08ee4eb61ed97ce1
1. Get the hDC from the BackSurface
2. Create a compatible memory image DC
3. StretchBlt the BackSurface contents to the memory image whose size
I have determined from the print page's size
4. Next BitBlt to printer DC (The memory image was needed coz you
can't StretchBlt to a printer DC)
PROBLEM : I am losing all color information on the printed image !
-------------------------------------------------------------------------------------------------
I tried a few things
- BitBlt directly from DD Surface DC to Printer DC
Result : Get a miniscule image but with color when printed
- BitBlt from DD Surface DC to Memory Image of same size as surface
and then BitBlt to Printer
Result : Get a miniscule image but all black n white
- BitBlt from DD Surface DC to Memory image (scaled up so as to best
fit the page) and then BitBlt to printer DC
Result : Get a properly scaled image but all black n white
This leads me to believe that the middle step of transferring onto a
Memory Image is losing all the Color.
Any ideas / pointers / suggestions most welcome..
Thanks,
Gishu
Code - Last approach:
HDC hDC_BackSurface;
hrRetVal = m_DDSBack->GetDC(&hDC_BackSurface);
CDC* pobSurfaceDC = CDC::FromHandle(hDC_BackSurface);
CDC* pobPrinterDC = CDC::FromHandle(hDC_Printer);
HDC hDC_TempMemImage = ::CreateCompatibleDC(hDC_BackSurface);
HBITMAP hBmp_MemImage = ::CreateCompatibleBitmap(hDC_TempMemImage,
iPrintableAreaWidth, iPrintableAreaHeight);
HGDIOBJ hOldGDIObj = ::SelectObject(hDC_TempMemImage, (HGDIOBJ)
hBmp_MemImage);
if (!::StretchBlt(hDC_TempMemImage,
0,0, iPrintableAreaWidth, iPrintableAreaHeight,
hDC_BackSurface,
0, 0, obSurfaceDesc.dwWidth, obSurfaceDesc.dwHeight,
SRCCOPY))
{
OutputDebugString( _T("StretchBlt to memory image failed!"));
}
if (!pobPrinterDC->BitBlt(
rectPrintArea.left, rectPrintArea.top, iPrintableAreaWidth,
iPrintableAreaHeight,
CDC::FromHandle(hDC_TempMemImage),
0, 0, // Source top-left corner
SRCCOPY))
{
OutputDebugString(_T("BitBlt to Printer failed!"));
}
SelectObject(hDC_TempMemImage, hOldGDIObj);
DeleteDC(hDC_TempMemImage);
m_DDSBack->ReleaseDC(hDC_BackSurface);
HBITMAP hBmp_MemImage = ::CreateCompatibleBitmap(hDC_TempMemImage,
iPrintableAreaWidth, iPrintableAreaHeight);
should be
HBITMAP hBmp_MemImage = ::CreateCompatibleBitmap( hDC_BackSurface,
iPrintableAreaWidth, iPrintableAreaHeight);
to create a bitmap with the same attributes as the Rendered Viewport.
Posting so that it helps the next guy.
-- Gishu
void CView::PrintBackSurfaceContents(HDC hDC_Printer, RECT
rectPrintArea)
{
HDC hDC_BackSurface;
HRESULT hrRetVal = m_DDSBack->GetDC(&hDC_BackSurface);
// get surface dimensions
DDSURFACEDESC obSurfaceDesc;
ZeroMemory(&obSurfaceDesc, sizeof(obSurfaceDesc));
obSurfaceDesc.dwSize = sizeof(obSurfaceDesc);
hrRetVal = m_DDSBack->GetSurfaceDesc(&obSurfaceDesc);
if (FAILED(hrRetVal))
{ return; }
// create 24 bit color Bitmap
BITMAPINFO obBmpInfo;
ZeroMemory(&obBmpInfo, sizeof(BITMAPINFO));
obBmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
obBmpInfo.bmiHeader.biWidth = obSurfaceDesc.dwWidth;
obBmpInfo.bmiHeader.biHeight = obSurfaceDesc.dwHeight;
obBmpInfo.bmiHeader.biPlanes = 1;
obBmpInfo.bmiHeader.biBitCount = 24;
obBmpInfo.bmiHeader.biCompression = BI_RGB;
LPBYTE pBits;
HBITMAP hBmpMemImage = CreateDIBSection(hDC_BackSurface,
&obBmpInfo, DIB_RGB_COLORS, (void**)&pBits, NULL, 0);
// Select bitmap to a DC compatible with back surface
HDC hDC_MemImage = ::CreateCompatibleDC(hDC_BackSurface);
::SelectObject(hDC_MemImage, hBmpMemImage);
// create Palette and apply to both source and dest
if (!(GetDeviceCaps(hDC_BackSurface, RASTERCAPS) & RC_PALETTE))
{
goto FunctionExit;
}
LPLOGPALETTE lpLogPal = (LPLOGPALETTE) ::GlobalAlloc(GPTR,
sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY));
if (!lpLogPal)
{
goto FunctionExit;
}
lpLogPal->palVersion = 0x300;
lpLogPal->palNumEntries = 256;
::GetSystemPaletteEntries(hDC_BackSurface, 0 , 256, lpLogPal-
>palPalEntry);
HPALETTE hPalette = ::CreatePalette(lpLogPal);
::GlobalFree(lpLogPal);
if (hPalette)
{
::SelectPalette(hDC_BackSurface, hPalette, FALSE);
::RealizePalette(hDC_BackSurface);
::SelectPalette(hDC_MemImage, hPalette, FALSE);
::RealizePalette(hDC_MemImage);
}
// Blit bits from Back Buffer to Temp Memory Bitmap
::BitBlt(hDC_MemImage,
0,0, obSurfaceDesc.dwWidth, obSurfaceDesc.dwHeight,
hDC_BackSurface,
0,0,
SRCCOPY);
DIBSECTION obDIBSection;
::GetObject(hBmpMemImage, sizeof(DIBSECTION), &obDIBSection );
// Stretch Memory Bitmap to Scaled up Print dimensions
RECT rectBestFit = GetBestFitArea(rectPrintArea,
obSurfaceDesc.dwWidth, obSurfaceDesc.dwHeight);
::StretchDIBits(hDC_Printer,
rectBestFit.left,rectBestFit.top, (rectBestFit.right-
rectBestFit.left), (rectBestFit.bottom-rectBestFit.top),
0,0, obSurfaceDesc.dwWidth, obSurfaceDesc.dwHeight,
obDIBSection.dsBm.bmBits,
(LPBITMAPINFO) &obDIBSection.dsBmih,
DIB_RGB_COLORS,
SRCCOPY);
FunctionExit:
// CleanUp
if (0 != hDC_MemImage)
{
::DeleteDC( hDC_MemImage );
}
if (0 != hBmpMemImage)
{
::DeleteObject(hBmpMemImage);
}
if (0 != hPalette)
{
::DeleteObject(hPalette);
}
m_DDSBack->ReleaseDC(hDC_BackSurface);
}