使用 MFC 打印文本和位图

Printing text and bitmap using MFC

我需要使用 MFC 打印一些文本(使用指定的字体),而不是打印位图。我可以在位图上绘制文本,而不是打印此位图,使用下面的代码 - 但我需要打印文本,而不是在底部打印位图。必须从文件加载位图。

CFont j1;
j1.CreateFont(
    120,                        // nHeight
    120,                         // nWidth
    0,                         // nEscapement
    0,                         // nOrientation
    FW_NORMAL,                 // nWeight
    FALSE,                     // bItalic
    FALSE,                     // bUnderline
    0,                         // cStrikeOut
    RUSSIAN_CHARSET,              // nCharSet
    OUT_DEFAULT_PRECIS,        // nOutPrecision
    CLIP_DEFAULT_PRECIS,       // nClipPrecision
    DEFAULT_QUALITY,           // nQuality
    DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
    "Arial");                 // lpszFacename               // lpszFacename


int w = 600, h = 400;
CClientDC dc(this);
CBitmap bmp;
CDC memdc;
memdc.CreateCompatibleDC(&dc);
bmp.CreateCompatibleBitmap(&dc, w, h);

if (!bmp.Attach(::LoadImage(
    ::GetModuleHandle(NULL), "D:\UPM\BMP\Login.bmp", IMAGE_BITMAP, 0, 0,
    LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE))) {
    AfxMessageBox(_T("Error loading bitmap!")); return;
}
BITMAP bm;
bmp.GetBitmap(&bm);

auto oldbmp = memdc.SelectObject(bmp);
CFont* pOldFont = memdc.SelectObject(&j1);



//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("qwerty\nrtrtrt\nttttt", &rc, DT_WORDBREAK | DT_EXPANDTABS | DT_CENTER);
    ///pDC->DrawText(dpu, strRect, DT_WORDBREAK | DT_EXPANDTABS | DT_CENTER);
//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 = "Print test";
    PrintDC.StartDoc(&docinfo);
    PrintDC.StartPage();
    PrintDC.BitBlt(0, 0, w, h, &memdc, 0, 0, SRCCOPY);
    PrintDC.EndPage();
    PrintDC.EndDoc();
}
dc.SelectObject(oldbmp);
CClientDC dc(this);
dc.DrawText(...);
...
PrintDC.BitBlt(0, 0, w, h, &memdc, 0, 0, SRCCOPY);

您正在显示器的“客户端 DC”上绘制文本,然后在“打印机 DC”上绘制位图。

改用 paint 函数处理一切,使用 paint_bitmap 函数使事情变得更简单。

void paint_bitmap(CDC& dc, CBitmap &bmp, CRect rc) 
{
    CDC memdc;
    memdc.CreateCompatibleDC(&dc);
    auto oldbmp = memdc.SelectObject(&bmp);
    dc.BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), &memdc, 0, 0, SRCCOPY);
    memdc.SelectObject(oldbmp);
}

void paint(CDC& dc) 
{
    CBitmap bmp;
    if (!bmp.Attach(...))...
    dc.DrawText(L"text", &rc, ...);
    rc.OffsetRect(0, 200);
    paint_bitmap(dc, bmp, rc);
}

...
CPrintDialog pd(false);
if (pd.DoModal() == IDOK) 
{
    HDC hdc = pd.GetPrinterDC();
    if (hdc) 
    {
        ...
        dc.StartPage();
        paint(dc); //<- use this for printer or display
        dc.EndPage();
    }

要直接打印到默认打印机:
CPrintDialog pd(false);
if (pd.GetDefaults() && pd.m_pd.hDC)
{
    CDC dc;
    dc.Attach(pd.m_pd.hDC);
    DOCINFO docinfo = { sizeof(docinfo) };
    docinfo.lpszDocName = L"Print test";
    dc.StartDoc(&docinfo);
    dc.StartPage();
    paint(dc);
    dc.EndPage();
    dc.EndDoc();
}
else
{
    MessageBox(L"no default printer...");
}

或者如果您想要一台您确定在那里的特定打印机,请使用

HDC hdc = CreateDC(L"WINSPOOL", L"Microsoft Print to PDF", NULL, NULL);
if (hdc)
{
    CDC dc;
    dc.Attach(hdc);
    ...
    //DeleteDC(hdc); CDC will take care of delete
}