MFC, Рисование текста в контексте памяти (печать) - PullRequest
0 голосов
/ 29 ноября 2018

Я застрял с проблемой - мне нужно создать растровое изображение в памяти, нарисовать некоторый текст в нем и сохранить его как файл BMP, а затем распечатать растровое изображение на физическом принтере.Я могу сделать этот рисунок в контексте диалогового окна - он отлично работает.Но когда я пытаюсь сделать тот же рисунок в контексте принтера, текст не появляется.Я действительно не могу понять, почему это так.Пожалуйста, помогите мне, ребята.Заранее спасибо.Вот код:

void CMy2Dlg::OnButton1() 
{
    // TODO: Add your control notification handler code here
    CPrintDialog pd(false); 

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


        PrintDC.StartDoc(&infStru);     

        PrintDC.StartPage();

        {           
            CRect r, r2;
            CBitmap memBMP, * pOldBitmap;
            CPaintDC dc(this); 
            CDC memDC, *pDC = &memDC;
            CFont font, * pOldFont;
            int width = 2000;
            int height = 1500;
            int textwidth = 300;
            int textheight = 150;
            int oldMapMode = 0;
            int oldbkmode = 0;
            int i, j;

            LOGFONT logFont, lf;
            COLORREF oldTextColor;

            memset(&logFont, 0, sizeof(logFont));
            logFont.lfHeight = 16;
            logFont.lfWidth = 0; 
            logFont.lfEscapement = 0;
            logFont.lfOrientation = 0;
            logFont.lfWeight = FW_NORMAL; 
            logFont.lfItalic = FALSE; 
            logFont.lfUnderline = FALSE; 
            logFont.lfStrikeOut = 0; 
            logFont.lfCharSet = ANSI_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");

            if(memDC.CreateCompatibleDC(&PrintDC)) {
                if (memBMP.CreateCompatibleBitmap(&PrintDC, width, height)) {

                    pOldBitmap = pDC->SelectObject(&memBMP);
                    pDC->FillSolidRect(0, 0, width, height, RGB(200, 200, 200));

                    oldTextColor = pDC->SetTextColor(RGB(255,0,0));
                    oldMapMode = pDC->SetMapMode(MM_LOMETRIC);
                    oldbkmode = pDC->SetBkMode(TRANSPARENT);


                    lf = logFont;
                    lf.lfHeight = -MulDiv(lf.lfHeight, GetDeviceCaps(pDC->GetSafeHdc(), LOGPIXELSY), 72);
                    //lf.lfHeight = 100;

                    font.CreateFontIndirect(&lf);
                    pOldFont = pDC->SelectObject(&font);


                    r.left = 10;
                    r.top = 10;
                    r.right = r.left + textwidth;
                    r.bottom = r.top + textheight;

                    r.top *= -1;
                    r.bottom *= -1;

                    pDC->MoveTo(r.left,  r.top);
                    pDC->LineTo(r.right, r.top);
                    pDC->LineTo(r.right, r.bottom);
                    pDC->LineTo(r.left,  r.bottom);
                    pDC->LineTo(r.left,  r.top);

                    pDC->DrawText("qwerty", &r, DT_CENTER | DT_SINGLELINE | DT_VCENTER);                    

                    pDC->SetMapMode(oldMapMode);
                    pDC->SetTextColor(oldTextColor);
                    pDC->SetBkMode(oldbkmode);

                    PrintDC.BitBlt(10, 10, width, height, pDC, 0, 0, SRCCOPY);                  

                    pDC->SelectObject(pOldBitmap);
                    pDC->SelectObject(pOldFont);                    

                    font.DeleteObject();
                    memBMP.DeleteObject();
                    pDC->DeleteDC();
                }
            }
        }

        PrintDC.EndPage();

        PrintDC.EndDoc();

        PrintDC.Detach();       
        DeleteDC(hdc);
    }
}

1 Ответ

0 голосов
/ 30 ноября 2018

Если SetMapMode(MM_LOMETRIC) используется для памяти DC, то память DC должна быть нарисована вверх ногами при использовании BitBlt для копирования на принтер / дисплей DC.Ширина / высота также должны быть отрегулированы.Просто используйте режим карты по умолчанию (MM_TEXT).Используйте SetMapMode(MM_LOMETRIC), когда вы рисуете на принтере DC, и вам нужны эти конкретные единицы измерения.

void CMy2Dlg::OnButton1() 
{
    //create the bitmap
    int w = 600, h = 400;
    CClientDC dc(this);
    CBitmap bmp;
    CDC memdc;
    memdc.CreateCompatibleDC(&dc);
    bmp.CreateCompatibleBitmap(&dc, w, h);
    auto oldbmp = memdc.SelectObject(bmp);

    //draw on bitmap
    memdc.FillSolidRect(0, 0, w, h, RGB(200, 200, 200));
    memdc.SetTextColor(RGB(255, 0, 0));
    CRect rc(0, 0, w, h);
    memdc.DrawText(L"qwerty", &rc, 0);

    dc.BitBlt(0, 0, w, h, &memdc, 0, 0, SRCCOPY);//optional: draw the bitmap on dialog

    CPrintDialog pd(false);
    if(pd.DoModal() == IDOK)
    {
        CDC PrintDC;
        HDC hdc = pd.GetPrinterDC();
        PrintDC.Attach(hdc);
        DOCINFO docinfo = { sizeof(docinfo) };
        docinfo.lpszDocName = L"Print test";
        PrintDC.StartDoc(&docinfo);
        PrintDC.StartPage();
        PrintDC.BitBlt(0, 0, w, h, &memdc, 0, 0, SRCCOPY);
        PrintDC.EndPage();
        PrintDC.EndDoc();
    }
    dc.SelectObject(oldbmp);
}
...