Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Keyhook - wParam und lParam in ASCII umwandeln (https://www.delphipraxis.net/152447-keyhook-wparam-und-lparam-ascii-umwandeln.html)

erich.wanker 23. Jun 2010 10:42

Delphi-Version: 2005

Keyhook - wParam und lParam in ASCII umwandeln
 
Hallo Leute,

Wenn ein Barcodescanner seine Daten schickt, sendet er ascii20 als erstes, gefolgt von dem Strichcodewerten, abschließend Return. Wenn ascii20 via Tastaturhook kommt, soll meine Anwendung aktiv werden. Aber anstelle ascii20 zu emfangen, empfange ich 2 DllMessages mit Wert 84 und 17 ???



Ein Tastaturhook sendet via:
Delphi-Quellcode:
PostMessage(FindWindow(nil,'Versatile'), WM_USER + 8765,wParam,lParam);

Informationen an "Versatile.exe". Dort werden sie in
Delphi-Quellcode:
procedure TVersatile_main_handle.DllMessage(var Msg: TMessage);

abgefangen und Testweise ausgegeben via:
Delphi-Quellcode:
if msg.WParam <>0 then
begin    
    memo1.Lines.Append('0: ['+inttostr(Msg.wParam)
    +'] 1: ['+inttostr(Msg.lParam)
    +'] 2: ['+inttostr(Msg.Result)
    +'] 3: ['+inttostr(Msg.WParamLo)
    +'] 4: ['+inttostr(Msg.WParamHi)
    +'] 5: ['+inttostr(Msg.LParamLo)
    +'] 6: ['+inttostr(Msg.LParamHi)
    +'] 7: ['+inttostr(Msg.ResultLo)
    +'] 8: ['+inttostr(Msg.ResultHi)
    +']');
end;

ABER:
Wenn ich "Strg" drücke, kommen diese Werte an: (17 wäre ja ascii vom Hardwaredevice 1)
Code:
0: [17] 1: [-1071841279] 2: [0] 3: [17] 4: [0] 5: [1] 6: [49181] 7: [0] 8: [0]
Wenn ich "a" drücke, kommen diese Werte an: (65 wäre ja ascii vom große "A")
Code:
0: [65] 1: [-1071775743] 2: [0] 3: [65] 4: [0] 5: [1] 6: [49182] 7: [0] 8: [0]
und wenn ein Barcodescanner Ascii[20] für Hardwaredevice4 sendet kommt das an:
Code:
0: [84] 1: [-1072431103] 2: [0] 3: [84] 4: [0] 5: [1] 6: [49172] 7: [0] 8: [0]
0: [17] 1: [-1071841279] 2: [0] 3: [17] 4: [0] 5: [1] 6: [49181] 7: [0] 8: [0]
Ich würde aber eigentlich nur den Wert ascii20 benötigen. Wie komm ich zu den Wert ?
Komischerweise ergibt 84 und 17 ..... also 8+4 + 1+7 = 20 ?

Kann mir jemand verraten, was ich da falsch mache?

Vielen Dank

Erich



ich hab schon versucht, den "wparam"-Wert via ToAscii umzuwandeln, wenn aber dann "Strg" gedrückt wird - gibts AccessViolations:
Delphi-Quellcode:
function GetCharFromVKey(vkey: Word): string;
var
   keystate: TKeyboardState;
   retcode: Integer;
begin
   Win32Check(GetKeyboardState(keystate)) ;
   SetLength(Result, 2) ;
   retcode := ToAscii(vkey,
     MapVirtualKey(vkey, 0),
     keystate, @Result[1],
     0) ;
   case retcode of
     0: Result := '';
     1: SetLength(Result, 1) ;
     2: ;
     else
       Result := '';
   end;
end;


Tastaturhook (Freepascal wegen 32 / 64 Bit)
Delphi-Quellcode:
library Versatile32;


{$mode objfpc}{$H+}

{$IFDEF WINDOWS}{$R Versatile32.rc}{$ENDIF}

uses
 Classes,
 Windows,
 ActiveX,
 ShlObj,
 Messages,
 SysUtils;



var
  HookHandle: Cardinal = 0;
  AppHandle: HWND;





function KeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  Result := CallNextHookEx(HookHandle,
                           nCode,
                           wParam,
                           lParam);
  if nCode = HC_NOREMOVE then Exit;


    if ((lParam and (1 shl 30)) <> 0) then
    begin
        if wParam = VK_F4 then
        begin
            PostMessage(FindWindow(nil,'Versatile'), WM_USER + 8765, 300, 0);
        end
        else
        begin
            PostMessage(FindWindow(nil,'Versatile'), WM_USER + 8765,wParam,lParam);
        end;
    end;
end;

function StartHook32(ApplicationHandle: HWND): Boolean; stdcall;
begin
  Result := False;
  if HookHandle = 0 then
    begin
    HookHandle := SetWindowsHookEx(WH_KEYBOARD,
                                   @KeyboardHookProc,
                                   HInstance,
                                   GetCurrentThreadId());
    AppHandle := ApplicationHandle;
    Result := TRUE;
    end;


end;

function StopHook32: Boolean; stdcall;
begin
  Result := UnhookWindowsHookEx(HookHandle);
  HookHandle := 0;
end;

exports
  StartHook32,
  StopHook32;
end.

SirThornberry 23. Jun 2010 12:09

AW: Keyhook - wParam und lParam in ASCII umwandeln
 
Wenn der Barcodescanner nicht 20 schickt kannst du auch nicht 20 empfangen. Da machst du nichts falsch.
Und nur weil die Quersumme der Tastencodes 20 ergibt ist das keine 20 :)
Aber eigentlich ist es doch auch egal ob eine 20 ankommt oder nicht? Dir geht es doch nur darum festzustellen wenn etwas vom Barcodescanner kommt. Und wenn dieser anstelle einer 20 etwas anderes schickt reagiere doch einfach auf das andere.

erich.wanker 23. Jun 2010 14:26

AW: Keyhook - wParam und lParam in ASCII umwandeln
 
Hallo SirThornberry,

komisch bei der ganzen Sache ist aber, das mit meinem aktuellen Keyhook "Strg" dann als "pseudo ascii 17" ermittelt wird .. und das bringt Probleme (soll ja HardwareDevice1 bleiben)

Wenn Barcode ascii20 schickt - bekomm ich per Postmessage 2 Meldungen (keyup wird ja geschluckt)
  • ascii 84 wurde gedrückt
  • ascii 17 wurde gedrückt

Mein "alter" Keyhook machte das nicht ;-)

Der neue ist auf Lazarus (wegen 32 und 64 Bit) geschrieben...

und siehe da - ich schaffs nicht, das :evil::twisted: ascii20 zeichen zu empfangen ...:oops:




schöne Grüße
Erich



Der "alte" Keyhook alá Delphi7:

Delphi-Quellcode:
library Versatile;

uses
  Windows,
  Messages,
  SysUtils;

type
  PHookRec = ^THookRec;
  THookRec = record
    AppHnd: Integer;
    MemoHnd: Integer;
  end;

var
  Hooked: Boolean;
  hKeyHook, hMemo, hMemFile, hApp: HWND;
  PHookRec1: PHookRec;




function KeyHookFunc(Code, VirtualKey, KeyStroke: Integer): LRESULT; stdcall;
var
  KeyState1: TKeyBoardState;
  AryChar: array[0..1] of Char;
  Count: Integer;
begin
  Result := 0;

  if Code = HC_NOREMOVE then Exit;
  Result := CallNextHookEx(hKeyHook, Code, VirtualKey, KeyStroke);
  if Code < 0 then Exit;

  if Code = HC_ACTION then
  begin

    if ((KeyStroke and (1 shl 30)) <> 0) then
      if not IsWindow(hMemo) then
      begin
        hMemFile := OpenFileMapping(FILE_MAP_WRITE, False, 'Versatile_mapping');
        PHookRec1 := MapViewOfFile(hMemFile, FILE_MAP_WRITE, 0, 0, 0);
        if PHookRec1 <> nil then
        begin
          hMemo := PHookRec1.MemoHnd;
          hApp := PHookRec1.AppHnd;
        end;
      end;

   


    if ((KeyStroke and (1 shl 30)) <> 0) then      
    begin
      GetKeyboardState(KeyState1);
      Count := ToAscii(VirtualKey, KeyStroke, KeyState1, AryChar, 0);

      if VirtualKey = VK_F4 then
      begin
        PostMessage(hApp, WM_USER + 8765, 300 , 0);
      end;

      if Count = 1 then
      begin
         PostMessage(hApp, WM_USER + 8765, Ord(AryChar[0]), 0);
      end;
    end;
  end;

  // ........

end; // procedure




function StartHook(MemoHandle, AppHandle: HWND): Byte; export;
begin
  Result := 0;
  if Hooked then
  begin
    Result := 1;
    Exit;
  end;
  if not IsWindow(MemoHandle) then
  begin
    Result := 4;
    Exit;
  end;
  hKeyHook := SetWindowsHookEx(WH_KEYBOARD, KeyHookFunc, hInstance, 0);
  if hKeyHook > 0 then
  begin

    hMemFile := CreateFileMapping($FFFFFFFF, // $FFFFFFFF gets a page memory file
      nil,               // no security attributes
      PAGE_READWRITE,    // read/write access
      0,                 // size: high 32-bits
      SizeOf(THookRec),  // size: low 32-bits
      //SizeOf(Integer),
      'Versatile_mapping');   // name of map object
    PHookRec1 := MapViewOfFile(hMemFile, FILE_MAP_WRITE, 0, 0, 0);
    hMemo := MemoHandle;
    PHookRec1.MemoHnd := MemoHandle;
    hApp := AppHandle;
    PHookRec1.AppHnd := AppHandle;
    {set the Memo and App handles to the mapped file}
    Hooked := True;
  end
  else
    Result := 2;
end;



function StopHook: Boolean; export;
begin
  if PHookRec1 <> nil then
  begin
    UnmapViewOfFile(PHookRec1);
    CloseHandle(hMemFile);
    PHookRec1 := nil;
  end;
  if Hooked then
    Result := UnhookWindowsHookEx(hKeyHook)
  else
    Result := True;
  Hooked := False;
end;

procedure EntryProc(dwReason: DWORD);
begin
  if (dwReason = Dll_Process_Detach) then
  begin
    if PHookRec1 <> nil then
    begin
      UnmapViewOfFile(PHookRec1);
      CloseHandle(hMemFile);
    end;
    UnhookWindowsHookEx(hKeyHook);
  end;
end;

exports
  StartHook,
  StopHook;

begin
  PHookRec1 := nil;
  Hooked := False;
  hKeyHook := 0;
  hMemo := 0;
  DLLProc := @EntryProc;
  EntryProc(Dll_Process_Attach);
end.

erich.wanker 23. Jun 2010 14:40

AW: Keyhook - wParam und lParam in ASCII umwandeln
 
oh mann ... ich probier mal was ganz simples..

Da es sich nur um EAN13 Codes handelt, bekomm ich immer 12 Zahlen... charakteristisch für die Barcodescannereingabe ist die "Eingabezeit" ....

So auf die Art::idea:
Wenn die letzten 12 Eingaben reine Zahlenwerte waren und diese Eingabe unter einer Sekunde erfolgte - dann ist es wahrscheinlich ein Barcode....

So könnte ich auf das Initialisierungszeichen ascii20 komplett versichten


:?:

erich.wanker 23. Jun 2010 15:39

AW: Keyhook - wParam und lParam in ASCII umwandeln
 
OK .. Test funktioniert ..

Delphi-Quellcode:
function mylength(s: String): Integer;
var
  len: Integer;
begin
  len := 1;
  while s[len] <> #0 do
    inc(len);
  result := len-1;
end;
Delphi-Quellcode:
var
    zeit1,zeit2,zeit3,zeit4,zeit5,zeit6,zeit7,zeit8,zeit9,zeit10,zeit11,zeit12     :TTime;
    barcodestring      :String;
    barcodelaenge      :Integer;
    hilfestring        :String;
Delphi-Quellcode:
procedure TVersatile_main_handle.DllMessage(var Msg: TMessage);
begin

//*********************************************************
//*********************************************************
//*********************  Barcodesachen.....     **********
//*********************************************************
//*********************************************************

if (Msg.wParam >47) AND (Msg.wParam <58) then
begin
//das Ding ist eine Zahl

            zeit12 :=zeit11;
            zeit11 :=zeit10;
            zeit10 :=zeit9;
            zeit9  :=zeit8;
            zeit8  :=zeit7;
            zeit7  :=zeit6;
            zeit6  :=zeit5;
            zeit5  :=zeit4;
            zeit4  :=zeit3;
            zeit3  :=zeit2;
            zeit2  :=zeit1;
            zeit1  :=now;

     barcodestring:=barcodestring+char(Msg.wParam);

     if mylength(barcodestring) > 12 then
     begin
     hilfestring:=copy(barcodestring,2,12); {-->}  barcodestring:= hilfestring;
     end;
memo1.Lines.Append('barcodestring= '+barcodestring);
     if mylength(barcodestring) = 12 then
     begin
     // ich hab eine Anzahl von 12 Zahlen gesammelt
         if zeit1-zeit12 <3 then
         begin
         memo1.Lines.Append('***** Barcode : '+barcodestring);
         barcodestring:='';
         end;

     end;


end
else
begin
//das Ding ist KEINE Zahl
     barcodestring:='';
end;

SirThornberry 23. Jun 2010 17:07

AW: Keyhook - wParam und lParam in ASCII umwandeln
 
Du hast jetzt 99 Beiträge und ich dachte eigentlich da weiß man dann inzwischen das pushen innerhalb von 24 Stunden in der DP nicht erwünscht ist. Bitte unterlasse das zukünftig und verwende den "bearbeiten"-Button :)

Warum merkst du dir eigentlich 12 Zeiten? merke dir doch einfach nur eine Zeit bei Eintreffen des ersten Zeichens und wenn du das letzte Zeiten empfangen hast kannst du diese eine Zeit mit der aktuellen Zeit vergleichen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:56 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz