如何使用MFC讲CListCtrl中内容输出到打印机,需要描画表格以及Header?急
也就是说如何将创建的CListView中显示的全部内容输出到打印机(包括表格)

解决方案 »

  1.   

    http://www.china-askpro.com/msg43/qa13.shtml
    参考一下吧
    这个是CTreeCtrl的,原理是一样的
      

  2.   

    BOOL PrintListCtrl(CListCtrl &list)
    {
    PRINTDLG pd ;
    pd.lStructSize = sizeof(PRINTDLG) ;
    pd.Flags = PD_RETURNDC ;
    pd.hDC = NULL ;
    pd.hwndOwner = NULL ;
    pd.hInstance = NULL ;
    pd.nMaxPage = 1 ;
    pd.nMinPage = 1 ;
    pd.nFromPage = 1 ;
    pd.nToPage  = 1 ;
    pd.nCopies = 1 ;
    pd.hDevMode = NULL ; 
    pd.hDevNames = NULL ;

    //显示打印对话框,由用户来设定纸张大小等。
    if ( !PrintDlg( &pd ) ) return FALSE ; 
    ASSERT( pd.hDC != NULL ) ;

    int nHorRes = GetDeviceCaps( pd.hDC , HORZRES ) ;
    int nVerRes = GetDeviceCaps( pd.hDC , VERTRES ) ;
    int nXMargin = 2 ;
    int nYMargin = 2 ;
    TEXTMETRIC tm ;
    GetTextMetrics( pd.hDC , &tm ) ;
    int nCharHeight = tm.tmHeight ;
    int nCharWidth = tm.tmAveCharWidth ;

    //以下是设置字体大小--------------------------------------------------------------
        short cxInch = GetDeviceCaps( pd.hDC , LOGPIXELSX ) ;
    short cyInch = GetDeviceCaps( pd.hDC , LOGPIXELSY ) ;

    // 取当前字体大小

    CDC *pDC = new CDC ;
    pDC->Attach( pd.hDC ) ;

    CFont *curFont = pDC->GetCurrentFont() ;

    LOGFONT curLogFont ;
    LOGFONT newLogFont ;

    curFont->GetLogFont( &curLogFont );
    long NewFontWidth = curLogFont.lfWidth;
    long NewFontHeight = curLogFont.lfHeight;

    newLogFont = curLogFont;

    //计算新的字体大小 扩大一倍
    newLogFont.lfWidth = ( long) ( ( float ) NewFontWidth * 2 * ( ( float ) cxInch / 72.0 ) ) ;
    newLogFont.lfHeight = (long) ( ( float ) NewFontHeight * 2 * ( ( float ) cyInch / 72.0) ) ; 
    //创建并设置新的字体,保留以前的字体

    NewFontWidth = newLogFont.lfWidth ;
    NewFontHeight = newLogFont.lfHeight ;

    CFont newFont;
    CFont *oldFont = new CFont ;

    newFont.CreateFontIndirect( &newLogFont );

    oldFont = ( CFont * )pDC->SelectObject( &newFont ) ;

    //设置字体大小到此--------------------------------------------------------------//


    CHeaderCtrl* pHeader = list.GetHeaderCtrl() ;
    //获得行,列的个数
    int nColCount = pHeader->GetItemCount() ;
    int nLineCount = list.GetItemCount() ;

    int ColOrderArray[100] ;
    COLATT ca[100] ;
    list.GetColumnOrderArray( ColOrderArray , nColCount ) ;
    int nColX = nXMargin * nCharWidth ;

    //检索各列的信息,确定列标题的内容长度。
    for(int i = 0 ; i < nColCount - 1 ; i++ )
    {
    ca[i].nColIndex = ColOrderArray[i] ;
    LVCOLUMN lvc ;
    char text[100] ;
    lvc.mask = LVCF_TEXT | LVCF_SUBITEM ;
    lvc.pszText = text ;
    lvc.cchTextMax = 100 ;
    list.GetColumn( ca[i].nColIndex , &lvc ) ;
    ca[i].strColText = lvc.pszText ;
    ca[i].nSubItemIndex = lvc.iSubItem ;
    ca[i].nPrintX = nColX;
    nColX += ( nCharWidth * strlen( ca[i].strColText ) ) ;

    if ( nColX > nHorRes ) 
    {
    DeleteDC( pd.hDC ) ;
    AfxMessageBox( "字段太多,无法在一行内打印,请试用较大的纸,或横向打印." ) ;
    return FALSE ;
    }
    }
    DOCINFO di ;
    di.cbSize = sizeof( DOCINFO ) ;
    di.lpszDocName = "ListCtrl Data Printing"; 
    di.lpszOutput = (LPTSTR) NULL ; 
    di.lpszDatatype = (LPTSTR) NULL ; 
    di.fwType = 0 ; 
    StartDoc( pd.hDC , &di ) ;
    StartPage( pd.hDC ) ;

    //调整各列的宽度,以使各列在后面的打印输出时更均匀的打印在纸上。
        int space = ( nHorRes - nXMargin * nCharWidth - nColX ) / ( nColCount - 2 ) ;
    /*
    for (i = 0 ; i < nColCount ; i++ )
    {
    ca[i].nPrintX += ( i * space ) ;
    }*/
    ca[0].nPrintX -= 3 * nCharWidth ;
    ca[1].nPrintX += ( space - 8 * nCharWidth ) ;

    for ( i = 2 ; i < nColCount - 1 ; i++ )
    {
    ca[i].nPrintX += ( i * space ) ;
    }

    //输出大标题
    //---------------------------------------------------------------------------
    TextOut(pd.hDC , 50 * nCharWidth , nYMargin , "报警记录" , strlen( "报警记录" ) ) ;
    //-------------------------------------------------------------------------
    pDC->SelectObject( oldFont ) ;

    //输出列标题
    for ( i = 0 ; i < nColCount - 1 ; i++ )
    TextOut( pd.hDC , ca[i].nPrintX , nYMargin + NewFontHeight + nCharHeight , 
    ca[i].strColText , strlen( ca[i].strColText ) ) ;

    int nMaxLinePerPage = nVerRes / nCharHeight - 3 ;
    int nCurPage = 1 ;
    //输出各列的数据
    for (i = 1 ; i < nLineCount ; i++ )
    {
    for ( int j = 0 ; j < nColCount - 1 ; j++ )
    {
    if ( i + 1 - ( nCurPage - 1 ) * nMaxLinePerPage > nMaxLinePerPage )
    {
    //新的一页
    EndPage( pd.hDC ) ;
    StartPage( pd.hDC ) ;
    nCurPage ++ ;
    }
    CString subitem = list.GetItemText( i , ca[j].nSubItemIndex ) ;
    TextOut( pd.hDC , ca[j].nPrintX , 
    nYMargin + ( i + 1 - ( nCurPage - 1 ) * nMaxLinePerPage ) * nCharHeight + NewFontHeight , 
    subitem , strlen( subitem ) ) ;
    }
    }

    EndPage( pd.hDC ) ;
    EndDoc( pd.hDC ) ;
    //打印结束
    pDC->Detach() ;
    DeleteDC( pd.hDC ) ;
    DeleteDC( pDC->m_hDC ) ;

    return TRUE ;
    }
      

  3.   

    COLATT 在这里是一个结构吧,
    能贴出来吗?
      

  4.   

    //该结构用于存储各列的信息
    typedef struct tagColAtt
    {
    int nColIndex;
    CString strColText;
    int nPrintX;
    int nSubItemIndex;
    }COLATT;BOOL PrintListCtrl(CListCtrl &list)
    { PRINTDLG pd;
    pd.lStructSize = sizeof(PRINTDLG);
    pd.Flags = PD_RETURNDC;
    pd.hDC = NULL;
    pd.hwndOwner = NULL;
    pd.hInstance = NULL;
    pd.nMaxPage = 1;
    pd.nMinPage = 1;
    pd.nFromPage = 1;
    pd.nToPage  = 1;
    pd.nCopies = 1;
    pd.hDevMode = NULL;
    pd.hDevNames = NULL; //显示打印对话框,由用户来设定纸张大小等。
    if(!PrintDlg(&pd)) return FALSE; 
    ASSERT(pd.hDC!=NULL); int nHorRes = GetDeviceCaps(pd.hDC, HORZRES);
    int nVerRes = GetDeviceCaps(pd.hDC, VERTRES);
    int nXMargin = 2;
    int nYMargin = 2;
    TEXTMETRIC tm;
    GetTextMetrics(pd.hDC, &tm);
    int nCharHeight = tm.tmHeight;
    int nCharWidth = tm.tmAveCharWidth;
    CHeaderCtrl* pHeader = list.GetHeaderCtrl();
    //获得行,列的个数
    int nColCount = pHeader->GetItemCount();
    int nLineCount = list.GetItemCount();

    int ColOrderArray[100];
    COLATT ca[100];
    list.GetColumnOrderArray(ColOrderArray, nColCount);
    int nColX =nXMargin*nCharWidth; //检索各列的信息,确定列标题的内容长度。
    for(int i =0 ; i< nColCount; i++)
    {
    ca[i].nColIndex = ColOrderArray[i];
    LVCOLUMN lvc;
    char text[100];
    lvc.mask = LVCF_TEXT|LVCF_SUBITEM;
    lvc.pszText = text;
    lvc.cchTextMax = 100;
    list.GetColumn(ca[i].nColIndex, &lvc);
    ca[i].strColText = lvc.pszText;
    ca[i].nSubItemIndex = lvc.iSubItem;
    ca[i].nPrintX = nColX;
    nColX += nCharWidth * strlen(ca[i].strColText); if(nColX > nHorRes) 
    {
    DeleteDC(pd.hDC);
    AfxMessageBox("字段太多,无法在一行内打印,请试用较大的纸,或横向打印。");
    return FALSE;
    }  
    } DOCINFO di;
    di.cbSize = sizeof(DOCINFO);
    di.lpszDocName = "ListCtrl Data Printing"; 
    di.lpszOutput = (LPTSTR) NULL; 
    di.lpszDatatype = (LPTSTR) NULL; 
    di.fwType = 0; 
    StartDoc(pd.hDC, &di);
    StartPage(pd.hDC); //调整各列的宽度,以使各列在后面的打印输出时更均匀的打印在纸上。
    int space = (nHorRes-nXMargin*nCharWidth-nColX) / (nColCount -1);
    for(i =1; i<nColCount; i++)
    {
    ca[i].nPrintX += i*space;
    }

    //输出列标题
    for(i =0; i<nColCount; i++)
    TextOut(pd.hDC, ca[i].nPrintX, nYMargin, 
    ca[i].strColText, strlen(ca[i].strColText));

    int nMaxLinePerPage = nVerRes/nCharHeight -3;
    int nCurPage =1;
    //输出各列的数据
    for(i =0; i<nLineCount; i++)
    {
    for(int j =0; j<nColCount; j++)
    {
    if(i+1-(nCurPage-1)*nMaxLinePerPage > nMaxLinePerPage)
    {
    //新的一页
    EndPage(pd.hDC);
    StartPage(pd.hDC);
    nCurPage ++;
    }
    CString subitem = list.GetItemText(i, ca[j].nSubItemIndex);
    TextOut(pd.hDC, ca[j].nPrintX, 
    nYMargin+(i+1-(nCurPage-1)*nMaxLinePerPage)*nCharHeight, 
    subitem, strlen(subitem));
    }
    }

    EndPage(pd.hDC);
    EndDoc(pd.hDC);
    //打印结束
    DeleteDC(pd.hDC);
    return TRUE;
    }