使用双缓冲绘图文本(MFC,CDC类)

时间:2014-08-07 14:02:20

标签: c++ mfc

我需要用MFC绘制某种报告,我想使用双缓冲。我遇到问题之前就遇到了问题:当我尝试在像DoPDF(Foxit Reader等)这样的虚拟打印机的上下文中绘制时,用CDC :: TextOut或CDC :: DrawText编写的文本不会出现。当我在屏幕上下文(在对话框表面上)复制位图而不是在打印机的打印/预览(虚拟或真实)中复制位图时,我可以看到它。我在设备的上下文中做同样的事情时没有这样的问题(没有双缓冲)。我真的不知道这是我的问题的原因。我做了一些示例来展示我的代码/请?给我一个建议。提前谢谢。

画家班主任:

class CPainter  
{
public:    
    static void Paint(CDC * pDC);

private:
    static void PaintMemory(CDC * pDC);
    static void PaintDC(CDC * pDC);

public:
    CPainter();
    virtual ~CPainter();

};

画家类的来源:

CPainter::CPainter()
{

}

CPainter::~CPainter()
{

}

void CPainter::PaintMemory(CDC *pDC)
{
    CDC memDC;
    CBitmap memBmp, * pOldMemBmp;

    int cnxx = pDC->GetDeviceCaps(HORZRES);
    int cnxy = pDC->GetDeviceCaps(VERTRES);

    memDC.CreateCompatibleDC(pDC);
    memBmp.CreateCompatibleBitmap(pDC, cnxx, cnxy);
    pOldMemBmp = (CBitmap *)memDC.SelectObject(memBmp);

    ////////////////////////////////////////////////////////////////////////////////////
    memDC.BitBlt(0, 0, cnxx, cnxy, pDC, 0, 0, SRCCOPY);
    PaintDC(&memDC);
    pDC->BitBlt(0, 0, cnxx, cnxy, &memDC, 0, 0, SRCCOPY);
    ////////////////////////////////////////////////////////////////////////////////////

    memDC.SelectObject(pOldMemBmp);
    memDC.DeleteDC();
    memBmp.DeleteObject();
}

void CPainter::PaintDC(CDC *pDC)
{
    CRect rect;
    CString text = "123";
    CFont font, * pOldFont;
    CBrush brush(RGB(255, 0, 0)), * pOldBrush;
    CPen pen(PS_SOLID, 20, RGB(0, 0, 255)), * pOldPen;
    CSize s1, s2;
    int map, bkmode, textcolor;

    ////////////////////////////////////////////////////
    LOGFONT logFont;        
    memset(&logFont, 0, sizeof(logFont));
    logFont.lfHeight = 144;
    logFont.lfWidth = 0; 
    logFont.lfEscapement = 0;
    logFont.lfOrientation = 0;
    logFont.lfWeight = 300; 
    logFont.lfItalic = FALSE; 
    logFont.lfUnderline = FALSE; 
    logFont.lfStrikeOut = 0; 
    logFont.lfCharSet = RUSSIAN_CHARSET; 
    logFont.lfOutPrecision = OUT_DEFAULT_PRECIS; 
    logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; 
    logFont.lfQuality = DEFAULT_QUALITY; 
    logFont.lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS; 
    strcpy(logFont.lfFaceName, "Arial");
    font.CreateFontIndirect(&logFont);
    ////////////////////////////////////////////////////

    int cnxx = pDC->GetDeviceCaps(HORZRES);
    int cnxy = pDC->GetDeviceCaps(VERTRES);

    int x = 40;
    int y = 20;
    int width = 300;
    int height = 250;

    rect.left   = (x);
    rect.top    = (y) * -1;
    rect.right  = (rect.left + width);
    rect.bottom = (rect.top + height) * -1;

    ////////////////////////////////////////////////////
//    s1  = pDC->SetWindowExt(cnxx, cnxy);
//    s2  = pDC->SetViewportExt(cnxx, cnxy);
    map = pDC->SetMapMode(MM_LOMETRIC);
    pOldFont = pDC->SelectObject(&font);
    pOldBrush = pDC->SelectObject(&brush);
    pOldPen = pDC->SelectObject(&pen);
    bkmode = pDC->SetBkMode(TRANSPARENT);
    textcolor = pDC->SetTextColor(RGB(0, 255, 0));
    ////////////////////////////////////////////////////    

    pDC->Rectangle(&rect);
    pDC->DrawText(text, rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);

    //pDC->TextOut(rect.left + 10, rect.top - 20, text);

    ////////////////////////////////////////////////////
//    pDC->SetWindowExt(s1);
//    pDC->SetViewportExt(s2);
    pDC->SetMapMode(map);
    pDC->SelectObject(pOldFont);
    pDC->SetBkMode(bkmode);
    pDC->SetTextColor(textcolor);
    ////////////////////////////////////////////////////

    font.DeleteObject();
    brush.DeleteObject();
    pen.DeleteObject();
}

void CPainter::Paint(CDC *pDC)
{
    //PaintDC(pDC); 
    PaintMemory(pDC); 
}

主对话框中的Button处理程序:

void CTestDlg::OnButton1() 
{
    // TODO: Add your control notification handler code here

    CPrintDialog pd(true);    
    pd.m_pd.Flags |= PD_RETURNDC;


    if (pd.DoModal()==IDOK)    
    {
        CDC PrintDC;    
        HDC hdc = pd.GetPrinterDC();
        PrintDC.Attach(hdc);    
        DOCINFO infStru;                    
        ::ZeroMemory (&infStru, sizeof (DOCINFO));
        CString title="PC Passport";
        infStru.cbSize = sizeof (DOCINFO);        
        infStru.lpszDocName=title;
        infStru.lpszOutput=NULL;

        PrintDC.StartDoc(&infStru);        
        PrintDC.StartPage();        
        //CPainter::PaintMemory(&PrintDC);        
        CPainter::Paint(&PrintDC);        
        PrintDC.EndPage();        
        PrintDC.EndDoc();
        PrintDC.Detach();

        DeleteDC(hdc);
    }
}

0 个答案:

没有答案