Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi TreeView-->OnEditing/OnEdited die Enter-Taste abfangen (https://www.delphipraxis.net/129084-treeview-onediting-onedited-die-enter-taste-abfangen.html)

RWarnecke 12. Feb 2009 13:00


TreeView-->OnEditing/OnEdited die Enter-Taste abfangen
 
Hallo zusammen,

ich habe da mal wieder ein Problem. Ich erstelle mit dem folgenden Code eine neue Node in einem TreeView und setze diese in den Editiermodus :
Delphi-Quellcode:
  tmpNode := TV_Category.Items.AddChild(TV_Category.Selected, 'Neue Kategorie');
  tmpNode.ImageIndex := 0;
  tmpNode.SelectedIndex := 0;
  TV_Category.Selected.Expand(False);
  tmpNode.Selected := True;
  TV_Category.Selected.EditText;
Funktioniert auch soweit ganz gut. Nun zu meinem Problem, wenn ich jetzt einfach die Enter-Taste drücke, wird die neue Node mit dem Namen "Neue Kategorie" eingefügt und das Ereignis OnEdited wird nicht ausgeführt. Das heißt, dass die Node nicht in meiner Datenbank abgeseichert wird.

Wie kann ich das ganze jetzt abfangen ? Denn ich möchte, dass der User einen neuen Namen für die Kategorie vergibt und nicht eher aus dem Editiermodus des TreeViews rauskommt bis mindestens ein Name vergeben ist. Über die OnKeyxxx-Ereignisse habe ich es auch schon probiert. Diese werden aber im Editiermodus nicht angesprochen.

HHennig 12. Feb 2009 20:01

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Hallo evtl. hilft dir meine damalige Antwort weiter. Nicht so fein formatiert (wie mir zu recht vorgeworfen wurde... :wink: ), aber funktioniert.

HHennig 12. Feb 2009 20:04

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Ehm, habe vergessen auf das hinzuweisen, was ich eigentlich sagen wollte: Versuche mal die Enter-Taste schon global auf Applikationsebene abzufangen, wie im Link des letzten Beitrags beschrieben.

RWarnecke 12. Feb 2009 20:36

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Zitat:

Zitat von HHennig
Hallo evtl. hilft dir meine damalige Antwort weiter. Nicht so fein formatiert (wie mir zu recht vorgeworfen wurde... :wink: ), aber funktioniert.

Zitat:

Zitat von HHennig
Ehm, habe vergessen auf das hinzuweisen, was ich eigentlich sagen wollte: Versuche mal die Enter-Taste schon global auf Applikationsebene abzufangen, wie im Link des letzten Beitrags beschrieben.

Dann müsste ich ja meine anderen KeyDown, KeyPress etc. alle umbauen. Das ist nicht was ich will, da ich in mehreren Komponenten auf Tasten reagiere.

HHennig 12. Feb 2009 22:30

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Zitat:

Dann müsste ich ja meine anderen KeyDown, KeyPress etc. alle umbauen
Nicht unbedingt, wenn in der globalen OnAppMsg gerade nicht die richtige Komponente den Tastaturfokus hat, kannst du das ja abfragen und mit Handled := False die Tastaturereignisse ganz normal an die nachfolgenden KeyDown, KeyPress, etc. weiterreichen.

RWarnecke 12. Feb 2009 22:44

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Ok, dabei stellt sich mir jetzt aber die Frage, welche wird als erstes Ausgeführt ? Das OnKeyDown, OnKeyPress Ereignis von der Komponente oder das globale ?

HHennig 12. Feb 2009 23:02

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Ich bin fast sicher, dass der globale Event zuerst kommt, sonst würde ja der Parameter Handled keinen Sinn machen.

Aber, am besten testen: je einen Breakpoint in das globale und in ein sonstiges Key-Event setzen und starten. Wer zuerst kommt mahlt auch zu erst... :wink:

RWarnecke 12. Feb 2009 23:13

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Ok, ich werde es mal testen. Aber ganz zufrieden bin ich damit nicht. Da das eine Menge Aufwand bedeutet.

HHennig 12. Feb 2009 23:21

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Sicher kann das ggf. aufwendig werden. Hast du aber überhaupt eine andere Wahl, wenn doch, wie du anfangs sagtest, die 'normalen' Events gar nicht greifen?

Ich wüsste jetzt gerade keine Alternative.

RWarnecke 12. Feb 2009 23:30

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Zitat:

Zitat von HHennig
Sicher kann das ggf. aufwendig werden. Hast du aber überhaupt eine andere Wahl, wenn doch, wie du anfangs sagtest, die 'normalen' Events gar nicht greifen?

Das haben zumindest meine bisherigen Tests ergeben. Ich habe zu dem Editiermodus des TreeViews aber auch noch nichts weiteres gefunden. Mir wäre es am liebsten, ich kann das über das normale KeyDown vom TreeView abhandeln. So brauche ich die anderen Komponenten nicht anzufassen. Das blöde ist halt, wenn ich per Sourcecode einen Text für die Node vorgebe und dann nur Enter gedrückt wird, wird das OnEdited-Ereignis nicht ausgeführt. Gebe ich zum Beispiel nur eine 1 hinter dem vorgegebenen Namen ein, dann funktioniert es.

Eine andere Möglichkeit wäre noch eine Dialogbox zu machen, wo ich dann das entsprechende Edit-Feld auswerten kann. Was ich aber aus Designersicht wiederum nicht elegant gelöst finde.

HHennig 12. Feb 2009 23:45

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Werde später, wenn ich wieder im Büro bin, mal in das Projekt reinschauen und dir ggf. noch mehr Code senden. Die Lösung sollte doch eigentlich deine übrigen Komponenten und deren Key-Events gar nicht so sehr betreffen.

Es hilft halt nichts, du musst dem beschriebenen Verhalten der VCL zuvor kommen und die Tasten vorher so auswerten, wie du es benötigst.

Lass uns erst mal drüber schlafen... :)

RWarnecke 12. Feb 2009 23:56

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Zitat:

Zitat von HHennig
Werde später, wenn ich wieder im Büro bin, mal in das Projekt reinschauen und dir ggf. noch mehr Code senden. Die Lösung sollte doch eigentlich deine übrigen Komponenten und deren Key-Events gar nicht so sehr betreffen.

Es hilft halt nichts, du musst dem beschriebenen Verhalten der VCL zuvor kommen und die Tasten vorher so auswerten, wie du es benötigst.

Lass uns erst mal drüber schlafen... :)

Da hast Du recht, lass uns mal drüber schlafen. Die Tests aus meinem Beitrag #8 werde ich auch erst machen, wenn ich geschlafen habe. So richtig weiter komme ich nämlich zur Zeit auch nicht.

RWarnecke 13. Feb 2009 07:54

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Hallo Hartmut,

ich habe jetzt mal ein bischen mit dem Code aus Deinem verlinkten Beitrag getestet und folgendes ist dabei rausgekommen :
Delphi-Quellcode:
procedure TForm16.OnAppMsg(var Msg: TMsg; var Handled: Boolean);
begin
  Handled := False;
  if Msg.message = WM_KEYDOWN then
  begin
    if (Msg.wParam = VK_RETURN) and (tv1.IsEditing) then
    begin
      if (tv1.Selected.Text = 'Neue Kategorie') then
      begin
        ShowMessage('Bitte einen neuen Namen eingeben !!' + #13#10 + tv1.Selected.Text);
        tv1.Selected.EditText;
      end;
      Handled := True;
    end;
  end;
end;
Das einzigste Problem, was im Moment noch besteht, wie komme ich an den aktuellen Text, der im Editiermodus im TreeView eingegeben ist :?: Denn so wie ich es jetzt gemacht habe, hat er in der ShowMessage immer noch "Neue Kategorie".

HHennig 13. Feb 2009 10:36

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Hallo Rolf,

habe erst jetzt mal eine ruhige Minute gefunden, um nach deinem Problem zu sehen.

ich würde deine Code ein wenig umbauen, etwa so:

Delphi-Quellcode:
type
  TForm16 = class...
    ...
   public // oder wo es passender ist
    EditedTxt : string;
   ...
  end;

procedure TForm16.OnAppMsg(var Msg: TMsg; var Handled: Boolean);
begin
  Handled := False;
  if Msg.message = WM_KEYDOWN then
  begin
    if (tv1.IsEditing) then
    begin
      if (Msg.wParam in [VK_A..VK_Z]) then // -> nimm hier alle deine gültigen Zeichen
        EditedTxt := EditedTxt + chr(Msg.wParam)
      else
        if (Msg.wParam = VK_RETURN) then
        begin
          tv1.Selected.EditText := EditedTxt;
          EditedTxt := '';
        end;
      Handled := True;
    end;
  end;
end;
So ungefähr, ich hab's nicht getestet, sondern nur mal schnell runtergetippt.
Denn auch der eingegebene Text geht ja Zeichen für Zeichen durch dieses globale Key-Event.
Versuche einfach mal auf dieser Basis weiterzuforschen.

RWarnecke 13. Feb 2009 10:45

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Hallo Hartmut,

Dein Sourcecode wird nicht funktionieren. Denn die Zeile 21 wird nicht funktionieren, da EditText eine Funktion ist und mir nur Boolean zurückgibt.

HHennig 13. Feb 2009 11:38

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Hallo Rolf,

du hast recht, ich meinte eigentlich das Property 'Text' des neuen Treenode; das wolltest du ja editieren und dahin schreibst du nun den per OnAppMsg 'gesamelten' Text.

RWarnecke 13. Feb 2009 12:31

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Dieser Code funktioniert insoweit, dass das Eingebene erst nach dem betätigen der Enter-Taste sichtbar wird.
Delphi-Quellcode:
procedure TForm16.OnAppMsg(var Msg: TMsg; var Handled: Boolean);
begin
  Handled := False;
  if Msg.message = WM_KEYDOWN then
  begin
    if tv1.IsEditing then
    begin
      if (Msg.wParam > 64) and (Msg.wParam < 91) then // oder irgendeine andere Taste deiner Wahl
        EditedTxt := EditedTxt + chr(Msg.wParam)
      else
        if (Msg.wParam = VK_RETURN) then
        begin
          tv1.Selected.Text := EditedTxt;
          EditedTxt := '';
        end;
      Handled := True;
    end;
  end;
end;
Es muss ja irgendeine Message ausgelöst werden, wenn ich eine Node in den Editiermodus setze mit
Delphi-Quellcode:
tv1.selected.edittext
. Genau diese Message möchte ich trotzdem senden, auch wenn ich nur die Enter-Taste betätigt habe und keine andere Taste gedrückt habe. Dabei soll dann der Text überprüft werden und dementsprechend reagiert werden.

HHennig 13. Feb 2009 20:17

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Genau dafür ist der Parameter Handled zuständig; wenn du eine Message komplett selbst behandeln willst, setze Handled := True, dann wird die Message von Windows nicht weiter behandelt. Sonst setze Handled := False nachdem du mit deiner Vorbehandlung fertig bist, damit wird die Message einfach an die Standardbehandlung weitergereicht.

Welche Messages aber im Einzelnen von Treeview wann generiert werden, weiss ich nicht; da wirst du am Besten mal so was wie WinSight o. ä. starten und nachsehen, welche Message du abfangen/modifizieren musst.

RWarnecke 14. Feb 2009 15:28

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Ich habe nochmals rum und num probiert, komme aber auf keinen grünen Zweig. So sieht jetzt meine Procedure aus :
Delphi-Quellcode:
procedure TForm16.OnAppMsg(var Msg: TMsg; var Handled: Boolean);
begin
  Handled := False;
  if Msg.message = WM_KEYDOWN then
  begin
    if TV_1.IsEditing then
    begin
      if (Msg.wParam > 47) and (Msg.wParam < 91) then // oder irgendeine andere Taste deiner Wahl
      begin
        Handled := True;
        EditedTxt := EditedTxt + chr(Msg.wParam);
      end
      else
      begin
        Handled := False;
        if (Msg.wParam = VK_RETURN) then
          if EditedTxt <> TV_1.Selected.Text then
          begin
            tmpNode.Text := EditedTxt;
            EditedTxt := '';
          end
          else
            tmpNode.EditText;
      end;
      Handled := False;
    end;
  end;
end;
Wenn ich jetzt nichts ändere nach dem Erstellen und dann auf Enter drücke, legt er mir eine leere Node an. Wie kann ich das Programm dazu bringen, dass die Node im Editiermodus bleibt, trotz das ich die Enter-Taste betätigt habe ?

RWarnecke 18. Mär 2009 21:02

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
Hallo zusammen,

ich habe es mittlerweile hinbekommen. Mein Sourcecode sieht jetzt so aus :
Delphi-Quellcode:
procedure TForm16.OnAppMsg(var Msg: TMsg; var Handled: Boolean);
begin
  Handled := False;
  if Msg.message = WM_KEYDOWN then
  begin
    if (TV_1.IsEditing) and (TV_1.Tag = 0) then
    begin
      case Msg.wParam of
        VK_BACK, VK_SHIFT, VK_INSERT, VK_DELETE, 47..91, 96..109 :
        begin
          Handled := True;
          EditedTxt := EditedTxt + chr(Msg.wParam);
          NodeEdit := True;
        end;
      else
        if (Msg.wParam = VK_RETURN) and (Msg.lParam <> TVN_ITEMCHANGED) and (not NodeEdit) then
        begin
          ShowMessage('Bitte vergeben Sie einen Namen');
          NodeEdit := False;
          tmpNode.EditText;
        end;
      end;
      Handled := False;
    end;
  end;
end;
Jetzt habe ich dabei das Problem, dass ich mir mit dieser Funktion die Shortcuts für Copy&Paste abgeklemmt habe. Wie kann ich diese Shortcuts wieder aktivieren ?

RWarnecke 21. Mär 2009 08:16

Re: TreeView-->OnEditing/OnEdited die Enter-Taste abfange
 
*push* Hat denn keiner eine Idee, Hinweis oder Hinweispunkt ? *push*


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