Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Warten bis Event OnKeyDown abgearbeitet ist (https://www.delphipraxis.net/191348-warten-bis-event-onkeydown-abgearbeitet-ist.html)

concept2015 5. Jan 2017 09:18

Delphi-Version: 7

Warten bis Event OnKeyDown abgearbeitet ist
 
Problem gelöst !!!
Ich habe in meiner Routine den Focus auf Edit26 gesetzt !
Das war der Fehler
Der Focus geht automatisch weiter.:shock: :oops:

************************************************** **************


Hallo Spezialisten,
ich habe ein Problem, welches ich auch nach längerem suchen nicht gelöst bekomme. (kann sein, dass ich auch nicht nach dem richtigen Begiff gesucht habe)
Ursprünglich habe ich meine Programme mit Visual Dbase programmiert.
Seit dem Tod des Mitarbeiters, in der Firma meines Freundes, der die Programme in dieser Firma entwickelt hat, beschäftige ich mich mit Delphi (freiwillig und kostenlos)
Jetzt zu meinem Problem:
In dem bestehenden Programm werden Zahlen von Hand, in mehrere Edit Felder eingetragen und ausgewertet.

Für dieses Programm habe ich eine optische Leseeinheit (Auswertung von Belegen in denen Zahlen markiert sind) eingebunden.
Hier werden jetzt mehrere Zahlen bereitgestellt.

Mein Problem ist: an Edit1 (bestehendes Prog.) wird eine Zahl gesendet und mit
Keybd_Event(VK_RETURN,0,0,0);
Keybd_Event(VK_RETURN,0,KEYEVENTF_KEYUP,0);
übergeben.
Jetzt wird das Event TForm1.Edit1KeyDown ausgelöst und eine Folge abgearbeitet.

In meiner Prozedur muss jetzt gewaret werden bis das Event TForm1.Edit1KeyDown abgearbeitet ist bevor ich in das nächste Feld(Edti26) die nächste Zahl eintragen kann.

Das bekomme ich nicht hin :cry:

Kurzfassung:
Mehrere Editfelder werden automatisch ausgefüllt.
Ich sende (aus meiner Procedure) Zahl 1 an Edit1 in der gleichen Form.
Bevor ich Zahl2 an Edit26 sende, muss das Event von Edit1 fertig sein.

Bitte dringend um HILFE :roll:

Jumpy 5. Jan 2017 09:49

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Mir ist jetzt nicht ganz klar geworden, ob das alles im selben Programm stattfindet, oder ob das Programm mit den Edits von einem externen Programm gesteuert/gefüllt wird?

concept2015 5. Jan 2017 09:52

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Tut mir leid ... habe es hinbekommen.
Alles in einem Programm (6000 Zeilen) :cry:

baumina 5. Jan 2017 12:35

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Wenn alles innerhalb des Delphiprogramms läuft, würde ich statt irgendwelche Tasten auszulösen (z.B. VK_RETURN) lieber die Edits direkt füllen (Edit1.Text := 'blabla').

p80286 5. Jan 2017 13:35

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
@Baumina
Ich vermute das:
Zitat:

Für dieses Programm habe ich eine optische Leseeinheit (Auswertung von Belegen in denen Zahlen markiert sind) eingebunden.
Hier werden jetzt mehrere Zahlen bereitgestellt.
steckt dahinter. Und da viele Benutzer/Chefs nicht in der Lage sind zu sagen was sie wollen/benötigen kommen dann solche Durchdiebrustinsaugekonstrukte heraus.

Gruß
K-H

concept2015 5. Jan 2017 15:17

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Hallo,
meine Routine hat 6 Zahlen gelesen und soll sie nun in dem Hauptprogramm in die vorhandenen Felder eintragen.

Es geht darum, ca 300 Belege werden täglich eingegeben (von Hand)
Um diese Arbeit zu vereinfachen, werde ich die Belege umstellen.

Es werden keine Zahlen auf den Beleg geschrieben sondern Zahlen markiert.
Diese Markierungen werden von einem anderen Programm gelesen und
in die entsprechenden Zahlen umgewandelt.

Klappt alles !

Jetzt sollen diese Zahlen im eigentlichen Programm per Button übertragen werden ... Klappt auch alles ... bis auf einen Fehler,
der sich erst jetzt herausgestellt hat.

Die letzte Zahl z.B 118,50 (das ist die einzige Zahl mit Dezimalstellen)
wird nicht richtig übernommen ! das Komma fehlt !

Eingetragen wird 11850
Zum übertragen nutze ich die PostKeyExHWND Prozedur die hier im Forum schon mehrfach besprochen wurde.

Alles klappt wunderbar ! nur dieses Komma oder Punkt wird in der Procedure gelöscht oder übergangen :cry:

Habt Ihr eine Idee ?

nahpets 5. Jan 2017 16:42

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Wenn ich das recht sehe, werden die Edits doch zeichenweise befüllt.

Die Frage, die sich für mich stellt ist nun: Wird das Komma vom Leseeinheit denn geliefert?

p80286 5. Jan 2017 17:00

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Zitat:

Zitat von concept2015 (Beitrag 1358178)
Die letzte Zahl z.B 118,50 (das ist die einzige Zahl mit Dezimalstellen)
wird nicht richtig übernommen ! das Komma fehlt !

Eingetragen wird 11850

Wie sieht der Übertragungs-Source-Code aus?
gibt es da einen Filter der nur Ziffern durch lässt?

Gruß
K-H

concept2015 6. Jan 2017 06:42

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Ja, es wird zeichenweise befüllt.
Ja, dass Komma ist in der Zahl.

Hier der Link, in dem hier schon etwas besprochen wurde.

http://www.delphipraxis.net/110482-a...nd-delphi.html

Wie gesagt, alles klappt wunderbar, bis auf das Komma.

Da blicke ich nicht durch.

Der Str5:string sieht z.B. so aus 118,65
Im Editfeld wird aber das eingetragen 11865
Von Hand kann die Zahl aber selbstverständlich mit , eingegeben werden.

Es liegt eindeutig an der Routine.
Hab ein kleines Prog. geschrieben, nur mit dieser Routine und einem Editfeld ... kein Komma.
************************************** Testcode
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Timer1: TTimer;
Edit1: TEdit;
Edit2: TEdit;
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
procedure PostKeyExHWND(hWindow: HWnd; key: Word; const shift: TShiftState;
specialkey: Boolean);
type
TBuffers = array [0..1] of TKeyboardState;
var
pKeyBuffers: ^TBuffers;
lParam: LongInt;
begin

(* check if the target window exists *)
if IsWindow(hWindow) then
begin
(* set local variables to default values *)
pKeyBuffers := nil;
lParam := MakeLong(0, MapVirtualKey(key, 0));

(* modify lparam if special key requested *)
if specialkey then
lParam := lParam or $1000000;

(* allocate space for the key state buffers *)
New(pKeyBuffers);
try
(* Fill buffer 1 with current state so we can later restore it.
Null out buffer 0 to get a "no key pressed" state. *)
GetKeyboardState(pKeyBuffers^[1]);
FillChar(pKeyBuffers^[0], SizeOf(TKeyboardState), 0);

(* set the requested modifier keys to "down" state in the buffer*)
if ssShift in shift then
pKeyBuffers^[0][VK_SHIFT] := $80;
if ssAlt in shift then
begin
(* Alt needs special treatment since a bit in lparam needs also be set *)
pKeyBuffers^[0][VK_MENU] := $80;
lParam := lParam or $20000000;
end;
if ssCtrl in shift then
pKeyBuffers^[0][VK_CONTROL] := $80;
if ssLeft in shift then
pKeyBuffers^[0][VK_LBUTTON] := $80;
if ssRight in shift then
pKeyBuffers^[0][VK_RBUTTON] := $80;
if ssMiddle in shift then
pKeyBuffers^[0][VK_MBUTTON] := $80;

(* make out new key state array the active key state map *)
SetKeyboardState(pKeyBuffers^[0]);
(* post the key messages *)
if ssAlt in Shift then
begin
PostMessage(hWindow, WM_SYSKEYDOWN, key, lParam);
PostMessage(hWindow, WM_SYSKEYUP, key, lParam or $C0000000);
end
else
begin
PostMessage(hWindow, WM_KEYDOWN, key, lParam);
PostMessage(hWindow, WM_KEYUP, key, lParam or $C0000000);
end;
(* process the messages *)
Application.ProcessMessages;

(* restore the old key state map *)
SetKeyboardState(pKeyBuffers^[1]);
finally
(* free the memory for the key state buffers *)
if pKeyBuffers <> nil then
Dispose(pKeyBuffers);
end; { If }
end;
end; { PostKeyEx }

procedure TForm1.Button1Click(Sender: TObject);
const
Str1: string = '2340';
Str2: string = '118,65';
var
Inp: TInput;
I: Integer;
begin
//*************************************** 1
Edit1.SetFocus;
for I := 1 to Length(Str1) do
begin
// press
Inp.Itype := INPUT_KEYBOARD;
Inp.ki.wVk := Ord(UpCase(Str1[i]));
Inp.ki.dwFlags := 0;
SendInput(1, Inp, SizeOf(Inp));

// release
Inp.Itype := INPUT_KEYBOARD;
Inp.ki.wVk := Ord(UpCase(Str1[i]));
Inp.ki.dwFlags := KEYEVENTF_KEYUP;
SendInput(1, Inp, SizeOf(Inp));

Application.ProcessMessages;
Sleep(120);
end;
//*************************************** 2
Edit2.SetFocus;
for I := 1 to Length(Str2) do
begin
// press
Inp.Itype := INPUT_KEYBOARD;
Inp.ki.wVk := Ord(UpCase(Str2[i]));
Inp.ki.dwFlags := 0;
SendInput(1, Inp, SizeOf(Inp));

// release
Inp.Itype := INPUT_KEYBOARD;
Inp.ki.wVk := Ord(UpCase(Str2[i]));
Inp.ki.dwFlags := KEYEVENTF_KEYUP;
SendInput(1, Inp, SizeOf(Inp));

Application.ProcessMessages;
Sleep(120);
end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
// Bei Taste + befehl ausführen
if GetAsyncKeyState(VK_ADD) < 0 then Button1Click(Button1);
end;
end.

**************************************
Danke für euer Interesse.

Jasocul 6. Jan 2017 07:15

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Der Ordinal-Wert von "," ist nicht gleich dem virtuellen Tasten-Code.
Das betrifft nicht nur Sonderzeichen, sondern zum Beispiel auch Buchstaben. Die Ordinal-Werte für "A" und "a" sind unterschiedlich. der virtuelle Tasten-Code aber gleich.

Da musst du dir eine Umsetzung für Sonderzeichen basteln.

EWeiss 6. Jan 2017 07:17

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Es wäre schön wenn du die Code Formatierung verwenden würdest.
Dein Beitrag ist leider nicht lesbar.

gruss

concept2015 6. Jan 2017 07:59

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Ich kenne mich in Foren leider noch nicht so gut aus, was das Schreiben betrifft :roll:
Codeformatierung ? über Code einfügen ? sieht alles gleich aus :oops:
Ahh ... hat geklappt !

Umsetzung für Sonderzeichen ????
Hier ?

Code:
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
    // Tasteneingabe nur Numerisch
      if not (key in [#8,#13,#48..#57]) then key := #0;
end;

EWeiss 6. Jan 2017 08:04

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Zitat:

Ich kenne mich in Foren leider noch nicht so gut aus, was das Schreiben betrifft
Dann mache ich das mal für dich.
Und schon ist es lesbar ;)

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Timer1: TTimer;
    Edit1: TEdit;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure PostKeyExHWND(hWindow: HWnd; key: Word; const shift: TShiftState; specialkey: Boolean);
type
  TBuffers = array [0 .. 1] of TKeyboardState;
var
  pKeyBuffers: ^TBuffers;
  lParam: LongInt;
begin

  (* check if the target window exists *)
  if IsWindow(hWindow) then
  begin
    (* set local variables to default values *)
    pKeyBuffers := nil;
    lParam := MakeLong(0, MapVirtualKey(key, 0));

    (* modify lparam if special key requested *)
    if specialkey then
      lParam := lParam or $1000000;

    (* allocate space for the key state buffers *)
    New(pKeyBuffers);
    try
      (* Fill buffer 1 with current state so we can later restore it.
        Null out buffer 0 to get a "no key pressed" state. *)
      GetKeyboardState(pKeyBuffers^[1]);
      FillChar(pKeyBuffers^[0], SizeOf(TKeyboardState), 0);

      (* set the requested modifier keys to "down" state in the buffer *)
      if ssShift in shift then
        pKeyBuffers^[0][VK_SHIFT] := $80;
      if ssAlt in shift then
      begin
        (* Alt needs special treatment since a bit in lparam needs also be set *)
        pKeyBuffers^[0][VK_MENU] := $80;
        lParam := lParam or $20000000;
      end;

      if ssCtrl in shift then
        pKeyBuffers^[0][VK_CONTROL] := $80;
      if ssLeft in shift then
        pKeyBuffers^[0][VK_LBUTTON] := $80;
      if ssRight in shift then
        pKeyBuffers^[0][VK_RBUTTON] := $80;
      if ssMiddle in shift then
        pKeyBuffers^[0][VK_MBUTTON] := $80;

      (* make out new key state array the active key state map *)
      SetKeyboardState(pKeyBuffers^[0]);
      (* post the key messages *)
      if ssAlt in shift then
      begin
        PostMessage(hWindow, WM_SYSKEYDOWN, key, lParam);
        PostMessage(hWindow, WM_SYSKEYUP, key, lParam or $C0000000);
      end
      else
      begin
        PostMessage(hWindow, WM_KEYDOWN, key, lParam);
        PostMessage(hWindow, WM_KEYUP, key, lParam or $C0000000);
      end;
      (* process the messages *)
      Application.ProcessMessages;

      (* restore the old key state map *)
      SetKeyboardState(pKeyBuffers^[1]);
    finally
      (* free the memory for the key state buffers *)
      if pKeyBuffers <> nil then
        Dispose(pKeyBuffers);
    end; { If }
  end;
end; { PostKeyEx }

procedure TForm1.Button1Click(Sender: TObject);
const
  Str1: string = '2340';
  Str2: string = '118,65';
var
  Inp: TInput;
  I: Integer;
begin
  Edit1.SetFocus;
  for I := 1 to Length(Str1) do
  begin
    // press
    Inp.Itype := INPUT_KEYBOARD;
    Inp.ki.wVk := Ord(UpCase(Str1[I]));
    Inp.ki.dwFlags := 0;
    SendInput(1, Inp, SizeOf(Inp));

    // release
    Inp.Itype := INPUT_KEYBOARD;
    Inp.ki.wVk := Ord(UpCase(Str1[I]));
    Inp.ki.dwFlags := KEYEVENTF_KEYUP;
    SendInput(1, Inp, SizeOf(Inp));

    Application.ProcessMessages;
    Sleep(120);
  end;

  Edit2.SetFocus;
  for I := 1 to Length(Str2) do
  begin
    // press
    Inp.Itype := INPUT_KEYBOARD;
    Inp.ki.wVk := Ord(UpCase(Str2[I]));
    Inp.ki.dwFlags := 0;
    SendInput(1, Inp, SizeOf(Inp));

    // release
    Inp.Itype := INPUT_KEYBOARD;
    Inp.ki.wVk := Ord(UpCase(Str2[I]));
    Inp.ki.dwFlags := KEYEVENTF_KEYUP;
    SendInput(1, Inp, SizeOf(Inp));

    Application.ProcessMessages;
    Sleep(120);
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  // Bei Taste + befehl ausführen
  if GetAsyncKeyState(VK_ADD) < 0 then
    Button1Click(Button1);
end;

end.

Jasocul 6. Jan 2017 08:11

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Zitat:

Zitat von concept2015 (Beitrag 1358216)
Umsetzung für Sonderzeichen ????
Hier ?
Code:
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  // Tasteneingabe nur Numerisch
  if not (key in [#8,#13,#48..#57]) then key := #0;
end;

Nein, hier:

Delphi-Quellcode:
Inp.ki.wVk := Ord(UpCase(Str2[i]));
Wenn du an dieser Stelle auf ein Komma triffst, wird der Ordinal-Wert (44) vom Komma übergeben. Du musst aber VK_SEPARATOR (108) übergeben.

concept2015 6. Jan 2017 15:24

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Entschuldige, aber das ist im moment zu hoch für mich.
Ich hänge wohl schon zu lange in dieser Sache.

44 ist doch das Komma und genau das soll doch dort eingetragen werden.

Ich bin LEER im Kopf ... wenn du mir den Lösungsweg zeigst komme ich evtl. dahinter :lol:

Delphi-Quellcode:
if (Inp.ki.wVk=Ord(UpCase(Str1[i])))=(CHR(44)) then Inp.ki.wVk:=(CHR(108)) else Inp.ki.wVk=Ord(UpCase(Str1[i]));
bringt nur Fehler .... HIIILFE ich kann nicht mehr.

concept2015 7. Jan 2017 07:33

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Danke :-D

Hat sich erledigt, habe es anders gelöst.

Wie so oft im Leben, der Wald und die Bäume :wink:

Luckie 8. Jan 2017 03:24

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Und sagst du uns auch, wie du es gelöst hast?

concept2015 8. Jan 2017 08:27

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Ja klar, ursprünglich war geplant, die Daten von einem eigenständigen Programm in das Hauptprogramm als "Tastatureingabe"
zu übergeben.

Da sich das aber als Problem herausstellte, habe ich es jetzt im Hauptprogramm gelassen und fülle die Felder direkt.

Bei der komplexität des Hauptprogramms - jede Eingabe wird erst
geprüft dann zugeordnet und berechnet - war mir das aber zu aufwändig.

Wie gesagt, es lief alles bis auf das Komma.
Da ich aber leider nicht sehr geduldig bin, bin ich jetzt dabei, es im Hauptprogramm zu implementieren.

Ganz nebenbei habe ich auch keine Lust mehr.
Ich schreibe meine Programme eigentlich mit Visual Dbase -
habe jetzt aber Geschmack an Delphi bekommen und musste mich zwischenzeitlich mit Java (Eclipse) wegen der optischen Bearbeitung beschäftigen - mit 62 Jahren geht das alles nicht mehr ganz so mit "links".
Jetzt kommt auch noch C++ (Arduino) für den automatischen Belegeinzug.
Das ganze reicht mir ... und wenn dann auch noch so blöde Fehler wie der mit dem Komma kommen stosse ich an meine Grenzen der Gedult und stehe kurz davor es hinzuschmeissen .... NEEE da steckt zuviel Arbeit drin.

Danke für das Interesse, sollte ich weitere Probleme bekommen, melde ich mich. :cheers:

concept2015 8. Jan 2017 09:44

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Ich hätte da noch etwas :cry:
Im System sind 2 Rechner.
Rechner 1 (bei mir zum testen und programmieren Win10)
in der Firma Win 7

Als Leseeinheit benutze ich einen MiniPc (Win10):Rechner2

Zwischen den beiden Rechnern müssen jetzt Daten ausgetauscht werden.

Rechner1 prüft, ob auf Rechner2 eine Datei vorhanden ist, wenn ja, holt er sich diese Datei zur Weiterverarbeitung.

Das mache ich im Moment über ein Heimnetz (Wlan) Lankabel geht nicht, da Rechner 1 in der Firma vernetzt ist und ich da nicht ran möchte.

Jetzt habe ich mir gedacht, dass beide Rechner USB Anschlüsse haben, über die doch eine Kommunikation möglich sein müsste.
Über einen Arduino beide Rechner mit (USB-(RS232)-USB) verbinden.

Im Rechner1 ist ein Programm (Delphi). dass ein Signal über (USB-(Arduino)-USB) an Rechner2 schickt.
Das Programm in Rechner2 prüft ob die Datei da ist und sendet sie an das Programm in Rechner1 und speichert es in einem Verzeichnis (C:\Austausch)
Damit würde ich alles mit Lan und W-Lan umgehen.

Hat dazu jemand eine Idee ?
In der Theorie ist das kein Problem ... aber die Praxis :?

Luckie 8. Jan 2017 09:46

AW: Warten bis Event OnKeyDown abgearbeitet ist
 
Zitat:

Zitat von concept2015 (Beitrag 1358374)
Ich hätte da noch etwas :cry:

Dann mach bitte einen neuen Thread mit entsprechenden aussagekräftigen Titel auf. Ich schließe hier mal.


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

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