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

如何用WinAPI C++打印完整文本文件?打印仅一行问题求助

问题分析与解决方案

你的代码只输出一行的核心原因有两个:

  1. TextOutA不解析换行符:你给每行末尾加的\r\n不会触发换行,TextOut只会把它们当作普通不可打印字符处理,根本不会实现换行效果。
  2. 行间距设置不合理:打印机DC的默认单位是千分之一英寸,你每次把y加50,相当于只往下移动了0.05英寸(约1.27毫米),所有行几乎重叠在一起,视觉上就像只有一行。

另外,代码未检查StartDoc、StartPage等API的返回值,万一这些调用失败,后续打印操作也会无效,这也是需要补上的细节。

修复后的代码

#include <windows.h>
#include <fstream>
#include <string>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow)
{
    PRINTDLG prDlg;
    memset(&prDlg, 0, sizeof(prDlg));
    prDlg.lStructSize = sizeof(prDlg);
    prDlg.Flags = PD_RETURNDC;

    if (!PrintDlg(&prDlg))
    {
        MessageBox(NULL, "PrintDlg(&pd) failed!", "Fatal Error", MB_OK | MB_ICONERROR);
        return -1;
    }

    HDC hPrinter = prDlg.hDC;

    DOCINFO document_Information;
    memset(&document_Information, 0, sizeof(document_Information));
    document_Information.cbSize = sizeof(document_Information);
    document_Information.lpszDocName = L"Text File Print Job"; // 给打印任务命名,方便识别

    // 检查StartDoc调用是否成功
    if (StartDoc(hPrinter, &document_Information) <= 0)
    {
        MessageBox(NULL, "StartDoc failed!", "Error", MB_OK | MB_ICONERROR);
        DeleteDC(hPrinter);
        return -1;
    }

    // 检查StartPage调用是否成功
    if (StartPage(hPrinter) <= 0)
    {
        MessageBox(NULL, "StartPage failed!", "Error", MB_OK | MB_ICONERROR);
        EndDoc(hPrinter);
        DeleteDC(hPrinter);
        return -1;
    }

    // 获取当前字体的高度,计算合理行间距
    TEXTMETRIC tm;
    GetTextMetrics(hPrinter, &tm);
    int lineHeight = tm.tmHeight + tm.tmExternalLeading; // 字体高度+额外行间距

    std::string filePath = "D:/documents/text.txt"; 

    std::ifstream file(filePath);
    if (file.is_open())
    {
        std::string line;
        int y = 100; // 初始y坐标,100=0.1英寸,距离顶部留足空间
        while (std::getline(file, line))
        {
            // 直接输出行内容,无需添加换行符
            if (!TextOutA(hPrinter, 100, y, line.c_str(), line.length()))
            {
                MessageBox(NULL, "TextOut failed!", "Error", MB_OK | MB_ICONERROR);
                break;
            }
            y += lineHeight; // 用字体高度设置下一行的y坐标

            // 检查是否超出页面高度,自动换页
            int pageHeight = GetDeviceCaps(hPrinter, VERTRES);
            if (y + lineHeight > pageHeight)
            {
                EndPage(hPrinter);
                StartPage(hPrinter);
                y = 100; // 重置y坐标到新页顶部
            }
        }
        file.close();
    }
    else
    {
        MessageBox(NULL, "Failed to open the file!", "Error", MB_OK | MB_ICONERROR);
    }

    EndPage(hPrinter);
    EndDoc(hPrinter);
    DeleteDC(hPrinter);

    return 0;
}

关键修改点说明

  • 移除line += "\r\n":TextOut不处理换行符,添加后无意义,直接输出读取到的行内容即可。
  • 用GetTextMetrics计算行高:通过获取当前字体的实际高度,确保每行之间有合理间距,避免重叠。
  • 添加API错误检查:对StartDoc、StartPage、TextOut的调用结果进行校验,及时发现并处理错误。
  • 新增分页逻辑:当内容超出页面高度时自动换页,避免内容被截断。
  • 设置打印任务名称:在打印机队列中能直观看到任务名称,方便排查问题。

内容的提问来源于stack exchange,提问作者yulia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 03:25:03