首页 > 计算机技术 > 后端开发 > Nim

B/S架构POS客户端开发之三-本地打印程序的实现

原创 lihf8515 2025年02月15日 18:11
来源:本站 阅读:527

本篇是 B/S架构POS客户端开发之三-本地打印程序的实现篇。

接上篇,https://www.hfsoft.top/article/55.html 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)

作者
昵称:君子如兰
注册时间:2025-01-31 02:47:34
最近更新:2026-03-05 14:38:55
文章总数:100篇
原创 94篇   转载 6篇
友情链接: 海峰收银系统  
Copyright © 2009-2026 hfsoft.top All Rights Reserved.
中华人民共和国工业和信息化部ICP备案序号:皖ICP备2025073039号