Programma di esempio SCANNER.PRT
; SCANNER
;
; Programma per Proteus
;
; (C) 2004 Simone Zanella Productions
;
; Introduce in emulazione di tastiera i dati in arrivo da un dispositivo seriale (ad esempio uno scanner per codici
; a barre). 
; Questo programma può essere installato come script associato al servizio Proteus.
;
; I parametri di comunicazione si trovano all'inizio del programma e sono:
; - COMPORT = porta di comunicazione ("COM1", "COM2", ecc.)
; - COMSPEED = velocità di comunicazione (1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200)
; - COMPARITY = "N" (nessuna), "E" (pari), "O" (dispari), "M" (marca), "S" (spazio)
; - COMDATA = 7 o 8 (bit di dati)
; - COMSTOP = 1 o 2 (bit di stop)
; - COMFLOW = "R" (RTS/CTS detto anche hardware), "X" (XON/XOFF detto anche software), "E" (entrambi), "N" (nessuno)
; - POSTFIX = terminatore (di solito, "{ENTER}")
;
; In dettaglio, il programma esegue le seguenti operazioni:
; - ogni mezzo secondo verifica se ci sono dei dati in ingresso sulla seriale;
; - se trova qualcosa, controlla che l'ultimo carattere sia CHR(13) = carattere terminatore; in questo caso,
;   invia il dato in emulazione di tastiera e ci aggiunge il carattere POSTFIX.
;
; Il codice commentato più sotto permette anche in alternativa di:
; - selezionare una specifica finestra (applicativo Ultra-Edit) ed inviare il dato verbatim, seguito da Invio;
; - lanciare il blocco note (se non aperto), introdurre il dato verbatim (seguito da Invio) e tornare alla finestra
;   iniziale.

#!proteus -z -j

!include "win32.prt"

; Parametri di default: COM1, 9600, N, 8, 1, controllo di flusso XON/XOFF
CONST COMPORT = "COM1"
CONST COMSPEED = 9600
; Parità (None, Odd, Even, Mark, Space: solo iniziale)
CONST COMPARITY = "N"
CONST COMDATA = 8
CONST COMSTOP = 1
CONST COMFLOW = "X"
CONST POSTFIX = "{ENTER}"

; Apre la seriale con i parametri specificati
HCom = ApriSeriale(COMPORT, COMSPEED, COMPARITY, COMDATA, COMSTOP, COMFLOW)

S = ""

WHILE 1
  ; Attende mezzo secondo
  W32WAITRXCHAR(HCom, 500)
  
  ; Verifica se c'è qualcosa sulla porta seriale
  S1 = W32READCOM(HCom, 0)
  WHILE STRLEN(S1)
    S = S S1
    S1 = W32READCOM(HCom, 0)
  LOOP

  ; Controlla il terminatore ed invia i dati  
  P = STRSTR(S, CHR(13))
  WHILE P
    Dato1 = LEFT(S, DEC(P))
    S = RESTFROM(S, INC(P))
    
    ; >>> Codice di esempio commentato (funzionamento alternativo) <<<
    ;
    ; Seleziona una specifica finestra (che sappiamo essere sicuramente esistente) prima di
    ; inviare il dato in emulazione di tastiera, senza ulteriori elaborazioni, tranne l'aggiunta del tasto Invio.
    ;
    ; IF STRLEN(Dato1)
    ;   W32SETFOCUS(W32FINDWINDOW("*ULTRAEDIT-32*"))
    ;   W32SENDKEYS(KTrans(Dato1) "{ENTER}")
    ; FI
    ; CONTINUE

    ; >>> Codice di esempio commentato (funzionamento alternativo) <<<
    ;
    ; Seleziona la finestra del Blocco note; se non esiste, lancia il programma, attende 2 secondi, quindi
    ; introduce il dato in emulazione di tastiera, senza ulteriori elaborazioni.
    ; Il fuoco (= finestra in primo piano) al termine torna all'applicazione precedentemente in evidenza.
    ;
    ; IF STRLEN(Dato1)
    ;   Hold = W32GETFOCUS()
    ;     
    ;   H = W32FINDWINDOW("*Blocco note*")
    ;   IF EQ(H, 0)
    ;     W32SHELL("NOTEPAD.EXE")
    ;     SLEEP(2)
    ;     H = W32FINDWINDOW("*Blocco note*")
    ;   FI
    ;   IF NEQ(H, 0)
    ;     W32SETFOCUS(H)
    ;     W32SENDKEYS(KTrans(Dato1))
    ;   ELSE
    ;     CONSOLELN "Impossibile aprire blocco note!"
    ;   FI
    ;   W32SETFOCUS(Hold)
    ; FI
    ; CONTINUE
    
    W32SENDKEYS(KTrans(Dato1) POSTFIX)
    P = STRSTR(S, CHR(13))
  LOOP
LOOP
W32CLOSEHANDLE(HCom)
ABORT 0   


FUNCTION KTrans(s)

; Mappatura dei caratteri speciali: caratteri che non si trovano
; sulla tastiera potrebbero richiedere l'introduzione della sequenza
; con ALT + numero

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)

; Apre la seriale con i parametri indicati

  hcom = W32CREATEFILE(comport, NOR(_W32_GENERIC_WRITE, _W32_GENERIC_READ), 0, \
                       _W32_OPEN_EXISTING, 0)
  
  IF EQ(hcom, -1)
    CONSOLELN "Impossibile aprire " comport "."
    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 "Errore nell'impostazione della porta (" 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
Indice esempi Prossimo esempio Esempio precedente Indice per argomenti Indice analitico