首页
> 计算机技术
> 后端开发
> Nim
B/S架构POS客户端开发之三-本地打印程序的实现
原创 lihf8515于2025年02月15日 18:11发表
来源:本站 阅读:110
本篇是 B/S架构POS客户端开发之三-本地打印程序的实现 篇
接上篇,B/S架构POS客户端开发之二-本地Web打印代理服务的实现
这里,我们仍然使用Nim语言实现,之所以选择用Nim开发,上篇文章中已经讲明白了。
其中,wNim是一个Nim语言实现的Windows界面GUI开发库,用它开发Windows界面的程序非常方便,这里仅使用了它的 MessageBox 函数用以向用户显示提示信息。
完整代码如下:
import std/[os, strutils]
import wNim/[wApp]
import wNim/private/winimx
{.link:"res/app.res".}
# 导入有驱动程序的打印动态库
proc winPrint*(printString: cstring): cint {.dynlib: "winprint.dll" importc: "winPrint".}
# 导入winapi的写文件,支持写lpt端口
proc winWriteFile*(filename, printString: cstring, len: cint): cint {.dynlib: "winprint.dll" importc: "winWriteFile".}
# 导入客显动态库
proc com_init*(com, baud: cint): bool {.stdcall dynlib: "api_com.dll" importc: "com_init".}
proc com_rest*(): bool {.stdcall dynlib: "api_com.dll" importc: "com_rest".}
proc com_send*(buf: cstring, len: cint): bool {.stdcall dynlib: "api_com.dll" importc: "com_send".}
proc update*() =
## 更新主程序
let desktopHwnd = GetDesktopWindow()
try:
sleep(1000)
let sfile = getAppDir() / "hfpos.exe.txt"
let dfile = getAppDir() / "hfpos.exe"
moveFile(sfile, dfile)
sleep(500)
discard ShellExecute(desktopHwnd, "open", "hfpos.exe", "", "", SW_HIDE)
except Exception as e:
MessageBox(desktopHwnd, e.msg, "系统提示", MB_OK or MB_ICONSTOP)
proc monitor*(commandType, ysje: string): bool =
## 客显显示
var command: string
if commandType == "5": # 清屏
command = chr(12) & ""
else:
# 点亮显示类型灯
command = chr(27) & chr(115) & commandType & "" # ls_type值:1、单价;2、总计;3、收款;4、找零;0、灯全灭
# 显示应收金额
command = command & chr(27) & chr(81) & chr(65) & ysje & chr(13)
if com_send(command.cstring, command.len.cint):
result = true
else:
result = false
proc opencash*(printerPort: string): bool =
## 开钱箱
let port = toUpperAscii(printerPort)
var command: string
command = chr(27) & chr(64) & "" # 初始化打印机
command = command & chr(27) & chr(112) & chr(48) & chr(60) & chr(120) # 开钱箱
if port == "USB":
if winPrint(command.cstring) == 0: # 开钱箱
result = true
else:
result = false
else:
if winWriteFile(port.cstring, command.cstring, command.len.cint) == 0:
result = true
else:
result = false
proc print*(fileName, printerPort, opencashEnabled, cutEnabled, blankrowNum: string): bool =
## 打印小票
let port = toUpperAscii(printerPort)
let opencash = toUpperAscii(opencashEnabled)
let cut = toUpperAscii(cutEnabled)
let blankrow = blankrowNum.parseInt
var command: string
command = chr(27) & chr(64) & "" # 初始化打印机
if port == "USB":
if opencash == "TRUE":
command = command & chr(27) & chr(112) & chr(48) & chr(60) & chr(120) # 开钱箱
var lines: seq[string]
if fileExists(fileName):
let content = readFile(fileName)
lines = splitLines(content)
else:
return false
for line in lines:
command = command & line & chr(10) # 打印数据行
for i in 1..blankrow:
command = command & "\n" # 打印空行
if cut == "TRUE":
command = command & chr(29) & chr(86) & chr(66) & chr(0) # 切纸
if winPrint(command.cstring) == 0:
result = true
else:
result = false
else:
if opencash == "TRUE":
command = command & chr(27) & chr(112) & chr(48) & chr(60) & chr(120) # 开钱箱
var lines: seq[string]
if fileExists(fileName):
let content = readFile(fileName)
lines = splitLines(content)
else:
return false
for line in lines:
command = command & line & chr(10) # 打印数据行
for i in 1..blankrow:
command = command & "\n"
if cut == "TRUE":
command = command & chr(29) & chr(86) & chr(66) & chr(0) # 切纸
if winWriteFile(port.cstring, command.cstring, command.len.cint) == 0:
result = true
else:
result = false
when declared(commandLineParams):
# 打开钱箱命令为:hfpos_print opencash lpt1
# 打印小票命令为:hfpos_print print PrintOut1.txt lpt1 true true 2
# 显示客显命令为:hfpos_print display 1 888888.88 com2 2400
# 显示主程序命令:hfpos_print update
let errMsg = "调用参数不正确"
var args = commandLineParams()
var argsCount = paramCount()
let desktopHwnd = GetDesktopWindow()
if argsCount > 0:
var command = toUpperAscii(args[0])
if argsCount == 6 and command == "PRINT": # 参数6个,0、PRINT; 1:打印的文件;2:接口,如lpt1;3:是否开钱箱;4:是否切纸;5:打印后走几个空行
if not print(args[1], args[2], args[3], args[4], args[5]):
MessageBox(desktopHwnd, "打印小票出错", "系统提示", MB_OK or MB_ICONSTOP)
elif argsCount == 2 and command == "OPENCASH": # 参数2个,0:OPENCASH;1:接口,如lpt1
if not opencash(args[1]):
MessageBox(desktopHwnd, "打开钱箱出错", "系统提示", MB_OK or MB_ICONSTOP)
elif argsCount == 5 and command == "DISPLAY": # 参数5个,0:DISPLAY;1:显示类型;2:应收金额;3:接口,如com2;4:波特率,如2400
if args[3].len > 3:
var com: int = args[3][3..3].parseInt
if not com_init(com.cint, args[4].parseInt.cint):
MessageBox(desktopHwnd, "顾客显示屏" & args[3] & "打开出错\n请检查顾客显示屏接口设置是否正确", "系统提示", MB_OK or MB_ICONSTOP)
else:
if monitor(args[1], args[2]): # args[2]值:1、单价;2、总计;3、收款;4、找零;0、灯全灭;5、清屏
discard com_rest()
else:
MessageBox(desktopHwnd, "顾客显示屏发送失败", "系统提示", MB_OK or MB_ICONSTOP)
else:
MessageBox(desktopHwnd, "COM端口写法不对", "系统提示", MB_OK or MB_ICONSTOP)
elif argsCount == 1 and command == "UPDATE": # 参数1个,0:UPDATE;
update()
else:
MessageBox(desktopHwnd, "您的调用命令是:" & command & "\n" & errMsg, "系统提示", MB_OK or MB_ICONSTOP)
else:
MessageBox(desktopHwnd, "调用参数不能为空", "系统提示", MB_OK or MB_ICONSTOP)
else:
MessageBox(desktopHwnd, "不支持参数调用", "系统提示", MB_OK or MB_ICONSTOP)
阅读排行榜