Keytec - usando a dll WinIO para exibir mensagens no teclado com display

Top  Previous  Next

{

  Unit destina a trabalhar com as funções da DLL da KEYTEC para Win9x..XP

  por Flávio Junior

 

  Caso a DLL não esteja presente na máquina nada ocorre, apenas uma mensagem de erro

  18-11-2002

 

  Para Windows 9x não é necessário DLL pode-se chamar as funções com o acesso da porta

  $60 direto!

 

  Apesar de que as funções da DLL também funcionam no 95 e 98 eu não as uso pois são lentas

 

        >\\\!/<

        !_"""_!

        (O) (o)

------ooo-----ooo------------------------------------------------------------------------}

 

unit KeytecUnit;

 

interface

 

var

  // Este handle é usado para fazer a junção da DLL e da unit

  Keytec_Handle_DLL: THandle;

 

// estas duas funções só tem efeito no WinNT

procedure Keytec_CarregaDLL;

procedure Keytec_FinalizaDLL;

// funções para manipulacao

procedure Keytec_Mostra(const Linha1:string; Linha2: string = ''; Alinha1: char = 'E'; Alinha2: char = 'E');

procedure Keytec_Limpa;

procedure Keytec_Char(const C: Char);

 

implementation

 

uses SysUtils, Forms, Windows, ARotinasUnit, ARotinas2Unit;

 

type

  PInitializeWinIo = function                                                  : Boolean; stdcall;

  PShutdownWinIo   = function                                                  : Boolean; stdcall;

  PSetPortVal      = function(PortAddr: Integer; PortVal: Integer; bSize: Byte): Boolean; stdcall;

 

var

  InitializeWinIo: PInitializeWinIo;

  ShutdownWinIo  : PShutdownWinIo;

  SetPortVal     : PSetPortVal;

  Keytec_DLL_Disponivel: Boolean = False;

  Keytec_Primeira      : Boolean = True; // quando for a primeira vez ele desliga o cursor.

 

procedure Alerta;

begin

  if Keytec_Primeira then

    msgAlerta('DLL do teclado KEYTEC (WINIO.DLL) não carregada!');

end;

 

/////////////////////////////////////////////////////////////////////// FUNCOES DA DLL (PARA WINNT, 2000 E XP)

 

// esta rotina chama a função DLL que envia um byte pra teclado

function KeytecDLL_EnviaKeyb(const B: Byte): Boolean;

begin

  if Keytec_DLL_Disponivel then

    Result := SetPortVal($60, B, SizeOf(B))

  else

    Result := False;

  Delay(1); // não consegui colocar Delay(0) nem DoEvents nem monte de Application.ProcessMessages;

end;

 

// limpa o teclado

procedure KeytecDLL_Clear;

begin

  if Keytec_DLL_Disponivel then

  begin

    KeytecDLL_EnviaKeyb($A0);

    KeytecDLL_EnviaKeyb($01);

  end

  else

    Alerta;

end;

 

// remove o cursor

procedure KeytecDLL_NoCursor;

begin

  if Keytec_DLL_Disponivel then

  begin

    KeytecDLL_EnviaKeyb($A0);

    KeytecDLL_EnviaKeyb($0C);

  end

  else

    Alerta;

end;

 

procedure KeytecDLL_DisplayChar(const C: Char);

begin

  if Keytec_DLL_Disponivel then

  begin

    KeytecDLL_EnviaKeyb($A5);

    KeytecDLL_EnviaKeyb(Ord(C));

  end

  else

    Alerta;

end;

 

procedure KeytecDLL_DisplayText(const Texto: string);

var

  I: Integer;

begin

  if Keytec_DLL_Disponivel then

  begin

    KeytecDLL_EnviaKeyb($08);              // inicio da transmissao

    for I := 1 to Length(Texto) do

      KeytecDLL_EnviaKeyb(Ord(Texto[I]));  // envia cada caracter

    KeytecDLL_EnviaKeyb($09);              // fim da transmissao

  end

  else

    Alerta;

end;

 

procedure Keytec_CarregaDLL;

var

  EstadoWin: Word;

  P        : Pointer;

begin

  // só carrega a dll caso seja WinNT, 2000 e XP

  if Win32Platform = VER_PLATFORM_WIN32_NT then

  begin

    EstadoWin := SetErrorMode(sem_NoOpenFileErrorBox);

    Keytec_Handle_DLL := LoadLibrary('WINIO.DLL');

    SetErrorMode(EstadoWin);

    Keytec_DLL_Disponivel := (Keytec_Handle_DLL > HINSTANCE_ERROR);

    P := GetProcAddress(Keytec_Handle_DLL,'InitializeWinIo');  InitializeWinIo := PInitializeWinIo(P);

    P := GetProcAddress(Keytec_Handle_DLL,'ShutdownWinIo');    ShutdownWinIo   := PShutdownWinIo(P);

    P := GetProcAddress(Keytec_Handle_DLL,'SetPortVal');       SetPortVal      := PSetPortVal(P);

  end;

end;

 

procedure Keytec_FinalizaDLL;

begin

  // só finaliza se for WinNt, 2K e XP e a DLL estiver carregada

  if (Win32Platform = VER_PLATFORM_WIN32_NT) and (Keytec_DLL_Disponivel) then

    FreeLibrary(Keytec_Handle_DLL);

end;

 

//////////////////////////////////////////////// FUNCOES DE USO DA PORTA $60 DIRETO - SÓ PARA WIN95 E WIN98

 

procedure Keytec_DisplayChar(const C: Char);

var

  A: Shortint;

begin

  Application.ProcessMessages;

  if C = #27 then // troca o ESC por "x"

    A := Ord('x')

  else

    A := Ord(C);

  asm

    mov    al,165;

    out    60h,al

    in     al,60h

 

    mov    al,A;

    out    60h,al

    in     al,60h

  end;

end;

 

procedure Keytec_DisplayText(const Texto:string);

var

  I: Integer;

  A: Shortint;

begin

  // os dados devem ser enviados 1 por vez ao port 60h

  asm

    mov    al,08;  // o valor que está sendo movido para al, é o comando, ou os dados.

    out    60h,al

    in     al,60h

  end;

 

  for I := 1 to Length(texto) do

  begin

    A := Ord(Texto[I]);

    Application.ProcessMessages;

    asm

      mov    al,A;

      out    60h,al

      in     al,60h

    end;

  end;

 

  asm

    mov    al,09;

    out    60h,al

    in     al,60h

  end;

end;

 

procedure Keytec_Clear;

begin

  Application.ProcessMessages;

  asm

    mov    al,160;

    out    60h,al

    in     al,60h

 

    mov    al,01;

    out    60h,al

    in     al,60h

  end;

end;

 

procedure Keytec_NoCursor;

begin

  Application.ProcessMessages;

  asm

    mov    al,160;

    out    60h,al

    in     al,60h

 

    mov    al,0Ch;

    out    60h,al

    in     al,60h

  end;

end;

 

///////////////////////////////////////////////////////////////// IMPLEMENTACAO

 

procedure Keytec_Mostra(const Linha1:string; Linha2: string = ''; Alinha1: char = 'E'; Alinha2: char = 'E');

var

  S1, S2: string;

begin

  // prepara as strings

  if Linha1 <> '' then

  begin

    S1 := TiraAcentos(Linha1);

    case Alinha1 of

      'C': S1 := AlinhaCentro(S1, 40);

      'E': S1 := AlinhaEsq(S1, 40);

      'D': S1 := AlinhaDir(S1, 40);

    end;

  end;

 

  if Linha2 <> '' then

  begin

    S2 := TiraAcentos(Linha2);

    case Alinha2 of

      'C': S2 := AlinhaCentro(S2, 40);

      'E': S2 := AlinhaEsq(S2, 40);

      'D': S2 := AlinhaDir(S2, 40);

    end;

  end;

 

  // para NT, 2000 e XP chama DLL

  if Win32Platform = VER_PLATFORM_WIN32_NT then

  begin

    if Keytec_Primeira then KeytecDLL_NoCursor;

    KeytecDLL_Clear;

    if S1 <> '' then KeytecDLL_DisplayText(S1);

    if S2 <> '' then KeytecDLL_DisplayText(S2);

  end  //// 95 e 98

  else

  begin

    if Keytec_Primeira then Keytec_NoCursor;

    Keytec_Clear;

    if S1 <> '' then Keytec_DisplayText(S1);

    if S2 <> '' then Keytec_DisplayText(S2);

  end;

  if Keytec_Primeira then Keytec_Primeira := False;

end;

 

procedure Keytec_Limpa;

begin

  if Win32Platform = VER_PLATFORM_WIN32_NT then

    KeytecDLL_Clear

  else

    Keytec_Clear;

end;

 

procedure Keytec_Char(const C: Char);

begin

  if Win32Platform = VER_PLATFORM_WIN32_NT then

    KeytecDLL_DisplayChar(C)

  else

    Keytec_DisplayChar(C);

end;

 

end.