我做一个打印程序,结果在预览窗口中不能正确分页,这个程序是从一个数据库中取值进行打印。请各位高手帮忙看看,不剩感激!!!
void CSearchTurnover::MyPrint(CDC *pDC, CPrintInfo *pInfo)
{
//pDC->SetMapMode(MM_TEXT); pDC->DPtoLP(&pInfo->m_rectDraw); 
m_strReportTitle="报表程序";
m_strReportFooter="页数";
// int nWidth=pDC->GetDeviceCaps(HORZRES);
// int nHeight=pDC->GetDeviceCaps(VERTRES);
int nWidth = pDC->GetDeviceCaps(PHYSICALWIDTH)- 2*(pDC->GetDeviceCaps(PHYSICALOFFSETX));
int nHeight = pDC->GetDeviceCaps(PHYSICALHEIGHT)- 2*(pDC->GetDeviceCaps(PHYSICALOFFSETY));
int ghdf=pDC->GetDeviceCaps(LOGPIXELSY); CFont TitleFont, HeadingFont, DetailFont, FooterFont;
//字体大小设置
m_uSizeTitle=-MulDiv(32,-pDC->GetDeviceCaps(LOGPIXELSY),72);
m_uSizeContentHead=-MulDiv(12,-pDC->GetDeviceCaps(LOGPIXELSY),72);
m_uSizeContent=-MulDiv(9,-pDC->GetDeviceCaps(LOGPIXELSY),72);
m_uSizeFooter=-MulDiv(12,-pDC->GetDeviceCaps(LOGPIXELSY),72);

//字体创建
m_strFontTitle=_T("黑体");
m_strFontContentHead=_T("宋体");
m_strFontContent=_T("宋体");
m_strFontFooter=_T("宋体"); TitleFont.CreateFont(m_uSizeTitle, 0, 0, 0, FW_BOLD, FALSE, FALSE, 0,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, 
m_strFontTitle);
HeadingFont.CreateFont(m_uSizeContentHead, 0, 0, 0, FW_BOLD, FALSE, TRUE, 0,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, 
m_strFontContentHead);
DetailFont.CreateFont(m_uSizeContent, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, 
m_strFontContent);
FooterFont.CreateFont(m_uSizeFooter, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_ROMAN, 
m_strFontFooter); CRect DrawRect(0,0,nWidth,nHeight),rect,tempRect;
// DrawRect.InflateRect(-100,-50,-100,-20); DrawRect.left+=nWidth/20;
DrawRect.right-=nWidth/20;
DrawRect.top+=nHeight/20;
DrawRect.bottom-=nHeight/20; if (pInfo->m_nCurPage==1) 
pDC->SetWindowOrg(0,0);
// pDC->SetWindowExt(1000,1000);
// pDC->SetViewportOrg(DrawRect.left,DrawRect.top);
// pDC->SetViewportExt(DrawRect.right,DrawRect.bottom); int LineHeight;
CString line;
int y = DrawRect.top;//y值控制整个页面的纵象大小
int length=0;
int height=0;
int hangshu=0;//页行数
int FooterTabStops[] = {350};
int wordlen;
LPDEVMODE mode=pInfo->m_pPD->GetDevMode();
//分横向和纵象打印
if(mode->dmOrientation==DMORIENT_LANDSCAPE)
wordlen=DrawRect.Width()/20;//字体长度
else
wordlen=DrawRect.Width()/10;
//查找数据库字段
if(hSearchCondition=="")
return;
// 标题 TEXTMETRIC metrics;
CFont *OldFont = pDC->SelectObject(&TitleFont);
pDC->GetTextMetrics(&metrics);
pDC->DrawText(m_strReportTitle,DrawRect,DT_TOP|DT_CENTER);
LineHeight = metrics.tmHeight + metrics.tmExternalLeading;
y += LineHeight;
// 表头
// 字段填充
pDC->SelectObject(&DetailFont);
pDC->GetTextMetrics(&metrics);
LineHeight = metrics.tmHeight + metrics.tmExternalLeading; //计算最大页数
int islongest=0;
for(int i=0;i<m_pListResult.GetItemCount();i++)
{
for(int j=0;j<m_pListResult.GetHeaderCtrl()->GetItemCount();j++)
{
CString value;
value=m_pListResult.GetItemText(i,j);
islongest=value.GetLength()>islongest?value.GetLength():islongest;
}
//height 为每个输出行的最大高度
//pagenum为最大页数
//hangshu 为每页行数
height+=(islongest/20+3)*LineHeight;
hangshu++;
if(height>nHeight-200)
{
rowperpage.Add(hangshu);
islongest=0;
height=y;
hangshu=0;
pagenum+=1;
}

}
pInfo->SetMaxPage(pagenum+1); //标题与表头空一行
y += LineHeight;
line.Empty(); 
CString strValue;
if(pNowRec>m_pListResult.GetItemCount())
pNowRec=0;
if(0<pResultArray.GetSize())
{
for(int j=0;j<pResultArray.GetSize()-1;j++)
{
strValue=pResultArray.GetAt(j);
strValue.TrimLeft();
strValue.TrimRight();
pDC->TextOut(DrawRect.left+wordlen*j,y,strValue);
}
y += LineHeight;
//表头与内容空一行
y += LineHeight;
} //填充提取数据
// y=DrawRect.top;
CStringArray resulttext;
for( i=pNowRec;i<m_pListResult.GetItemCount();i++)
{
CString value;
int n=0; if (pInfo && abs(y)+DrawRect.Height()/20 > DrawRect.bottom) 
{
// pInfo->m_nCurPage = pInfo->m_nCurPage + 1;
// pInfo->SetMaxPage(pInfo->m_nCurPage + 1);
if(pInfo->m_nCurPage>1)
{
int v_length;
// v_length=(pInfo->m_nCurPage-1)*(pInfo->m_rectDraw.Height()+200)+400; 
// v_length=(pInfo->m_nCurPage-1)*nHeight+nHeight/20; 
v_length=(pInfo->m_nCurPage-1)*nHeight;

pDC->SetWindowOrg(pInfo->m_rectDraw.left,v_length);

pDC->SetViewportOrg(DrawRect.left,DrawRect.top);
pDC->SetViewportExt(DrawRect.right,DrawRect.bottom);
}
else if(pInfo->m_nCurPage==1)
{
pDC->SetWindowOrg(0,0);
pDC->SetViewportOrg(DrawRect.left,DrawRect.top);
pDC->SetViewportExt(DrawRect.right,DrawRect.bottom);
}
}
if(abs(y)>DrawRect.Height()*pInfo->m_nCurPage)
{
pNowRec=i;
break;
}
resulttext.RemoveAll();
for(int j=0;j<m_pListResult.GetHeaderCtrl()->GetItemCount();j++)
{
value=m_pListResult.GetItemText(i,j);
resulttext.Add(value);
}
CRect textrect;
int length= 0;
// for(int y=rect.top;y+LineHeight<rect.bottom;y+=LineHeight)
// for(int x=DrawRect.left;x+700<DrawRect.right;x+=700)
int x=DrawRect.left;int m=0;int result=0;int linage;
while(m<resulttext.GetSize())
{
//对字串进行处理时,每行长度由wordlen控制
//则转行数输出计算由字串长度/wordlen
//共有行数linage*LineHeight为字串共占有行数维度大小
textrect.left=x;
textrect.top=y;
x+=wordlen;
linage=resulttext.GetAt(m).GetLength()/20+3;
textrect.right=x;
textrect.bottom=y+LineHeight*linage;
pDC->DrawText(resulttext.GetAt(m),textrect,DT_TOP|DT_WORDBREAK);
result=textrect.bottom>=result?textrect.bottom:result;
// pDC->DrawText(resulttext.GetAt(i),textrect,DT_CALCRECT);
length++;m++;
}
y=result+10;//行与行间留一定空隙
} // 页角
if (pInfo) 
{
pDC->SelectObject(&FooterFont);
line.Format("%s : %d ", m_strReportFooter, pInfo->m_nCurPage);
pDC->DrawText(line,DrawRect,DT_BOTTOM |DT_RIGHT|DT_SINGLELINE);
}
pDC->LPtoDP(&pInfo->m_rectDraw);  pDC->SelectObject(OldFont);
}

解决方案 »

  1.   

    打印类源代码
    http://www.vckbase.com/code/viewcode.asp?id=1567
    more
    http://www.vckbase.com/code/listcode.asp?mclsid=5&sclsid=511
      

  2.   

    提供一个我用来打印话单的简单例子:
    if(m_List.GetItemCount()==0)
    return;
    CPrintDialog Print(false);
    if(Print.DoModal()==IDOK)
    {
    HDC hdc=Print.CreatePrinterDC();
    CDC pDC;
    pDC.Attach(hdc);
    int nItem=0,nItemCount,nPage=0;
    nItemCount=m_List.GetItemCount();
    pDC.StartDoc("话单打印");
    pDC.SetMapMode(MM_LOENGLISH);
    for(;nItem<m_List.GetItemCount();)
    {
    pDC.StartPage();
    int m_xStart=30,m_yStart=-30,m_offset=0;
    pDC.TextOut(m_xStart+m_offset,m_yStart,"话机号码");
    m_offset+=120;
    pDC.TextOut(m_xStart+m_offset,m_yStart,"主叫(被叫)号码");
    m_offset+=160;
    pDC.TextOut(m_xStart+m_offset,m_yStart,"通话开始时间");
    m_offset+=180;
    pDC.TextOut(m_xStart+m_offset,m_yStart,"通话时长");
    m_offset+=110;
    pDC.TextOut(m_xStart+m_offset,m_yStart,"通话费用");
    m_offset+=110;
    pDC.TextOut(m_xStart+m_offset,m_yStart,"通话类型"); CPen NewPen(PS_SOLID,2,RGB(0,0,0));
    pDC.SelectObject(&NewPen);
    pDC.MoveTo(0,-50);
    pDC.LineTo(m_xStart+m_offset+80,-50);
    CPen OldPen(PS_SOLID,1,RGB(0,0,0));
    pDC.SelectObject(OldPen); m_yStart=-60;
    nPage++;
    for(;nItem<nItemCount;nItem++)
    {
    m_offset=0;
    pDC.TextOut(m_xStart+m_offset,m_yStart,m_List.GetItemText(nItem,0));
    m_offset+=120;
    pDC.TextOut(m_xStart+m_offset,m_yStart,m_List.GetItemText(nItem,2));
    m_offset+=160;
    pDC.TextOut(m_xStart+m_offset,m_yStart,m_List.GetItemText(nItem,3));
    m_offset+=180;
    pDC.TextOut(m_xStart+m_offset,m_yStart,m_List.GetItemText(nItem,4));
    m_offset+=110;
    pDC.TextOut(m_xStart+m_offset,m_yStart,m_List.GetItemText(nItem,5));
    m_offset+=110;
    pDC.TextOut(m_xStart+m_offset,m_yStart,m_List.GetItemText(nItem,6));
    m_yStart-=20;
    if(nItem+1>=nPage*60)
    {
    pDC.EndPage();
    break;
    }
    }
    }
    pDC.EndPage();
    pDC.EndDoc();
    }