各位朋友,有谁知道在VC++里实现打印(预览)功能的方法?(用按扭来控制)我试了好多种,都不行,所以想请各位帮忙,在此非常感谢!(有实例最好)

解决方案 »

  1.   

    派生一个自己的打印预览类:
    // MyPreviewView.h : header file
    //#include "afxpriv.h"
    #include "mappedbitmapbutton.h"/////////////////////////////////////////////////////////////////////////////
    // CMyPreviewView viewclass CMyPreviewView : public CPreviewView
    {
    protected:
    CMyPreviewView();           // protected constructor used by dynamic creation
    DECLARE_DYNCREATE(CMyPreviewView)// Attributes
    public:protected:         //各个按钮
    CMappedBitmapButton m_print;
    CMappedBitmapButton m_next;
    CMappedBitmapButton m_previous;
    CMappedBitmapButton m_onetwo;
    CMappedBitmapButton m_zoomIn;
    CMappedBitmapButton m_zoomOut; BOOL m_bOne;// Operations
    public:// Overrides
    virtual void OnDisplayPageNumber(UINT nPage, UINT nPagesDisplayed); // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CMyPreviewView)
    //}}AFX_VIRTUAL// Implementation
    protected:
    virtual ~CMyPreviewView();
    #ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
    #endif // Generated message map functions
    protected:
    //{{AFX_MSG(CMyPreviewView)
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    //}}AFX_MSG
    afx_msg void OnPreviewPrint();
    afx_msg void OnUpdateNumPageChange(CCmdUI* pCmdUI);
    afx_msg void OnUpdateZoomIn(CCmdUI* pCmdUI);
    afx_msg void OnUpdateZoomOut(CCmdUI* pCmdUI);
    DECLARE_MESSAGE_MAP()
    };
      

  2.   

    cpp文件:
    #include "stdafx.h"
    #include "afxpriv.h"
    #include "afxres.h"
    #include "MyPreviewView.h"
    #include "resource.h"IMPLEMENT_DYNCREATE(CMyPreviewView, CPreviewView)#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif/////////////////////////////////////////////////////////////////////////////
    // CMyPreviewView
    CMyPreviewView::CMyPreviewView()
    {
    }CMyPreviewView::~CMyPreviewView()
    {
    }void CMyPreviewView::OnDisplayPageNumber(UINT nPage, UINT nPagesDisplayed)
    {
    CPreviewView::OnDisplayPageNumber( nPage, nPagesDisplayed );
    }void CMyPreviewView::OnPreviewPrint()
    {
    CPreviewView::OnPreviewPrint();
    }BEGIN_MESSAGE_MAP(CMyPreviewView, CPreviewView)
    //{{AFX_MSG_MAP(CMyPreviewView)
    ON_WM_CREATE()
    //}}AFX_MSG_MAP
    ON_COMMAND(AFX_ID_PREVIEW_PRINT, OnPreviewPrint)
    ON_UPDATE_COMMAND_UI(AFX_ID_PREVIEW_NUMPAGE, OnUpdateNumPageChange)
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CMyPreviewView drawing/////////////////////////////////////////////////////////////////////////////
    // CMyPreviewView diagnostics#ifdef _DEBUG
    void CMyPreviewView::AssertValid() const
    {
    CPreviewView::AssertValid();
    }void CMyPreviewView::Dump(CDumpContext& dc) const
    {
    CPreviewView::Dump(dc);
    }
    #endif //_DEBUG/////////////////////////////////////////////////////////////////////////////
    // CMyPreviewView message handlersvoid CMyPreviewView::OnUpdateNumPageChange(CCmdUI* pCmdUI)
    {
    UINT nPages = m_nZoomState == ZOOM_OUT ? m_nPages : m_nZoomOutPages; if (m_bOne) {
    if (nPages == 1) {
    // need to swap to show 2 pages
    m_onetwo.LoadBitmap( IDB_PREV_TWO );
    m_bOne = FALSE;
    m_onetwo.Invalidate();
    }
    }
    else {
    if (nPages != 1) {
    // need to swap to show 1 page
    m_onetwo.LoadBitmap( IDB_PREV_ONE );
    m_bOne = TRUE;
    m_onetwo.Invalidate();
    }
    } // enable it only if valid to display another page and not zoomed
    pCmdUI->Enable(m_nZoomState == ZOOM_OUT && m_nMaxPages != 1 &&
    (m_pPreviewInfo->GetMaxPage() > 1 || m_nPages > 1));
    }int CMyPreviewView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    {
    if (CPreviewView::OnCreate(lpCreateStruct) == -1)
    return -1; m_pToolBar->EnableToolTips( TRUE ); m_bOne = FALSE;  // the default is to show 2 pages, set in the dialog text m_print.AutoLoad( AFX_ID_PREVIEW_PRINT, m_pToolBar, IDB_PREV_PRINT );
    m_next.AutoLoad( AFX_ID_PREVIEW_NEXT, m_pToolBar, IDB_PREV_NEXT );
    m_previous.AutoLoad( AFX_ID_PREVIEW_PREV, m_pToolBar, IDB_PREV_PREVIOUS );
    m_onetwo.AutoLoad( AFX_ID_PREVIEW_NUMPAGE, m_pToolBar, IDB_PREV_TWO );
    m_zoomIn.AutoLoad( AFX_ID_PREVIEW_ZOOMIN, m_pToolBar, IDB_PREV_ZOOMIN );
    m_zoomOut.AutoLoad( AFX_ID_PREVIEW_ZOOMOUT, m_pToolBar, IDB_PREV_ZOOMOUT );

    return 0;
    }
      

  3.   

    上面的代码中的IDB_PREV_PRINT 、IDB_PREV_NEXT等等都是自己导入工程的位图,也就是那些按钮,你可以用你喜欢的样式的,^_^
    在自己的视图中加入两个函数:
    void CMyView::MyPrintPreview()
    {
    CPrintPreviewState* pState = new CPrintPreviewState;
    if (!DoPrintPreview(IDD_PREVIEW, this,
    RUNTIME_CLASS(CMyPreviewView), pState))
    {
    // In derived classes, reverse special window handling here for
    // Preview failure case
    TRACE0("Error: DoPrintPreview failed.\n");
    AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
    delete pState;      // preview failed to initialize, delete State now
    }
    }
    void CMyView::MyPrint()
    {  
    CDC dc;
        CPrintDialog printDlg(FALSE,PD_ALLPAGES | PD_COLLATE | PD_NOPAGENUMS | PD_HIDEPRINTTOFILE);    if (printDlg.DoModal() == IDCANCEL)         // Get printer settings from user
            return;    dc.Attach(printDlg.GetPrinterDC());         // Attach a printer DC
        dc.m_bPrinting = TRUE;    CString strTitle;                           // Get the application title
        strTitle.LoadString(AFX_IDS_APP_TITLE);    DOCINFO di;                                 // Initialise print document details
        ::ZeroMemory (&di, sizeof (DOCINFO));
        di.cbSize = sizeof (DOCINFO);
        di.lpszDocName = strTitle;    BOOL bPrintingOK = dc.StartDoc(&di);        // Begin a new print job    // Get the printing extents and store in the m_rectDraw field of a 
        // CPrintInfo object
        CPrintInfo Info;
        Info.m_rectDraw.SetRect(0,0, 
                                dc.GetDeviceCaps(HORZRES), 
                                dc.GetDeviceCaps(VERTRES));    OnBeginPrinting(&dc, &Info);                // Call your "Init printing" funtion
        for (UINT page = Info.GetMinPage(); 
             page <= Info.GetMaxPage() && bPrintingOK; 
             page++)
        {
            dc.StartPage();                         // begin new page
            Info.m_nCurPage = page;
            OnPrint(&dc, &Info);                    // Call your "Print page" function
            bPrintingOK = (dc.EndPage() > 0);       // end page
        }
        OnEndPrinting(&dc, &Info);                  // Call your "Clean up" funtion    if (bPrintingOK)
            dc.EndDoc();                            // end a print job
        else
            dc.AbortDoc();                          // abort job.    dc.Detach();}在需要的地方调用MyPrint()或MyPrintPreview()函数,就可以打印或预览了
      

  4.   

    回复common_man(谢安王导):
    你好,感谢你的回复。你的"IDD_PREVIEW"是定义的什么的ID号?
    能不能把你的实例发给我一个,我的邮箱上面有。我将非常感谢!
      

  5.   

    IDD_PREVIEW是一个对话框,是用来模拟打印预览工具条的
    你在工程中加入一个对话框资源,把ID号设为IDD_PREVIEW,做的细长一些,加入七个按钮:---------------------------------------------------------------------------------
     |  1  |  |  2  |  |  3  |  |  4  |  |  5  |  |  6  |  |  close  |  
    ---------------------------------------------------------------------------------他们的ID号依次为:
    AFX_ID_PREVIEW_PRINT
    AFX_ID_PREVIEW_NEXT
    AFX_ID_PREVIEW_PREV
    AFX_ID_PREVIEW_NUMPAGE
    AFX_ID_PREVIEW_ZOOMIN
    AFX_ID_PREVIEW_ZOOMOUT
    AFX_ID_PREVIEW_CLOSE
    就行了,(不要给给这个对话框生成一个新类)