Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi OnKeyDown/Press Ereignis bei dynamisch erzeugtem Edit (https://www.delphipraxis.net/1986-onkeydown-press-ereignis-bei-dynamisch-erzeugtem-edit.html)

Exciter 2. Jan 2003 02:17


OnKeyDown/Press Ereignis bei dynamisch erzeugtem Edit
 
Moin zusammen !

Ich möchte bei einem dynamisch erzeugtem TEdit auf ein OnKeyDown/Press Ereignis reagieren. Ich hab' mir diesen Thread durchgelesen http://www.delphipraxis.net/viewtopic.php?t=1934. Mir ist aber nicht klar wie ich die Methode deklarieren muss. Ein kurzes Beispiel wäre super !

Christian Seehase 2. Jan 2003 03:37

Moin Exicter,

prima, dass Du schon mal angefangen hast Dich schlau zu machen.

Diese Methode(n) sollten dort deklariert werden, wo auch die anderen Methoden des Formulares stehen.
Oben in der Unit hast Du ja so etwas wie:

Delphi-Quellcode:
TForm1 = class(TForm)
  // Hier stehen jetzt alle möglichen Komponenten, die Du auf dem Formular hast
  // und auch die Ereignisprozeduren
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
Dort bringst Du auch Deine eigenen Prozeduren unter:

Delphi-Quellcode:
TForm1 = class(TForm)
  //...
  procedure MeinKeyPress(Sender: TObject; var Key: Char);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
jetzt fehlt nur noch im implementation Abschnitt die eigentliche Prozedur

Delphi-Quellcode:
implementation

procedure TForm1.MeinKeyPress(Sender: TObject; var Key: Char);
begin
  // Was auch immer passieren soll
end;
und zugewiesen wird's dann meist an der Stelle, an der man die Komponente dynamisch erzeugt.
Hier mal als Beispiel im FormCreate.

Delphi-Quellcode:
procedure TfrmMAIN.FormCreate(Sender: TObject);
begin
  with TEdit.Create(self) do
  begin
    // Was auch immer sonst noch für das TEdit angegeben werden soll
    OnKeyDown := MeinKeyDown;
  end;
end;
Du kannst natürlich auch jede beliebige andere schon existierende Methode so zuweisen, solange die Parameterliste mit der erforderlichen übereinstimmt.

CalganX 2. Jan 2003 10:40

Mal eine Frage:
  1. Bei der einfachen VCL-Programmierung wird ButtonXClick(Sender: TObject) genommen
  2. Bei Komponenten muss man aber TMyButton.Click (ohne irgendwas) nehmen
Und bei nonVCL ist es glaube ich auch noch mal anders.
Kann mir das mal bitte erklären? Ich dachte Delphi wäre einigermaßen logisch...

Chris

Christian Seehase 2. Jan 2003 10:49

Moin Chris,

Deine Punkte 1 und 2 sind aber identisch.

In beiden Fällen handelt es sich um eine OnClick Routine.
Im ersten Falle als Methode eines Formulares (die dann einem Button zugewiesen wird), im zweiten die eines Button. (bei der ersten gehört ja wohl auch noch ein TForm1. o.ä. davor ;-))

Exciter 2. Jan 2003 15:20

Moin Moin !

Gesagt getan. Funzt aber nicht ...
(Das ganze soll ein Chat mit Private Messages werden und für jeden Chat/jede PM soll ein eigener TabSheet mit nem Edit/ListView erstellt werden)

Code:
  ...
  NewTab := TTabSheet.Create(Form1.PageControl3);
  NewTab.PageControl := Form1.PageControl3;
  NewEdit := TEdit.Create(NewTab);
  NewListView := TListView.Create(NewTab);
  TWinControl(NewEdit).parent := NewTab;
  TWinControl(NewListView).parent := NewTab;
  OnKeyDown := MeinKeyDown;
end;
Das funzt auch alles soweit. Nur passiert nix, wenn ich im Programm auf 'Return' drück'.
Code:
procedure TForm1.MeinKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);

begin
If (Key= (VK_RETURN)) And Not (NewEdit.Text='') Then
   begin ....
und hier das nächste Problem: Wie kann ich jetzt etwas mit dem eben erstelltem ListView anstellen ??

Thx für die Hilfe
Patrick

Helld_River 2. Jan 2003 15:30

blöde Frage, aber hast Du bei deinem Formular KeyPreview auf TRUE gesetzt ? :lol:
Was ich bei deinem Code nicht verstehe, ist die Zuweisung

OnKeyDown:=MeinKeyDown;

Zu welcher Komponente gehört dieses OnKeyDown ?

CalganX 2. Jan 2003 15:32

Vermutlich zu TForm1
Du schreibst ja auch Canvas.Draw und nicht Form1.Canvas.Draw (denk ich doch mal)...

Chris

Helld_River 2. Jan 2003 15:38

Könnte hinkommen !
Wenn ich das Problem aber richtig verstanden habe, dann möchte Exciter doch auf ein Tastaturereignis vom dynamisch erzeugten TEdit reagieren, somit müsste doch MeinKeyDown an NewEdit zugewiesen werden, oder ?

CalganX 2. Jan 2003 15:40

Jepp, dann müsste es wirklich NewEdit.OnKeyDown heißen. Er kann es so lassen, wenn Form.KeyPreview = true ist...

Chris

Exciter 2. Jan 2003 15:56

Ääääh hmmm ...

Also:
- KeyPreview ist true.
- OnKeyDown:=MeinKeyDown; sollte für's dynamisch erstellte TEdit sein.
Zitat:

Könnte hinkommen !
Wenn ich das Problem aber richtig verstanden habe, dann möchte Exciter doch auf ein Tastaturereignis vom dynamisch erzeugten TEdit reagieren, somit müsste doch MeinKeyDown an NewEdit zugewiesen werden, oder ?
Genau das hatte ich eigentlich vor :? !

Patrick

Helld_River 2. Jan 2003 16:02

Dann musst Du auch

NewEdit.OnKeyDown:=MeinKeyDown;

schreiben !!! :dancer2:

Exciter 2. Jan 2003 16:39

OK

Aber dann krieg ich oben bei der Deklaration die Meldung:
'Ungenügende Forward- oder External-Deklaration: TForm1.MyKeyDown'

Helld_River 2. Jan 2003 17:26

Sorry, aber das müsste ich mir genauer anschauen, habe nur im Moment nicht die zeit dazu. Stell doch mal einfach etwas mehr Quellcode rein, am besten die ganze Unit (wenn nicht zu groß) und ich versuche es mir heute NAcht anzuschauen.

Gruß, Helld

Exciter 2. Jan 2003 18:40

OK, alles wär vielleicht ein wenig lang ...
ich poste mal die Teile die ich für diese Prozedur erstellt/geändert hab:
Code:
interface
...
uses
...
type
...
procedure MeinKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);

implementation
...
procedure TForm1.Server1PrivMsg(Sender: TComponent; Nick, Msg: String);
var NewTab    : TTabSheet;
     NewChat   : TListView;
     NewEdit   : TEdit;
     Item      : TListItem;
begin
  NewTab := TTabSheet.Create(Form1.PageControl3);
  NewTab.Visible := True;
  NewTab.Caption := Nick;
  NewTab.PageControl := Form1.PageControl3;
  Form1.PageControl3.ActivePage := NewTab;
  NewEdit := TEdit.Create(NewTab);
  NewChat := TListView.Create(NewTab);
  TWinControl(NewEdit).parent := NewTab;
  TWinControl(NewChat).parent := NewTab;
  NewEdit.Align := AlBottom;
  NewChat.Align := alClient;
  NewChat.ViewStyle := vsReport;
  NewChat.ShowColumnHeaders := True;
  NewChat.Columns.Add;
  NewChat.Column[0].Caption := 'Time';
  NewChat.Columns.Add;
  NewChat.Column[1].Caption := 'User';
  NewChat.Column[1].Width := 100;
  NewChat.Columns.Add;
  NewChat.Column[2].Caption := 'Message';
  NewChat.Column[2].AutoSize := True;
  Item:=NewChat.Items.Add;
  Item.Caption := TimeToStr(Time);
  Item.SubItems.Add('<'+ Nick +'>');
  Item.SubItems.Add(Msg);
 NewEdit.OnKeyDown:=MeinKeyDown;
end;

procedure MeinKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var NewEdit : ???; //soll sich auf das oben erstellte TEdit beziehen
    NewChat : ???; //soll sich auf das oben erstellte TListView beziehen
    Nick   : String;
    Item   : TListItem;

begin
  If (Key = (VK_RETURN)) And Not (NewEdit.Text='') Then
  begin
    Nick := ??? wie krieg ich den String 'Nick' aus 'Server1PrivateMsg' jetzt hier hin ?
    Server1.SendPrivMsg(Nick, Trim(NewEdit.Text));
    Item:=NewChat.Items.Add;
    Item.Caption := TimeToStr(Time);
    Item.SubItems.Add('Ich ->');
    Item.SubItems.Add(NewEdit.Text);}
  end;
end;
Ich mach' das mit der dynamischen Erzeugung zum ersten Mal. Deswegen hab ich auch keine Ahnung wie ich die Variablen (NewEdit,NewChat,Nick) richtig deklariere, damit ich die in der OnKeyDown Prozedur verwenden kann (Server1.SendPrivMsg muss ja wissen wer 'Nick' ist) :?:

Exciter 3. Jan 2003 07:54

Moin !

Arrrgh :evil: Ich hab das TForm1 vor OnKeyDown vergessen.


Code:
procedure TForm1.MeinKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
Das OnKeyDown Ereignis funzt jetzt :D
Nun hab ich aber immer noch das Problem, dass ich nicht weiss wie ich mit meinem dyn. erstelltem TListView und TEdit in der TForm1.MeinKeyDown - Prozedur weiter arbeiten kann (Es kann ja auch vorkommen, dass mehrere erstellt werden).

phlux 3. Jan 2003 08:09

Ich glaube FindCompenent hilft dir dort, es gibt da aber auch noch die möglichkeit über nen array deine dyn. komps anzulegen. dann kannst du über nen array auf die kompos zugreifen.

Exciter 3. Jan 2003 15:55

Ok,

sagen wir, ich krieg 4 Nachrichten von unterschiedlichen Usern. Dann wird pro Nachricht, auf dem PageControl ein Tabsheet erzeugt und darauf jeweils ein TEdit und ein TListView als Array[0..3] of TEdit/TListView.
Nun kann ich in der nächsten Prozedur über den Index[0] bis [3] ja darauf zugreifen. Aber woher weiss ich, welcher Index zu dem jeweiligen User gehört ???
Kann ich da nicht etwas mit dem Username string anfangen, den ich bei jeder Nachricht zur Verfügung hab ?
Ich hab versucht, den dyn. erzeugten Komponenten die Namen der untersch. User zu geben. Dann hab' ich aber immer die Namen in den TEdits stehen und Exceptions bei den TListViews :evil:

Kann mir mal bitte jemand erklären wie man's richtig macht ?!

Helld_River 3. Jan 2003 18:22

Hi !
Versuch doch mal etwas in folgender Richtung:

Code:
  TKomp : record
           Name : string;
           Kedit : TEdit;
           KListView : TListView;
         end;

var LaengeArray : integer;
    Komp : TKomp;
    xyz : array of Komp; //dynamisches Array
   

//Array initialisieren
  LaengeArray:=0;
  SetLength(xyz,LaengeArray);

//über SetLength kannst Du das Array auch erweitern, einfach LaengeArray hochsetzten und dann wieder SetLength aufrufen
Schau sonst einfach mal in der DelphiHilfe unter "dynamische Arrays" nach.

Gruß, Helld

Exciter 3. Jan 2003 18:40

Hi Helld

Also ich ich hab' kein Problem damit das Array zu erstellen, sondern in der nächsten Prozedur (mein OnKeyDown vom dyn. TEdit) herauszufinden, von welchem TEdit das OnKeyDown-Ereignis ausging !

Christian Seehase 3. Jan 2003 18:56

Moin Exciter,

dafür kannst Du den Parameter Sender verwenden.
Wenn Du vorab Deinen Edits in der Eigenschaft Tag noch eine genaue ID verpasst hast gehts sogar noch einfacher, ansonsten wirst Du wohl den Namen nehmen müssen:

z.B.

Delphi-Quellcode:
if Sender ist TEdit then
begin
  if TEdit(Sender).Name = 'Edit1' then
  begin
    // Irgendetwas tun
    exit;
  end;
  if TEdit(Sender).Name = 'Edit2' then
  begin
    // Irgendetwas tun
    exit;
  end;
end;
Wenn Du die Eigenschaft Tag verwendest, kannst Du das sogar ganz einfach über eine case Anweisung handeln.

Exciter 3. Jan 2003 21:46

Verdammt, ich krieg's nicht hin !
Zur Entwurfszeit kein Problem ...
Code:
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
Var User : String;

begin
If (Key= (VK_RETURN)) And Not (Edit1.Text='') Then
   begin
    User := 'IrgendEinUser'
    Server1.SendPrivateMsg(User, Trim(Edit1.Text));
    Edit1.Text:='';
end;
Aber wie erstell ich sowas dynamisch ??? :?

Christian Seehase 3. Jan 2003 23:34

Moin Exiter,

wenn Du so fragst: Gar nicht. ;-)

Du musst die Routine als solche schon im Programm haben, und weist sie dann zur Laufzeit zu.

Vorher muss die Routine natürlich in der Lage sein unabhängig vom verwendeten Edit zu sein:

Delphi-Quellcode:
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
Var User : String;

begin
  // Nur zur Sicherheit
  if sender ist TEdit then
  begin
    If (Key= (VK_RETURN)) And Not (TEdit(Sender).Text='') Then
    begin
      User := 'IrgendEinUser'
      Server1.SendPrivateMsg(User, Trim(TEdit(sender).Text));
      TEdit(sender).Text:='';
    end;
  end;
end;

Exciter 4. Jan 2003 00:32

Moin Christian !

Jau, das hat hingehaun. Danke !
Aber ich werd das mit dem Chat wohl erstmal in Ruhe lassen.
Ich hab nämlich jetzt noch versucht meinen TEdit(Sender).Text in das auch dyn. erstellte TListView zu schreiben. Aber da hagelt's Exceptions ... GRRR
War wohl doch ein wenig zu heftig für'n Anfang ...


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:05 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