#include "stdafx.h"
#include "PrintWnd.h"
bool PrintWnd(HWND hWnd, dm_Orientation PrintLandscapeOrPortraitOrientation, dm_Color Color_Choice, dm_Duplex DuplexChoice, dm_PrintQuality PrintQuality)
{
CWaitCursor wait;
PRINTDLG pdlg;
memset(&pdlg, 0, sizeof(PRINTDLG));
pdlg.lStructSize = sizeof(PRINTDLG);
pdlg.Flags = PD_RETURNDC;
CDC cdc;
HDC hdcPrinter=NULL;
if (PrintLandscapeOrPortraitOrientation || Color_Choice || DuplexChoice || PrintQuality)
{
BOOL bRet=AfxGetApp()->GetPrinterDeviceDefaults(&pdlg);
if (bRet)
{
DEVMODE FAR *pDevMode=(DEVMODE FAR *)::GlobalLock(pdlg.hDevMode);
if (PrintLandscapeOrPortraitOrientation) pDevMode->dmOrientation=PrintLandscapeOrPortraitOrientation;
if (Color_Choice) pDevMode->dmColor=Color_Choice ;
if (DuplexChoice) pDevMode->dmDuplex=DuplexChoice ;
if (PrintQuality) pDevMode->dmPrintQuality =PrintQuality ;
::GlobalUnlock(pdlg.hDevMode);
}
else return false;
bRet=AfxGetApp()->CreatePrinterDC(cdc);
if (bRet)
{
hdcPrinter = cdc.m_hDC;
}
else return false;
}
else
{
if (!PrintDlg(&pdlg)) return false;
hdcPrinter = pdlg.hDC;
}
if (!hdcPrinter) return false;
HDC hdcwindow = ::GetWindowDC(hWnd);
RECT rc;
GetWindowRect(hWnd,&rc);
OffsetRect(&rc, -rc.left, -rc.top);
int iWidth = GetDeviceCaps(hdcPrinter, HORZRES);
int iHeight = GetDeviceCaps(hdcPrinter, VERTRES);
BITMAPINFO bmi;
LPBYTE pBits;
ZeroMemory(&bmi, sizeof(bmi));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = rc.right; bmi.bmiHeader.biHeight = rc.bottom; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biCompression = BI_RGB;
HBITMAP hbm = CreateDIBSection(hdcwindow, &bmi, DIB_RGB_COLORS, (void **)&pBits, NULL, 0);
if (!hbm)
{
DeleteDC(hdcPrinter);
::ReleaseDC(hWnd,hdcwindow);
return false;
}
HDC hdcMemory = CreateCompatibleDC(hdcwindow);
SelectObject(hdcMemory, hbm);
HANDLE hLogPal = 0;
LPLOGPALETTE lpLogPal;
HDC hDC = ::GetDC(NULL);
HPALETTE hPal = 0;
if (!(::GetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE))
{
::ReleaseDC(NULL, hDC);
hPal = 0;
}
else
{
lpLogPal = (LPLOGPALETTE)::GlobalAlloc(GPTR, sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY));
if (!hLogPal)
{
hPal = 0;
}
{
lpLogPal->palVersion = 0x300; lpLogPal->palNumEntries = 256;
GetSystemPaletteEntries(hDC, 0,
256,(LPPALETTEENTRY)(lpLogPal->palPalEntry));
hPal = CreatePalette(lpLogPal);
GlobalFree(lpLogPal);
::ReleaseDC(NULL, hDC);
}
}
if (hPal)
{
SelectPalette(hdcwindow, hPal, FALSE);
RealizePalette(hdcwindow);
SelectPalette(hdcMemory, hPal, FALSE);
RealizePalette(hdcMemory);
}
BitBlt(hdcMemory, 0, 0, rc.right, rc.bottom, hdcwindow, 0, 0,
SRCCOPY);
DOCINFO di;
ZeroMemory(&di, sizeof(di));
di.cbSize = sizeof(di);
di.lpszDocName = "Window Contents";
if (StartDoc(hdcPrinter, &di) > 0)
{
if (StartPage(hdcPrinter) > 0)
{
DIBSECTION ds;
GetObject(hbm, sizeof(DIBSECTION), &ds);
StretchDIBits(hdcPrinter,0, 0, iWidth, iHeight,0, 0,
rc.right,
rc.bottom,ds.dsBm.bmBits,(LPBITMAPINFO)&ds.dsBmih,
DIB_RGB_COLORS, SRCCOPY);
EndPage(hdcPrinter);
}
EndDoc(hdcPrinter);
}
DeleteDC(hdcPrinter);
DeleteDC(hdcMemory);
::ReleaseDC(hWnd, hdcwindow);
DeleteObject(hbm);
if (hPal) DeleteObject(hPal);
return true;
}
bool PrintWnd(CWnd *cwnd,
dm_Orientation PrintLandscapeOrPortraitOrientation,
dm_Color Color_Choice,
dm_Duplex DuplexChoice,
dm_PrintQuality PrintQuality)
{
return PrintWnd(cwnd->m_hWnd,PrintLandscapeOrPortraitOrientation,Color_Choice,DuplexChoice,PrintQuality);
}
// WriteDIB - Writes a DIB to file
// Returns - TRUE on success
// szFile - Name of file to write to
// hDIB - Handle of the DIB
BOOL WriteDIB( LPCTSTR szFile, HANDLE hDIB)
{
BITMAPFILEHEADER hdr;
LPBITMAPINFOHEADER lpbi;
if (!hDIB)
return FALSE;
CFile file;
if( !file.Open( szFile, CFile::modeWrite|CFile::modeCreate) )
return FALSE;
lpbi = (LPBITMAPINFOHEADER)hDIB;
int nColors = 1 << lpbi->biBitCount;
// Fill in the fields of the file header
hdr.bfType = ((WORD) ('M' << 8) | 'B'); // is always "BM"
hdr.bfSize = GlobalSize (hDIB) + sizeof( hdr );
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD) (sizeof( hdr ) + lpbi->biSize +
nColors * sizeof(RGBQUAD));
// Write the file header
file.Write( &hdr, sizeof(hdr) );
// Write the DIB header and the bits
file.Write( lpbi, GlobalSize(hDIB) );
return TRUE;
}
// DDBToDIB - Creates a DIB from a DDB
// bitmap - Device dependent bitmap
// dwCompression - Type of compression - see BITMAPINFOHEADER
// pPal - Logical palette
HANDLE DDBToDIB( CBitmap& bitmap, DWORD dwCompression, CPalette* pPal )
{
BITMAP bm;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
DWORD dwLen;
HANDLE hDIB;
HANDLE handle;
HDC hDC;
HPALETTE hPal;
ASSERT( bitmap.GetSafeHandle() );
// The function has no arg for bitfields
if( dwCompression == BI_BITFIELDS )
return NULL;
// If a palette has not been supplied use defaul palette
hPal = (HPALETTE) pPal->GetSafeHandle();
if (hPal==NULL)
hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
// Get bitmap information
bitmap.GetObject(sizeof(bm),(LPSTR)&bm);
// Initialize the bitmapinfoheader
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = bm.bmPlanes * bm.bmBitsPixel;
bi.biCompression = dwCompression;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
// Compute the size of the infoheader and the color table
int nColors = (1 << bi.biBitCount);
if( nColors > 256 )
nColors = 0;
dwLen = bi.biSize + nColors * sizeof(RGBQUAD);
// We need a device context to get the DIB from
hDC = GetDC(NULL);
hPal = SelectPalette(hDC,hPal,FALSE);
RealizePalette(hDC);
// Allocate enough memory to hold bitmapinfoheader and color table
hDIB = GlobalAlloc(GMEM_FIXED,dwLen);
if (!hDIB){
SelectPalette(hDC,hPal,FALSE);
ReleaseDC(NULL,hDC);
return NULL;
}
lpbi = (LPBITMAPINFOHEADER)hDIB;
*lpbi = bi;
// Call GetDIBits with a NULL lpBits param, so the device driver
// will calculate the biSizeImage field
GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,
(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
bi = *lpbi;
// If the driver did not fill in the biSizeImage field, then compute it
// Each scan line of the image is aligned on a DWORD (32bit) boundary
if (bi.biSizeImage == 0){
bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
* bi.biHeight;
// If a compression scheme is used the result may infact be larger
// Increase the size to account for this.
if (dwCompression != BI_RGB)
bi.biSizeImage = (bi.biSizeImage * 3) / 2;
}
// Realloc the buffer so that it can hold all the bits
dwLen += bi.biSizeImage;
if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
hDIB = handle;
else{
GlobalFree(hDIB);
// Reselect the original palette
SelectPalette(hDC,hPal,FALSE);
ReleaseDC(NULL,hDC);
return NULL;
}
// Get the bitmap bits
lpbi = (LPBITMAPINFOHEADER)hDIB;
// FINALLY get the DIB
BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
0L, // Start scan line
(DWORD)bi.biHeight, // # of scan lines
(LPBYTE)lpbi // address for bitmap bits
+ (bi.biSize + nColors * sizeof(RGBQUAD)),
(LPBITMAPINFO)lpbi, // address of bitmapinfo
(DWORD)DIB_RGB_COLORS); // Use RGB for color table
if( !bGotBits )
{
GlobalFree(hDIB);
SelectPalette(hDC,hPal,FALSE);
ReleaseDC(NULL,hDC);
return NULL;
}
SelectPalette(hDC,hPal,FALSE);
ReleaseDC(NULL,hDC);
return hDIB;
}
BOOL WriteWindowToDIB( LPCTSTR szFile, HWND hWnd )
{
CWnd Tmp;
Tmp.Attach(hWnd);
BOOL RtrnValue = WriteWindowToDIB(szFile, &Tmp);
Tmp.Detach();
return RtrnValue;
}
BOOL WriteWindowToDIB( LPCTSTR szFile, CWnd *pWnd )
{
CBitmap bitmap;
CWindowDC dc(pWnd);
CDC memDC;
CRect rect;
memDC.CreateCompatibleDC(&dc);
pWnd->GetWindowRect(rect);
bitmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height() );
CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
memDC.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, 0, 0, SRCCOPY);
// Create logical palette if device support a palette
CPalette pal;
if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
{
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
pLP->palVersion = 0x300;
pLP->palNumEntries =
GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry );
// Create the palette
pal.CreatePalette( pLP );
delete[] pLP;
}
memDC.SelectObject(pOldBitmap);
// Convert the bitmap to a DIB
HANDLE hDIB = DDBToDIB( bitmap, BI_RGB, &pal );
if( hDIB == NULL )
return FALSE;
// Write it to file
WriteDIB( szFile, hDIB );
// Free the memory allocated by DDBToDIB for the DIB
GlobalFree( hDIB );
return TRUE;
}
//________________________________________________________________________________
//Contents of PrintWnd.h
typedef enum {NO_Orientation_CHOICE=0,_DMORIENT_PORTRAIT=1,_DMORIENT_LANDSCAPE=2}dm_Orientation;
typedef enum {NO_COLOR_CHOICE=0,_DMCOLOR_MONOCHROME=1,_DMCOLOR_COLOR=2}dm_Color;
typedef enum {NO_Duplex_CHOICE=0,_DMDUP_SIMPLEX=1,_DMDUP_VERTICAL=2,_DMDUP_HORIZONTAL=2}dm_Duplex;
typedef enum {NO_PrintQuality_CHOICE=0,_DMRES_DRAFT=-1,_DMRES_LOW=-2,_DMRES_MEDIUM=-3,_DMRES_HIGH=-4}dm_PrintQuality;
bool PrintWnd(HWND hWnd,
dm_Orientation PrintLandscapeOrPortraitOrientation=NO_Orientation_CHOICE,
dm_Color Color_Choice=NO_COLOR_CHOICE,
dm_Duplex DuplexChoice=NO_Duplex_CHOICE,
dm_PrintQuality PrintQuality=NO_PrintQuality_CHOICE);
bool PrintWnd(CWnd *cwnd,
dm_Orientation PrintLandscapeOrPortraitOrientation=NO_Orientation_CHOICE,
dm_Color Color_Choice=NO_COLOR_CHOICE,
dm_Duplex DuplexChoice=NO_Duplex_CHOICE,
dm_PrintQuality PrintQuality=NO_PrintQuality_CHOICE);
BOOL WriteWindowToDIB( LPCTSTR szFile, HWND hWnd );
BOOL WriteWindowToDIB( LPCTSTR szFile, CWnd *pWnd );
Why is this not working
Can anyone tell me what is wrong with this code? I keep getting error messages and unresolved external symbols as well as a message that tells me that I can't redefine the contents of windows.h
It would make more sense to post the actual error messages that you are getting. On the offhand chance, you're sure that there aren't Windows functions named the same as your functions?
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement