Tastendruck per Message an TEdit senden
Tastendruck per Message an TEdit senden
Hallo Freunde,
ich habe ein kleines Problem. Ich möchte den Text in einem Eingabefeld TEdit ( LCL ) mit Hilfe von z.B. KeyDown-Messages verändern. Für mein Projekt habe ich keine Tastatur. Nur eine Maus. Also habe ich jede Menge Buttons mit Buchstaben erstellt und beim Klick soll der entsprechende Buchstabe im Text-Feld erscheinen.
Ich habe es bereits mit ~.Perform und ~.Dispatch probiert. Leider ändert sich nichts am Eingabefeld. Ich hab schon so viel getüftelt, debuggt und probiert. Ich weiß nicht woran es liegt.
Ich benutze Linux und auch das Projekt soll später im Linux laufen. Möglicherweise muss man dort etwas anders machen?.
Hat jemand von Euch eine Idee, wie ich das genau machen muss?
ich habe ein kleines Problem. Ich möchte den Text in einem Eingabefeld TEdit ( LCL ) mit Hilfe von z.B. KeyDown-Messages verändern. Für mein Projekt habe ich keine Tastatur. Nur eine Maus. Also habe ich jede Menge Buttons mit Buchstaben erstellt und beim Klick soll der entsprechende Buchstabe im Text-Feld erscheinen.
Ich habe es bereits mit ~.Perform und ~.Dispatch probiert. Leider ändert sich nichts am Eingabefeld. Ich hab schon so viel getüftelt, debuggt und probiert. Ich weiß nicht woran es liegt.
Ich benutze Linux und auch das Projekt soll später im Linux laufen. Möglicherweise muss man dort etwas anders machen?.
Hat jemand von Euch eine Idee, wie ich das genau machen muss?
Re: Tastendruck per Message an TEdit senden
Ändere doch einfach den Text
Code: Alles auswählen
Edit.Text := Edit.Text + Eingabe;
Re: Tastendruck per Message an TEdit senden
Die Idee hatte ich schon.
Das Eingabe-Feld hat aber alle anderen Eigenschaften noch. Und somit kann auch ein Teil im Wort oder Text markiert sein. Text=Text + Zeichen fügt aber nur ein Zeichen hinten an. Wenn der Cursor mitten im Wort steht (z.B. per Mausklick dahin gesetzt), muss das Zeichen dort eingefügt werden.
Ideal wäre also eine Tasten-Message.
Im Delphi klappt das mit Eingabefeld.Perform( WM_KEYDOWN, Zeichen, 0). Im Lazarus funktioniert es nicht
Ich habe zwischenzeitlich auch mal Lazarus unter Windows probiert. Da funktioniert es auch nicht. Es schein also nicht am Betriebssystem zu liegen.
Das Eingabe-Feld hat aber alle anderen Eigenschaften noch. Und somit kann auch ein Teil im Wort oder Text markiert sein. Text=Text + Zeichen fügt aber nur ein Zeichen hinten an. Wenn der Cursor mitten im Wort steht (z.B. per Mausklick dahin gesetzt), muss das Zeichen dort eingefügt werden.
Ideal wäre also eine Tasten-Message.
Im Delphi klappt das mit Eingabefeld.Perform( WM_KEYDOWN, Zeichen, 0). Im Lazarus funktioniert es nicht
Ich habe zwischenzeitlich auch mal Lazarus unter Windows probiert. Da funktioniert es auch nicht. Es schein also nicht am Betriebssystem zu liegen.
Re: Tastendruck per Message an TEdit senden
Nimm SelText, dann ist es egal ob was markiert ist und wo der Cursor steht
Code: Alles auswählen
Edit1.SelText := Taste;
Edit1.SetFocus;
Re: Tastendruck per Message an TEdit senden
Danke für den Tipp.
Aber auf diese Weise muss ich ja das halbe Edit-Feld neu programmieren. Was ist mit den Tasten Cursor links und rechts, Backspace, Delete usw....
Das brauch ich auch noch.
Es muss doch eine Möglichkeit mit Messages geben. Schließlich bekommt das Edit-Feld die normalen Tastendrücke auch per Message. Man muss wahrscheinlich nur vorher etwas anderes Senden, oder es funktioniert ganz und gar über eine andere Message?.
Kennt sich jemand mit Lazarus intern oder Messages aus ??
Aber auf diese Weise muss ich ja das halbe Edit-Feld neu programmieren. Was ist mit den Tasten Cursor links und rechts, Backspace, Delete usw....

Es muss doch eine Möglichkeit mit Messages geben. Schließlich bekommt das Edit-Feld die normalen Tastendrücke auch per Message. Man muss wahrscheinlich nur vorher etwas anderes Senden, oder es funktioniert ganz und gar über eine andere Message?.
Kennt sich jemand mit Lazarus intern oder Messages aus ??
-
- Beiträge: 657
- Registriert: Sa 9. Jan 2010, 17:32
- OS, Lazarus, FPC: Linux 2.6.x, SVN-Lazarus, FPC 2.4.0-2
- CPU-Target: 64Bit
Re: Tastendruck per Message an TEdit senden
Es gibt unter Linux schon gewisse Hilfsprogramme, die eine klickbare Tastatur zeichnen.
Es gibt 2 Möglichkeiten, eine Tastatur vorzugaukeln:
1. der LCL (das einfachere) WM_-Events feuern
2. Mit X11 Tastendrücke feuern (würde auch mit allen anderen Programmen dann gehen)
Es gibt 2 Möglichkeiten, eine Tastatur vorzugaukeln:
1. der LCL (das einfachere) WM_-Events feuern
2. Mit X11 Tastendrücke feuern (würde auch mit allen anderen Programmen dann gehen)
-
- Lazarusforum e. V.
- Beiträge: 3178
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: Tastendruck per Message an TEdit senden
Ich habe zwar nicht wirklich viel Ahnung von Messages, aber versuch mal bitte Folgendes:
Code: Alles auswählen
uses lmessages; // oder so ähnlich
Eingabefeld.Perform(LM_KEYDOWN, Zeichen, 0);
Eingabefeld.Perform(LM_KEYUP, Zeichen, 0);
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Re: Tastendruck per Message an TEdit senden
Danke für den Tipp, socke!
Aber wie ich oben bereits geschrieben habe, bringen weder Perform noch Dispatch irgend etwas.
Ich habe auch schon den normalen Ablauf (Tastendruck über Tastatur) probiert. Wenn die Behandlung der Messages LM_KEY~ oder CN_KEY~ stattfindet, ist das Zeichen bereits im Eingabefeld angekommen. Das wird irgendwo anders bereits behandelt.
Beim Anhängen über Text:=Text + Zeichen oder SelText:=Zeichen, werden die internen Werte für SelStart, SelLength sowas von durcheinander gewürfelt, das man diese Werte nicht mehr zum feststellen der Cursorposition und des evtl. selektierten Bereiches nutzen kann. Es ist einfach schrecklich!
Aber wie ich oben bereits geschrieben habe, bringen weder Perform noch Dispatch irgend etwas.
Ich habe auch schon den normalen Ablauf (Tastendruck über Tastatur) probiert. Wenn die Behandlung der Messages LM_KEY~ oder CN_KEY~ stattfindet, ist das Zeichen bereits im Eingabefeld angekommen. Das wird irgendwo anders bereits behandelt.

Beim Anhängen über Text:=Text + Zeichen oder SelText:=Zeichen, werden die internen Werte für SelStart, SelLength sowas von durcheinander gewürfelt, das man diese Werte nicht mehr zum feststellen der Cursorposition und des evtl. selektierten Bereiches nutzen kann. Es ist einfach schrecklich!

Re: Tastendruck per Message an TEdit senden
So schlimm ist das doch gar nicht, du gibst allen Buttons als Tag den ASCI-Code der gew. Taste und als OnClick die Prozedur BtnClick.
Code: Alles auswählen
procedure TForm1.BtnClick(Sender: TObject);
var
pos: integer;
begin
pos := Edit1.SelStart;
with TButton(Sender) do begin
case Tag of
8: begin // BckSp
dec(pos);
Edit1.SelStart := pos;
Edit1.SelLength := 1;
Edit1.SelText := '';
end;
37: begin // Left
dec(pos);
end;
39: begin // Right
inc(pos);
end;
36: begin // Pos1
pos := 0;
end;
35: begin // Ende
pos := Length(Edit1.Text);
end;
else begin
Edit1.SelText := chr(Tag);
inc(pos);
end;
end;
end;
Edit1.SetFocus;
Edit1.SelLength := 0;
Edit1.SelStart := pos;
end;
Re: Tastendruck per Message an TEdit senden
Vielen Dank DiBo33!
Allerdings funktioniert es bei mir nicht sauber. Ich kann zwar mit dem Cursor hin und her. Aber wenn ich dann (Cursor weiter vorn) wieder Zeichen drücke, wird alles hinterm Cursor (obwohl nicht selektiert) überschrieben.
Auch wenn ich den Cursor mit Maus weiter vorn im Wort einsetze, wird alles hinterm Cursor beim nächsten Zeichen überschrieben.
Möglicherweise ist es ja nur bei mir so, oder?
Allerdings funktioniert es bei mir nicht sauber. Ich kann zwar mit dem Cursor hin und her. Aber wenn ich dann (Cursor weiter vorn) wieder Zeichen drücke, wird alles hinterm Cursor (obwohl nicht selektiert) überschrieben.

Möglicherweise ist es ja nur bei mir so, oder?
Re: Tastendruck per Message an TEdit senden
Gerade mal ein TestProg geschrieben, bei mir wird nix überschrieben, alle Buttons reagieren wie beim Tastendruck.
Laz:0.9.31.29983M, FPC:2.4.2, i386-linux-gtk 2, Ubuntu10.10
Laz:0.9.31.29983M, FPC:2.4.2, i386-linux-gtk 2, Ubuntu10.10
Re: Tastendruck per Message an TEdit senden
Ich habe 0.9.30 auf Ubuntu 10.10, 64bit.
Aber daran liegt es nicht. Ich habe es jetzt in Windows XP 32bit mit 0.9.28 (anderer PC) und auf Ubuntu 10.10 Netbook i386 mit 0.9.29 getestet. Das gleiche Problem! Der Selektiert immer (ohne es anzuzeigen) von Cursorposition bis Ende Text, beim nächsten Zeichen: ..alles ab Cursor überschieben...
Gestern hatte ich auch noch ein 0.9.31 auf meinem PC (Ubuntu 10.10, 64bit), habe es heute aber durch das 0.9.30 von SourceForge ersetzt. Dachte mit nem Release liegt man immer gut.
Mit dem 0.9.31er hatte ich auch schon die Spinnerei mit dem intern selektierten Zeichen.
Da war ja auch der Grund warum ich eine Message senden wollte. Damit die internen Routinen den Text modifizieren...
Aber daran liegt es nicht. Ich habe es jetzt in Windows XP 32bit mit 0.9.28 (anderer PC) und auf Ubuntu 10.10 Netbook i386 mit 0.9.29 getestet. Das gleiche Problem! Der Selektiert immer (ohne es anzuzeigen) von Cursorposition bis Ende Text, beim nächsten Zeichen: ..alles ab Cursor überschieben...
Gestern hatte ich auch noch ein 0.9.31 auf meinem PC (Ubuntu 10.10, 64bit), habe es heute aber durch das 0.9.30 von SourceForge ersetzt. Dachte mit nem Release liegt man immer gut.
Mit dem 0.9.31er hatte ich auch schon die Spinnerei mit dem intern selektierten Zeichen.
Da war ja auch der Grund warum ich eine Message senden wollte. Damit die internen Routinen den Text modifizieren...

Re: Tastendruck per Message an TEdit senden
Hast du auch am Ende der Procedure SelLength auf 0 gesetzt?
SetFocus, SelStart und SelLength müssen genau in der Reihenfolge aufgefufen werden wie ich es bei mir gemacht habe.
SetFocus, fokusiert das Eingabefeld und ruft SelAll auf.
Edit: Setze auch mal AutoSelect und AutoSize des Edits auf false.
SetFocus, SelStart und SelLength müssen genau in der Reihenfolge aufgefufen werden wie ich es bei mir gemacht habe.
SetFocus, fokusiert das Eingabefeld und ruft SelAll auf.
Edit: Setze auch mal AutoSelect und AutoSize des Edits auf false.
Re: Tastendruck per Message an TEdit senden
Ja, ich habe Deinen Code! - Nichts dran verändert!
Ich habe aber zwischenzeitlich noch etwas herausgefunden...:
Wenn:
der Cursor an der 2. Position steht, wird 1 Zeichen überschrieben (nichts selektiert dargestellt)
der Cursor an der 3. Position steht, wird 2 Zeichen überschrieben (nichts selektiert dargestellt)
der Cursor an der 4. Position steht, wird 3 Zeichen überschrieben (nichts selektiert dargestellt)
usw.
Ich teste immer "12345678". Dann bin ich bisher immer zwischen 4 und 5 gegangen und habe ein Zeichen gedrückt. Dann wurde immer "5678" durch das eingegebene Zeichen ersetzt.
Heute habe ich das mit AutoSelect und AutoSize hinzugefügt und getestet. Bin, durch Zufall, mit den Cursor an die Position zwischen 2 und 3 gegangen und es wurde nur 3 und 4 => "34" durch das Zeichen ersetzt:
Vorher "12|345678" => "z" klicken => danach "12z|5678" ( | soll symbolisiert den Cursor ).
Ich habe aber zwischenzeitlich noch etwas herausgefunden...:
Wenn:
der Cursor an der 2. Position steht, wird 1 Zeichen überschrieben (nichts selektiert dargestellt)
der Cursor an der 3. Position steht, wird 2 Zeichen überschrieben (nichts selektiert dargestellt)
der Cursor an der 4. Position steht, wird 3 Zeichen überschrieben (nichts selektiert dargestellt)
usw.
Ich teste immer "12345678". Dann bin ich bisher immer zwischen 4 und 5 gegangen und habe ein Zeichen gedrückt. Dann wurde immer "5678" durch das eingegebene Zeichen ersetzt.
Heute habe ich das mit AutoSelect und AutoSize hinzugefügt und getestet. Bin, durch Zufall, mit den Cursor an die Position zwischen 2 und 3 gegangen und es wurde nur 3 und 4 => "34" durch das Zeichen ersetzt:
Vorher "12|345678" => "z" klicken => danach "12z|5678" ( | soll symbolisiert den Cursor ).
Re: Tastendruck per Message an TEdit senden
Ich habe gerade festgestellt, dass TEdit funktioniert. Aber Comboboxen funktionieren nicht.
Ich hänge mal ein wenig Quellcode an, falls jemand probieren will...
-> einfach ein neues Projekt erstellen und dann meine Unit1 benutzen.
-> starten...
- A,B,C,D,E,F,G,H über Buttons Klicken
ComboBox zeigt "ABCDEFGH"
- Cursor an Position zwischen C und D stellen
ComboBox zeigt "ABC|DEFGH" ( | ist Cursor )
- Dann einen Button Klicken ( ich nehme mal "U" )
ComboBox zeigt bei mir "ABCU|GH" ( | ist Cursor ) 3 Zeichen werden überschrieben. Könnte das ein BUG sein?
Ich hänge mal ein wenig Quellcode an, falls jemand probieren will...
-> einfach ein neues Projekt erstellen und dann meine Unit1 benutzen.
-> starten...
- A,B,C,D,E,F,G,H über Buttons Klicken
ComboBox zeigt "ABCDEFGH"
- Cursor an Position zwischen C und D stellen
ComboBox zeigt "ABC|DEFGH" ( | ist Cursor )
- Dann einen Button Klicken ( ich nehme mal "U" )
ComboBox zeigt bei mir "ABCU|GH" ( | ist Cursor ) 3 Zeichen werden überschrieben. Könnte das ein BUG sein?
Code: Alles auswählen
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ private declarations }
Combo: TComboBox;
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
if Sender is TButton then
begin
Combo.SelText:=chr( TButton(Sender).Tag );
Combo.SelStart:=Length( Combo.Text );
Combo.SelLength:=0;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
x,y: integer;
btn: TButton;
b: Byte;
begin
Combo:=TComboBox.Create(Self);
Combo.Left:=4;
Combo.Top:=4;
Combo.Width:=200;
Self.InsertControl( Combo );
//
for y:=0 to 2 do
for x:=0 to 7 do
begin
b:=65+(y*8)+x;
btn:=TButton.Create(Self);
btn.Tag:=b;
btn.Caption:=chr(b);
btn.OnClick:=@Button1Click;
btn.Width:=24;
btn.Height:=24;
btn.Left:=(x*28)+4;
btn.Top:=(y*28)+50;
Self.InsertControl(btn);
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
ctl: TControl;
l: integer;
begin
for l:=0 to ControlCount-1 do
begin
ctl:=Controls[l];
if (ctl<>nil) then ctl.Free;
end;
end;
end.