Click here to Skip to main content
15,886,518 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
hello, everyone,
i have a quesetion, i want to print my map in the my c++ class CPCToolView,
it is ok by the real printer, but dead with Adobe pdf printer,
and the windows os must restart. i track the flow, find out it has no response at the
windows sdk::StretchBlt(), does not the adobe virtual driver printer support this function?
I hope all can help me. thank you very much.

the codes as belows:
void CPCToolView::OnViewPrint(bool bIsToolPrint)
{
	CPrintDialog MapPrint(FALSE);
	HDC Hbuffer;
	CDC PrintDc;
	CRect rt1;
	GetClientRect(rt1);	
	if(m_hBufferDC==NULL)
	{
		MessageBox(GetUILanguage().LoadUIString
(IDS_CUR_PICTURE_CANNOT_PRINT),m_WwarnTitle);
		return;
	}
	HDC hMemDC = ::CreateCompatibleDC(m_hBufferDC);
	if( hMemDC == NULL )
		return;
	HBITMAP hMemDcBmp = CreateCompatibleBitmap(m_hBufferDC,rt1.Width(), rt1.Height()+18);
	HBITMAP hOldMemBmp = (HBITMAP)::SelectObject(hMemDC,hMemDcBmp);
	if (!bIsToolPrint)
	{
		if (IDCANCEL == OnPrintSet())
		{
			return;
		}
	}
	MapPrint.GetDefaults();
	if (m_pPrintDevmode != NULL)
	{
		MapPrint.m_pd.hDevMode = m_pPrintDevmode; 
		MapPrint.m_pd.hDevNames = m_pPrintDevName;
	}
	Hbuffer=MapPrint.CreatePrinterDC();
	if(Hbuffer==NULL)
	{
		MessageBox(GetUILanguage().LoadUIString
(IDS_MSG_UNCONNECT_TO_PRINTER),m_WwarnTitle);
	  return;
	}
	PrintDc.Attach(Hbuffer);
	DEVMODE* pPrintDevModeInfo;
// 	UINT32 nPrintWidth;
// 	UINT32 nPrintHeight;
	UINT32 nPrintDCWidth;
	UINT32 nPrintDCHeight;
// 	UINT32 nUnPrintWidth;
// 	UINT32 nUnPrintHeight;
	int nXPtDPI = GetDeviceCaps(Hbuffer,LOGPIXELSX);
	int nYPtDPI = GetDeviceCaps(Hbuffer,LOGPIXELSY);
	nPrintDCWidth = GetDeviceCaps(Hbuffer,HORZSIZE)*10;
	nPrintDCHeight = GetDeviceCaps(Hbuffer,VERTSIZE)*10;
	pPrintDevModeInfo = (LPDEVMODE)GlobalLock(MapPrint.m_pd.hDevMode); 
	::GlobalUnlock(MapPrint.m_pd.hDevMode); 
	nPrintDCWidth = nPrintDCWidth*100/254.0 -1;
	nPrintDCHeight = nPrintDCHeight*100/254.0 -1;
	PrintDc.SetMapMode(MM_LOENGLISH);
	PrintDc.SetWindowOrg(0,0);
	PrintDc.SetWindowExt(nPrintDCWidth,nPrintDCHeight);
	PrintDc.SetViewportOrg(0,0);
	PrintDc.SetViewportExt(nPrintDCWidth,nPrintDCHeight);
	PrintDc.SetStretchBltMode(HALFTONE);
	PrintDc.SetBrushOrg(0,0);

//if move these draw functions in front of sentence(PrintDc.Attach(Hbuffer);)
//it will not dead, but the out map printing picture is all black with nothing.
	DrawBakMap(hMemDC,TRUE);
	DrawGrid(hMemDC,TRUE);
	DrawScale(hMemDC,TRUE);
	DrawUserDataPt(hMemDC,TRUE);
	DrawUserDataCB(hMemDC,TRUE);
	DrawUserDataNL(hMemDC,TRUE);
	DrawUserDataTrack(hMemDC,TRUE);
	PrintDrawIcon(hMemDC,rt1);
	double dPictureRadio = rt1.Height()/rt1.Width();
	double dPrintDcRadio = nPrintDCHeight/nPrintDCWidth;
	if (dPictureRadio > dPrintDcRadio)
	{
		nPrintDCWidth = nPrintDCHeight*rt1.Width()/rt1.Height();
	}
	else
	{
		nPrintDCHeight = nPrintDCWidth*rt1.Height()/rt1.Width();
	}	
	PrintDc.StartDoc(_T("test"));
	PrintDc.StartPage();
	::StretchBlt(Hbuffer,0,0,nPrintDCWidth,-nPrintDCHeight,hMemDC,0,0,rt1.Width(),rt1.Height
(),SRCCOPY);
	PrintDc.EndPage();
	PrintDc.EndDoc();
	hMemDcBmp = (HBITMAP)::SelectObject(hMemDC,hOldMemBmp);
	if (hMemDC)
	{
		DeleteDC(hMemDC);
	}
	PrintDc.DeleteDC
Posted
Updated 20-Sep-11 17:27pm
v2
Comments
Prerak Patel 20-Sep-11 23:27pm    
Corrected code block

You also need to check your error handling code. In cases where things get cancelled you are leaking HDC and bitmap resources.
HDC hMemDC = ::CreateCompatibleDC(m_hBufferDC);
if( hMemDC == NULL )
    return;
HBITMAP hMemDcBmp = CreateCompatibleBitmap(m_hBufferDC,rt1.Width(), rt1.Height()+18);
HBITMAP hOldMemBmp = (HBITMAP)::SelectObject(hMemDC,hMemDcBmp);
if (!bIsToolPrint)
{
    if (IDCANCEL == OnPrintSet())
    {
        // leaking resources here
        return;
    }
}
 
Share this answer
 
first, thanks all
now i got the solution, i guess the adobe do not support the advanced
StretchBlt
function, and i used
SetDIBitsToDevice
instead of, and it's ok.

thank all guys.
 
Share this answer
 
StretchBlt[^] returns a BOOL, so check for its return value and only proceed when it returns TRUE.
When FALSE is returned use the GetLastError[^] function and see what the error returned is. You can then proceed from there.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900