如何用WinAPI C++打印完整文本文件?打印仅一行问题求助
问题分析与解决方案
你的代码只输出一行的核心原因有两个:
TextOutA不解析换行符:你给每行末尾加的\r\n不会触发换行,TextOut只会把它们当作普通不可打印字符处理,根本不会实现换行效果。- 行间距设置不合理:打印机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
相关产品推荐
相关产品推荐

