You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MFC打印指定字体文本并在下方打印从文件加载的位图

MFC打印需求调整方案

核心调整逻辑

  • 拆分文本绘制与位图加载逻辑,不再将文本绘制到位图素材上
  • 打印时先向打印DC输出指定字体的文本,提前计算文本占据的高度,再在文本底部位置绘制加载的位图
  • 修复原有代码的GDI资源泄漏问题

修改后完整可运行代码

// 创建指定字体
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
    _T("Arial"));                 // lpszFacename

// 加载本地位图,不要和文本绘制混用位图对象
CBitmap bmp;
if (!bmp.Attach(::LoadImage(
    ::GetModuleHandle(NULL), _T("D:\\UPM\\BMP\\Login.bmp"), IMAGE_BITMAP, 0, 0,
    LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE))) {
    AfxMessageBox(_T("Error loading bitmap!")); 
    j1.DeleteObject(); // 异常退出前释放字体资源
    return;
}
BITMAP bm;
bmp.GetBitmap(&bm);

// 弹出打印对话框
CPrintDialog pd(false);
if (pd.DoModal() == IDOK)
{
    CDC PrintDC;
    HDC hdc = pd.GetPrinterDC();
    PrintDC.Attach(hdc);
    DOCINFO docinfo = { sizeof(docinfo) };
    docinfo.lpszDocName = _T("Print test");
    
    PrintDC.StartDoc(&docinfo);
    PrintDC.StartPage();

    // 第一步:绘制文本,先计算文本所需的矩形高度
    CFont* pOldFont = PrintDC.SelectObject(&j1);
    PrintDC.SetTextColor(RGB(255, 0, 0));
    CRect textRect(0, 0, GetDeviceCaps(hdc, PHYSICALWIDTH), 0); // 宽度取打印纸可打印宽度
    // 先计算文本所需高度,不实际绘制
    PrintDC.DrawText(_T("qwerty\nrtrtrt\nttttt"), &textRect, DT_WORDBREAK | DT_EXPANDTABS | DT_CENTER | DT_CALCRECT);
    // 调整文本矩形到合适的左上边距,这里默认留20像素边距,可自行调整
    textRect.OffsetRect(20, 20);
    // 实际绘制文本
    PrintDC.DrawText(_T("qwerty\nrtrtrt\nttttt"), &textRect, DT_WORDBREAK | DT_EXPANDTABS | DT_CENTER);

    // 第二步:在文本底部绘制位图,位图左上角Y坐标为文本矩形的底部+10像素间距,可自行调整
    int bmpX = 20; // 位图左边距和文本对齐
    int bmpY = textRect.bottom + 10;
    // 创建兼容内存DC绘制位图
    CDC memdc;
    memdc.CreateCompatibleDC(&PrintDC);
    CBitmap* pOldBmp = memdc.SelectObject(&bmp);
    PrintDC.BitBlt(bmpX, bmpY, bm.bmWidth, bm.bmHeight, &memdc, 0, 0, SRCCOPY);
    
    // 资源回收
    memdc.SelectObject(pOldBmp);
    memdc.DeleteDC();
    PrintDC.SelectObject(pOldFont);

    PrintDC.EndPage();
    PrintDC.EndDoc();
    PrintDC.DeleteDC();
}

// 全局资源回收
bmp.DeleteObject();
j1.DeleteObject();

可选优化点

  • 打印机DPI远高于屏幕DPI,直接使用像素值绘制的内容会很小,可以通过GetDeviceCaps获取打印机DPI,按屏幕DPI比例缩放字体大小、坐标值,匹配预期打印尺寸
  • 可自行调整文本边距、文本和位图的间距,适配不同打印纸尺寸

内容的提问来源于stack exchange,提问作者Сергей Соколов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 20:06:03