Windows 的頁式打印系統雖然擁有「所見即所得」與「設備無關」等優勢,但在實時性要求極高的工業控制場景中卻難以勝任。這類系統需要將隨機產生的信息即時逐行輸出,而非等待整頁緩衝。為了滿足這一剛性需求,本文詳細闡述如何在 Windows 2000/NT 平台上構建一套高性能的實時行式打印系統。
實時打印系統的核心指標是實時性與設備無關性。為此,採用共享內存為中轉的打印假脫機技術,所有打印操作在內存中完成提交,確保應用系統對打印請求的即時響應;同時通過統一驅動層抽象硬體差異,僅需加載對應驅動即可適配不同打印機,無需修改上層業務代碼。
系統劃分為兩大核心模組:
Windows 提供 CreateFileMapping 與 MapViewOfFile 兩大 API 支援跨進程共享內存。前者在系統中創建命名共享內存區並返回句柄,後者將其映射到調用進程地址空間。關鍵參數說明:
hFile = 0xffffffff 表示創建純內存映射dwPROTECT = PAGE_READWRITE 賦予讀寫權限lpszMapName 需全系統唯一,本系統定義為 g_szRealTimePrintSystemShareMemName共享內存核心結構 REALTIMEPRINT_DB 包含待打印數據、寫入/讀出指針等元信息。初始化示例代碼:
REALTIMEPRINT_DB *g_pRealTimePrintSystemDb;
HANDLE hShareMemHandle = NULL;
DWORD dwRTPSShmLen = sizeof(REALTIMEPRINT_DB);
hShareMemHandle = CreateFileMapping((HANDLE)0xffffffff, NULL, PAGE_READWRITE,
0, dwRTPSShmLen, "g_szRealTimePrintSystemShareMemName");
g_pRealTimePrintSystemDb = (REALTIMEPRINT_DB *)MapViewOfFile(
hShareMemHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
為追求極致效率,採用環形先入先出隊列(FIFO)管理打印請求,避免多次內存拷貝帶來的時空開銷。上層封裝為兩個 DLL 類:
RealTimePrintSystemClnt:供應用程序提交請求,提供 IsWorking()、IsFull()、Request() 等介面RealTimePrintSystemServ:供打印服務進程消費請求,提供 GetRequstNum()、GetRequest()、rtPrintThread() 等介面UnionPrintSystem 類封裝了驅動加載、打印機選擇、顏色控制、字符串輸出等統一操作。其核心成員包括:
GeneralPrinter *m_pPrinter:當前工作打印機指針HZDotArrayFont *m_pHzDAF:漢字點陣提取器,支援多種字體規格PrintString():統一列印入口,自動處理中英文混排為實現真正的設備無關性,設計了 GeneralPrinter 抽象基類,定義了初始化、換行模式、顏色設置、圖形模式、字符/圖形打印等虛函數。具體打印機驅動只需繼承該基類並實例化控制碼即可。以 Canon BJC5500 為例:
class Printer_BJC5500 : public GeneralPrinter {
public:
PRINTCOLOR m_AllColor[BJC5500_PRT_COLOR_NUM];
Printer_BJC5500(char *szPort);
virtual int PrintGraphDotArray(char *pData, int iDataLen); // 重載特殊圖形打印邏輯
};
Printer_BJC5500::Printer_BJC5500(char *szPort) {
strcpy(szPrinterName, "BJC5500");
m_iPrtColorNum = 7; // 支援 7 種顏色
m_bDirectPrintHz = FALSE; // 無內建漢字字庫,需軟點陣
m_AllColor[0].szColorName = "黑色";
m_AllColor[0].szControlStr = "\x1b\x5b\x4d\x01\x00\x30"; // ESC 序列
m_pResetPrintStream.cs = "\x1b\x43\x1\x1b\x41\x1"; // 初始化指令
// ... 其他控制碼初始化
}
系統通過 PrinterDrive.ini 配置文件管理已安裝驅動:
[SystemCfg]
DefalutPrinter=Canon_Bjc5500
[Printer1Cfg]
Name=Canon_Bjc5500
DriveFile=c:\RealPrt\Drive\Bjc5500.dll
統一驅動層啟動時讀取配置,利用 LoadLibrary/GetProcAddress 動態加載 DLL 導出的 GetGeneralPrinterEnginer 工廠函數,獲取 GeneralPrinter* 實例並註冊到系統中。新增打印機僅需提供符合規範的 DLL 與配置項,零代碼侵入。
本系統建立了六大核心類:
| 類名 | 職責 |
|---|---|
| RealTimePrintSystemClnt | 客戶端提交封裝 |
| RealTimePrintSystemServ | 服務端消費封裝 |
| UnionPrintSystem | 統一驅動層門面 |
| GeneralPrinter | 打印機抽象基類 |
| Printer_BJC5500 | 具體驅動範例 |
| HZDotArrayFont | 漢字點陣提取器 |
架構天然符合 Client/Server 模式,易於擴展為分布式實時打印系統;亦可引入優先級隊列、多打印機路由策略,甚至移植至 Unix/Linux 平台。完整工程代碼可在此框架基礎上逐模組落地,構建穩定高效的工業級實時行式打印解決方案。