//printer 打印机 namespace sys; class printer{ ctor( printerName,printerDefaults ){ if(!printerName) printerName = default(); if(!printerName) return; this.hPrinter = {ptr value}; if(!api.OpenPrinter(printerName,this.hPrinter,printerDefaults) ) return; this.hPrinter = this.hPrinter.value; if(!this.hPrinter) return; this.deviceName = printerName; ..table.gc(this,"close"); }; documentProperties = function(param){ var needed = api.DocumentProperties(param[["hwnd"]],this.hPrinter,this.deviceName,,,0); var pDevMode = ..raw.buffer(needed); if( 1 != api.DocumentProperties(param[["hwnd"]],this.hPrinter,this.deviceName,pDevMode,null,2/*_DM_OUT_BUFFER*/) ){ return; } if(param){ var devMode = ..raw.convert(pDevMode,DEVMODE()); ..table.assign(devMode,param); if( 1 != api.DocumentProperties(param[["hwnd"]],this.hPrinter,this.deviceName,pDevMode,devMode,8 | 2/*_DM_IN_BUFFER | _DM_OUT_BUFFER*/) ){ return; } } return pDevMode; }; createDevice = function(param){ var pDevMode; if(param) pDevMode = this.documentProperties(param); var hdc = topointer( ::Gdi32.CreateDC(null, this.deviceName, null, pDevMode) ); var pdc = device(hdc,true); pdc.deviceName = this.deviceName; return pdc; }; startDoc = function(docName,dataType,outputFile){ return !!api.StartDocPrinter(this.hPrinter,1,{ ustring docName = docName : "My Document"; ustring outputFile = outputFile; ustring dataType = dataType : "RAW"; }); }; startPage = function(){ return !!api.StartPagePrinter(this.hPrinter); }; endPage = function(){ return !!api.EndPagePrinter(this.hPrinter); }; endDoc = function(){ return !!api.EndDocPrinter(this.hPrinter); }; start = function(printProc,docName,dataType,outputFile){ if( this.startDoc(docName,dataType,outputFile) ){ if( this.startPage() ){ printProc(); this.endPage(); } this.endDoc(); } }; write = function(data){ var written = {INT len}; if( api.WritePrinter(this.hPrinter,data, #data,written) ){ return written.len; } }; writePack = function(...){ var data = ..string.pack(...); var written = {INT len}; if( api.WritePrinter(this.hPrinter,data, #data,written) ){ return written.len; } }; read = function(len=255){ var buf = ..raw.buffer(len); var noBytesRead = {INT value}; if( api.ReadPrinter(this.hPrinter,buf,len,noBytesRead) ) return ..string.left(buf,noBytesRead.value); }; close = function(){ if(this.hPrinter) { api.ClosePrinter(this.hPrinter); this.hPrinter = null; }; } } namespace printer{ api = ..raw.loadDll("Winspool.drv"); each = function(flags){ var needed = {INT value} var returned = {INT value}; if(flags===null) flags = 2/*_PRINTER_ENUM_LOCAL*/; api.EnumPrinters(flags, null, 4, null, 0, needed, returned) ; if(!needed.value) return function(){}; var buffer = ..raw.buffer(needed.value) api.EnumPrinters(flags, null, 4, buffer, #buffer, needed, returned) ; var info4 = ..raw.convert(buffer,{ struct printers[] = { { ustring printerName; ustring serverName; INT attributes; }; length = returned.value; } }) var index = 0; return function(){ index = index + 1; var printer = info4.printers[index]; if(printer) return printer.printerName,printer.serverName,printer.attributes; } } default = function(){ var buffer = ..raw.buffer(1024) var length = { INT value = 1024}; if(api.GetDefaultPrinter(buffer,length) ) return ..string.fromUtf16(buffer); } setDefault = function(printerName){ return !!api.SetDefaultPrinter(printerName); } ::Gdi32 := ..raw.loadDll("Gdi32.dll"); class device{ ctor(hdc,gc){ this.hdc = hdc; if(!this.hdc){ var printerName = ..sys.printer.default(); if(printerName) { return ..sys.printer(printerName).createDevice(); } } if(gc)this.gchdc = this.hdc; if(!this.hdc) return; }; size = function(){ return ::Gdi32.GetDeviceCaps(this.hdc,0x8/*_HORZRES*/),::Gdi32.GetDeviceCaps(this.hdc,0xA/*_VERTRES*/); }; rect = function(){ return ::RECT(0,0,this.size()); } dpi = function(){ return ::Gdi32.GetDeviceCaps(this.hdc,0x58/*_LOGPIXELSX*/),::Gdi32.GetDeviceCaps(this.hdc,0x5A/*_LOGPIXELSY*/); }; reset = function(devMode){ ::Gdi32.ResetDC(this.hdc,devMode); }; startDoc = function(docName,dataType,output,fwType){ return 0 < ::Gdi32.StartDoc(this.hdc,{ int cbSize = 20; ustring docName = docName : "My Document"; ustring output = output; ustring dataType = dataType; INT fwType = fwType; }); }; startPage = function(){ return 0 < ::Gdi32.StartPage(this.hdc); }; endPage = function(){ return 0 < ::Gdi32.EndPage(this.hdc); }; endDoc = function(){ return 0 < ::Gdi32.EndDoc(this.hdc); }; start = function(printProc,docName,dataType,output,fwType){ if( this.startDoc(docName,dataType,output,fwType) ){ if( this.startPage() ){ printProc(this.hdc,this.rect()); this.endPage(); } this.endDoc(); } }; close = function(){ if(this.gchdc){ ::Gdi32.DeleteDC(this.gchdc); this.gchdc = null; this.hdc = null; } } @{ _topointer = function(){return this.hdc}} } class DEVMODE{ WORD dmDeviceName[32]; WORD dmSpecVersion; WORD dmDriverVersion; WORD dmSize; WORD dmDriverExtra; INT dmFields; word dmOrientation; word dmPaperSize; word dmPaperLength; word dmPaperWidth; word dmScale; word dmCopies; word dmDefaultSource; word dmPrintQuality; word dmColor; word dmDuplex; word dmYResolution; word dmTTOption; word dmCollate; WORD dmFormName[32]; WORD dmLogPixels; INT dmBitsPerPel; INT dmPelsWidth; INT dmPelsHeight; INT dmDisplayFlags; INT dmDisplayFrequency; INT dmICMMethod; INT dmICMIntent; INT dmMediaType; INT dmDitherType; INT dmReserved1; INT dmReserved2; INT dmPanningWidth; INT dmPanningHeight; } } /**intellisense() sys.printer(.(printerName,printerDefaults) = 打开打印机设备\nprinterName指定打印机名称,省略打开默认打印机\nprinterDefaults可省略 sys.printer.device(.(hdc) = 创建绘图设备对象\n如果不指定hdc,则自动获取默认打印机绘图设备句柄\n如果参数@2为true,则负责释放参数@1指定的hdc sys.printer() = !stdsysprinter. sys.printer.device() = !stdsysprinterdc. sys.printer.each(flags) = @for printerName,serverName,attributes in sys.printer.each(){ __/*遍历系统打印机:\nprinterName为打机机名称,\nserverName为服务名,\nattributes为_PRINTER_ATTRIBUTE_前缀常量*/ } sys.printer.setDefault(__/*名称*/) = 设置默认打印机 sys.printer.default() = 返回默认打印机名称 end intellisense**/ /**intellisense(!stdsysprinter) documentProperties() = 获取或修改DEVMODE缓冲区指针\n可选在参数中使用任意个键值对重新指定DEVMODE部分字段的值 createDevice() = 创建绘图设备对象,\n可选在参数中使用任意个键值对重新指定DEVMODE部分字段的值\n!stdsysprinterdc. startDoc(docName,dataType,outputFile) = 开始打印文档,所有参数可选\n参数参考API函数StartPagePrinter的说明 startPage() = 开始打印一个页面 endPage() = 结束打印一个页面 endDoc() = 结束打印一个文档 writePack(__) = 写入一个或多个字节码 write(__) = 写入字符串 start(回调函数,文档名,文档类型,输出文件) = @.start(\n function(){\n __ \n }\n); end intellisense**/ /**intellisense(!stdsysprinterdc) reset(__) = 修改打印机设置\n参数应为 sys.printer.documentProperties 函数返回的 DEVMODE 指针 size() = 返回 2 个返回值,分别为绘图区块的宽,高。 rect() = 返回一个表示绘图区块的 RECT 结构体\n!rect. dpi() = 返回DPI startDoc(docName,dataType,output,fwType) = 开始打印文档,所有参数可选\n参数参考 API 函数 StartPage 的说明 startPage() = 开始打印一个页面 endPage() = 结束打印一个页面 endDoc() = 结束打印一个文档 start(回调函数,文档名,文档类型,输出文件,类型) = @.start(\n function(hdcPrinter,rc){\n ::Gdi32.TextOut(hdcPrinter,20,20,"测试打印",4); __/*回调参数 hdcPrinter 为绘图设备上下文句柄(hdc),\nrc 为绘图区块( ::RECT 结构体)。*/\n }\n); end intellisense**/