; SCANNER
;
; Program for Proteus
;
; (C) 2004 Simone Zanella Productions
;
; Emulates keyboard (wedge emulation) by entering data coming from a serial device (e.g. a barcode scanner).
; This program can be installed as a script for Proteus Service.
;
; Communication parameters can be found at the very beginning of the program; the meaning is as follow:
; - COMPORT = communication port ("COM1", "COM2", etc.)
; - COMSPEED = communication speed (1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200 baud)
; - COMPARITY = "N" (none), "E" (even), "O" (odd), "M" (mark), "S" (space)
; - COMDATA = 7 o 8 (data bits)
; - COMSTOP = 1 o 2 (stop bits)
; - COMFLOW = "R" (RTS/CTS or hardware), "X" (XON/XOFF or software), "E" (both), "N" (none)
; - POSTFIX = terminator (usually: "{ENTER}")
;
; In detail, the program does the following:
; - every half second verifies if there are data waiting at the serial port;
; - if it finds something, checks if the last character is CHR(13); in this case,
; emulate keyboard by sending preceding data and appends POSTFIX.
;
; The lines below (commented out) allow for alternate behaviours:
; - bring to the foreground a specific window (Ultra-Edit) and emulate keyboard;
; - open notepad (if it is not running), emulate keyboard and return to previous window.
#!proteus -z -j
!include "win32.prt"
; Default parameters: COM1, 9600, N, 8, 1, XON/XOFF flowcontrol
CONST COMPORT = "COM1"
CONST COMSPEED = 9600
; Parity (None, Odd, Even, Mark, Space: only first letter)
CONST COMPARITY = "N"
CONST COMDATA = 8
CONST COMSTOP = 1
CONST COMFLOW = "X"
CONST POSTFIX = "{ENTER}"
; Open serial port with specified parameters
HCom = ApriSeriale(COMPORT, COMSPEED, COMPARITY, COMDATA, COMSTOP, COMFLOW)
S = ""
WHILE 1
; Wait 500 ms
W32WAITRXCHAR(HCom, 500)
; Verify if data is available at the serial port
S1 = W32READCOM(HCom, 0)
WHILE STRLEN(S1)
S = S S1
S1 = W32READCOM(HCom, 0)
LOOP
; Search terminator and emulate keyboard
P = STRSTR(S, CHR(13))
WHILE P
Dato1 = LEFT(S, DEC(P))
S = RESTFROM(S, INC(P))
; >>> Additional code commented out (alternate behaviour) <<<
;
; Bring to the foreground a specific window (which is known to exist) before
; emulating keyboard.
;
; IF STRLEN(Dato1)
; W32SETFOCUS(W32FINDWINDOW("*ULTRAEDIT-32*"))
; W32SENDKEYS(KTrans(Dato1) "{ENTER}")
; FI
; CONTINUE
; >>> Additional code commented out (alternate behaviour) <<<
;
; Select Notepad window; if it does not exist, run the program, wait 2 seconds, then
; emulate keyboard. Focus is returned to the window which had it before selecting Notepad window.
;
; IF STRLEN(Dato1)
; Hold = W32GETFOCUS()
;
; H = W32FINDWINDOW("*Notepad*")
; IF EQ(H, 0)
; W32SHELL("NOTEPAD.EXE")
; SLEEP(2)
; H = W32FINDWINDOW("*Notepad*")
; FI
; IF NEQ(H, 0)
; W32SETFOCUS(H)
; W32SENDKEYS(KTrans(Dato1))
; ELSE
; CONSOLELN "Notepad could not be opened!"
; FI
; W32SETFOCUS(Hold)
; FI
; CONTINUE
W32SENDKEYS(KTrans(Dato1) POSTFIX)
P = STRSTR(S, CHR(13))
LOOP
LOOP
W32CLOSEHANDLE(HCom)
ABORT 0
FUNCTION KTrans(s)
; Special characters: characters which are not available on the keyboard
; require special treatment (Alt + 3 digits) - useful for foreign keyboards
l = STRLEN(s)
r = ""
FOR x = 1 TO l
c = SUBSTR(s, x, 1)
SWITCH c STREQ
ON "~"
r = r "{ALT DOWN}{NUMPAD1}{NUMPAD2}{NUMPAD6}{ALT UP}"
ON "{"
r = r "{ALT DOWN}{NUMPAD1}{NUMPAD2}{NUMPAD3}{ALT UP}"
ON "}"
r = r "{ALT DOWN}{NUMPAD1}{NUMPAD2}{NUMPAD5}{ALT UP}"
ON "+", "^", "%", "(", ")", "[", "]"
r = r "{" c "}"
OTHER
r = r c
OFF
NEXT
RETURN r
FUNCTION ApriSeriale(comport, comspeed, comparity, comdata, comstop, comflow)
; Open serial port with specified parameters
hcom = W32CREATEFILE(comport, NOR(_W32_GENERIC_WRITE, _W32_GENERIC_READ), 0, \
_W32_OPEN_EXISTING, 0)
IF EQ(hcom, -1)
CONSOLELN "Port " comport " could not be opened."
ABORT 2
FI
compar = VECNEW(13)
v = W32GETCOMSTATE(hcom, compar)
VECSET(compar, 2, comspeed)
v = NOR(_W32_COM_BINARY, _W32_COM_PARITY_ON)
SWITCH comflow STREQ
ON "R"
NOR(@v, _W32_COM_RTS_HANDSHAKE, _W32_COM_CTSFLOW_ON)
ON "X"
NOR(@v, _W32_COM_XONXOFF_OUT, _W32_COM_XONXOFF_IN, _W32_COM_XOFF_CONTINUE)
ON "E"
NOR(@v, _W32_COM_RTS_HANDSHAKE, _W32_COM_CTSFLOW_ON, \
_W32_COM_XONXOFF_OUT, _W32_COM_XONXOFF_IN, _W32_COM_XOFF_CONTINUE)
ON "N"
OFF
VECSET(compar, 3, v)
VECSET(compar, 7, comdata)
SWITCH LEFT(comparity, 1) STRIEQ
ON "N"
v = _W32_COM_PARITY_NONE
ON "E"
v = _W32_COM_PARITY_EVEN
ON "O"
v = _W32_COM_PARITY_ODD
ON "M"
v = _W32_COM_PARITY_MARK
ON "S"
v = _W32_COM_PARITY_SPACE
OFF
VECSET(compar, 8, v)
SWITCH comstop
ON 1
VECSET(compar, 9, 0)
ON 2
VECSET(compar, 9, 2)
OFF
v = W32SETCOMSTATE(hcom, compar)
VECFREE(compar)
IF v
CONSOLELN "Error configuring port (" W32GETLASTERROR() ")."
W32CLOSEHANDLE(hcom)
ABORT 3
FI
tout = VECNEW(5)
VECSET(tout, 1, 0)
VECSET(tout, 2, 0)
VECSET(tout, 3, 0)
VECSET(tout, 4, 0)
VECSET(tout, 5, 0)
W32SETCOMTIMEOUTS(hcom, tout)
VECFREE(tout)
RETURN hcom