Delphi-PRAXiS
Seite 4 von 5   « Erste     234 5      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi VirtualTreeView Editfelder, ComboBox und andere (https://www.delphipraxis.net/188689-virtualtreeview-editfelder-combobox-und-andere.html)

Aviator 10. Apr 2016 11:04

AW: VirtualTreeView Editfelder, ComboBox und andere
 
Zitat:

Zitat von jaenicke (Beitrag 1335153)
ActiveControl ist eine Eigenschaft von TForm und funktioniert deshalb auch nur im Kontext des jeweiligen Formulars.

Korrekt. Und in dem Fall müsstest du dann die Form an deine Editorklasse übergeben und könntest dann wieder darauf prüfen. Nur kannst du dann immer nur auf die Klasse der Komponente prüfen und nicht direkt auf die Komponente da du ja sonst noch Zugriff auf deine Formklasse aus der Editorklasse bräuchtest.

Jens Hartmann 10. Apr 2016 14:07

AW: VirtualTreeView Editfelder, ComboBox und andere
 
Das habe ich jetzt auch schon so hinbekommen. Ich habe jetzt Deine Editorklasse bei mir integriert und angepasst. Ich kann jetzt komplett navigieren wie gewünscht. Aber das mit dem TAB bekomme ich nicht hin.

Starte ich mein Programm ohne

Delphi-Quellcode:
procedure TfKabellisten.vstKabelInEditing(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean);
begin
  //Allowed := true;
end;
Dann geht das navigieren auch mit der TAB Taste. Anders nicht. Ich habe jetzt versucht meine Klasse zu erweitern um die TAB Taste abzufangen.

Delphi-Quellcode:
  ...
  TEditEditLink = class abstract(TBaseDataEditLink)
  private
    procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
  ...

procedure TEditEditLink.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
  Inherited;
    Message.Result := Message.Result or DLGC_WANTTAB;
end;
Aber ich bin auch ehrlich, die Funktion verstehe ich absolut nicht. Und im
Delphi-Quellcode:
OnKeyDown,
OnKeyUp
OnKeyPress
Kann man die TAB Taste nicht abfangen. Entnehme ich zumindestens der Delphi Hilfe...

Delphi-Quellcode:
  case Key of
    VK_TAB:
      begin
        //geht so nicht
      end;

jaenicke 11. Apr 2016 07:30

AW: VirtualTreeView Editfelder, ComboBox und andere
 
Zitat:

Zitat von Jens Hartmann (Beitrag 1335173)
Aber ich bin auch ehrlich, die Funktion verstehe ich absolut nicht.
[...]
Und im
Delphi-Quellcode:
OnKeyDown,
OnKeyUp
OnKeyPress
Kann man die TAB Taste nicht abfangen.

Hast du denn einmal in die Doku geschaut? Da ist das eigentlich sehr gut beschrieben:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms645425(v=vs.85).aspx
Wenn du die Tab Taste selber behandeln willst, musst du in dem Control, das die entsprechenden Messages bekommt, WM_GETDLGCODE entsprechend des bereits geposteten Codes implementieren. Damit sagst du Windows, dass es die Standardbehandlung für Tab (zum nächsten Steuerelement springen) nicht ausführen und stattdessen die Messages zur Behandlung des Tastendrucks schicken soll.

Jens Hartmann 11. Apr 2016 19:56

AW: VirtualTreeView Editfelder, ComboBox und andere
 
Zitat:

Zitat von Jaenicke
Hast du denn einmal in die Doku geschaut? Da ist das eigentlich sehr gut beschrieben:
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
Wenn du die Tab Taste selber behandeln willst, musst du in dem Control, das die entsprechenden Messages bekommt, WM_GETDLGCODE entsprechend des bereits geposteten Codes implementieren. Damit sagst du Windows, dass es die Standardbehandlung für Tab (zum nächsten Steuerelement springen) nicht ausführen und stattdessen die Messages zur Behandlung des Tastendrucks schicken soll.


Schaue ich mir jetzt gleich mal an.


Im weiteren habe ich noch ein Problem gefunden. Die Tasten VK_UP, und VK_DOWN gehen. Allerdings, denke ich, das die Funktion ja folgendes machen soll... (siehe Kommentare

Delphi-Quellcode:
    VK_UP,
    VK_DOWN,
    VK_LEFT,
    VK_RIGHT:
      begin
        CanEndEdit := Shift = []; //CanEndEdit wird gesetzt, wenn keine Shift Taste gedrückt ist
        if FEdit is TComboBox then //Hier wird geprüft, ob FEdit vom Typ ComboBox ist
          CanEndEdit := CanEndEdit and not TComboBox(FEdit).DroppedDown;
          {CanEndEdit wird gesetzt, wenn vorab CanEndEdit gesetzt und TComboBox kein
           geöffnetes DroppedDown Menü hat. Wäre das DroppedDown Menü geöffnet, soll
           der nächste Eintrag im Menü gewählt werden. Das funktioniert so nicht. Der
           nächste Eintrag wird zwar gewählt, aber dann sofort das DroppedDown Menü geschlossen}
        if CanEndEdit then
          {Ist kein DroppedDown Menü geöffnet oder kein TComboBox oder kein Shift, müsste
           dann müsste hier CanEndEdit noch true sein} 
          begin
            PostMessage(FTree.Handle, WM_KEYDOWN, Key, 0);
            {Versteh ich wieder nicht so richtig. Ich denke hier wird geprüft, welcher
             Key und diese Message wird dann verarbeitet. Soll heißen, dass Bewegen mit den
             Taste Links, Rechts, Auf und Ab. Hier funktioniert die Navigation auch tadellos,
             allerdings, wird nur beim VK_UP und VK_DOWN die Funktion "SaveChanges" aufgerufen.
             Dies liegt ja vermutlich daran, das der Node nicht verlassen wird, sondern nur das
             Column gewechselt. Aber eine Idee zur Lösung fehlt mir trotzdem aktuell}
            Key := 0;
            { Abschließen wird der Key auf 0 gesetzt damit keine weitere Bearbeitung
              entsprechend der normalen Windows Funktionen erfolgt }
          end;
      end;
Ich hoffe, dass ist so und jemand kann mir mal erklären, woran das Problem liegt und wie ich das abstellen kann.

Danke nochmal und Gruß Jens

Jens Hartmann 11. Apr 2016 20:22

AW: VirtualTreeView Editfelder, ComboBox und andere
 
Zitat:

Zitat von Jaenicke"
Hast du denn einmal in die Doku geschaut? Da ist das eigentlich sehr gut beschrieben:
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
Wenn du die Tab Taste selber behandeln willst, musst du in dem Control, das die entsprechenden Messages bekommt, WM_GETDLGCODE entsprechend des bereits geposteten Codes implementieren. Damit sagst du Windows, dass es die Standardbehandlung für Tab (zum nächsten Steuerelement springen) nicht ausführen und stattdessen die Messages zur Behandlung des Tastendrucks schicken soll.

Hier habe ich überigens auch schon eine Idee, woran es liegen könnte. Ich habe das ganze jetzt wie folgt implementiert...

Delphi-Quellcode:
//es gibt ja den Basis Editor
type
  TBaseDataEditLink = class(TInterfacedObject, IVTEditLink)
  protected
    FEdit  : TWinControl;
    FTree  : TVirtualStringTree;
    FNode  : PVirtualNode;
    FColumn : Integer;
    IsCanceling: Boolean; // Wird auf True gesetzt, wenn der Bearbeitungsvorgang abgebrochen wird

    const WM_ENDEDITING = WM_USER + 1311;
    const FAILURE_CREATECHOICECONTROL = 'Fehler beim Erstellen der Auswahlobjekte!';
  protected
    procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); virtual;
    procedure EditKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); virtual;
    procedure EditKeyPress(Sender: TObject; var Key: Char); virtual;
    procedure SetBounds(R: TRect); virtual; stdcall;
    function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; virtual; stdcall;

    procedure GetNodeText; virtual; abstract;
    procedure SaveChanges; virtual; abstract;
  public
    destructor Destroy; override;

    function BeginEdit: Boolean; virtual; stdcall;
    function CancelEdit: Boolean; virtual; stdcall;
    function EndEdit: Boolean; virtual; stdcall;
    function GetBounds: TRect; virtual; stdcall;
    procedure ProcessMessage(var Message: TMessage); virtual; stdcall;

    /// <summary>
    /// Wird benötigt, damit FEdit von TBaseEditLink nicht auf nil zeigt
    /// Muss bei jeder Klasse die von TBaseEditLink abgeleitet wird im PrepareEdit ausgeführt werden
    /// </summary>
    procedure SetEditComponent(AEditComponent: TWinControl);
  end;

//In diesem Basis Editor habe ich im OnKeyDown die Abfrage der TAB-Taste einbunden
procedure TBaseDataEditLink.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  ...
begin
  CanEndEdit := True;
  ...
  VK_TAB:
    begin
      ShowMessage('tt');
    end;
  ...
end;

//Dann gibt es ja die abgeleiteten Editoren für TEdit und TComboBox
//TComboBox
  TComboBoxEditLink = class abstract(TBaseDataEditLink)
  protected
    FEdit: TComboBox;
    procedure GetNodeText; override;
    procedure EditKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); override;
    function FillOptions(Sender: TComboBox): Boolean; virtual; abstract;
    function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; override;
  public
    destructor Destroy; override;
    function BeginEdit : Boolean; override;
  end;

TEdit
  TEditEditLink = class abstract(TBaseDataEditLink)
  protected
    FEdit: TEdit;
    procedure GetNodeText; override; abstract;
    function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; override;
  public
    destructor Destroy; override;
    function BeginEdit : Boolean; override;
  end;
{
Von diesen Editoren habe ich weitere Editoren abgeleitet, in denen ich dann noch ein paar Details eingebunden habe. z.B. verschiedene Properties etc.
}

{
Hier nehme ich mal als Beispiel eine von
}
type
  TKabelbezeichnungEditLink = class(TEditEditLink)
  private
    //Hier die implementation der message WM_GETDLGCODE
    procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
  protected
    procedure GetNodeText; override;
    procedure SaveChanges; override;
  end;

{
und
}

procedure TKabelbezeichnungEditLink.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
  Inherited;
    Message.Result := Message.Result or DLGC_WANTTAB;
end;
Jetzt gehe ich aktuell davon aus, dass die TAB Taste nicht erkannt wird, weil entweder die Implementation an der falschen Stelle durchgeführt wurde, oder der "Parent" nicht richtig ist...

Ich habe hierzu dieses gefunden...

http://www.delphipraxis.net/72821-ab...gar-nicht.html

Aviator 11. Apr 2016 20:32

AW: VirtualTreeView Editfelder, ComboBox und andere
 
Zitat:

Zitat von Jens Hartmann (Beitrag 1335335)
Jetzt gehe ich aktuell davon aus, dass die TAB Taste nicht erkannt wird, weil [...] der "Parent" nicht richtig ist...

Hast du denn den Parent in der Editorklasse auch gesetzt? Ich hatte den in meiner Basisklasse damals aus irgendeinem Grund weggelassen und in der Implementierung des eigentlichen Editors immer erst gesetzt. Aber du könntest das jetzt zum Testen mal machen und in der
Delphi-Quellcode:
TBaseDataEditLink.PrepareEdit()
Funktion den Parent des FEdit mal auf den Tree setzen. Dann nochmal probieren. Wenn es dann nicht funktioniert, dann müsstest du mal schauen, ob die Message evtl. im Tree schon abgefangen und eliminiert wird, sobald sich der Tree im Editmodus befindet. Kann jetzt leider gerade nicht nachschauen bzw. nachprüfen. Aber das wäre jetzt mal ein Ansatz den du austesten könntest.

[EDIT]Sorry nicht in der
Delphi-Quellcode:
TBaseDataEditLink.PrepareEdit()
sondern in einer der nachfolgenden Klassen, in der die Instanz der Komponente erzeugt wird.[/EDIT]

Jens Hartmann 11. Apr 2016 21:08

AW: VirtualTreeView Editfelder, ComboBox und andere
 
Also ich mache das eigendlich in der Instanz in der ich die Komponente erzeuge...

Delphi-Quellcode:
function TKabelNrEditLink.PrepareEdit(Tree: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex): Boolean;
begin
  inherited;
  Self.FEdit.Style := csDropDownList;
  Self.FEdit.OnChange := Change;
  Self.FEdit.Parent := Self.FTree;
end;

Jens Hartmann 12. Apr 2016 05:25

AW: VirtualTreeView Editfelder, ComboBox und andere
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ergänzend muss ich vieleicht mal noch erklären, dass meine Form mit dem integrierten VST als Form auf einem Panel auf meiner MainForm liegt.

Ich habe meine Programmoberfläche wie folgt gestaltet:

1. MainForm
2. Linkes Seite MainForm ein VST als eine Art Datenexplorer
3. Rechte Seite MainForm ein Panel als Datenpanel auf dem ich je nach Auswahl im vst entsprechende Daten anzeige.
Auf dieses Panel werden dann entweder Frames oder in diesem Fall eine Form gelegt und dieser Form ist dann das Panel als Parent zugewiesen.

siehe Bild im Anhang..

jaenicke 12. Apr 2016 06:27

AW: VirtualTreeView Editfelder, ComboBox und andere
 
Es ist dann vielleicht einfacher, wenn du mit dem Window Detective anschaust welche Messages eigentlich wo landen...
Vielleicht muss WM_GETDLGCODE auch in deinem obersten Formular beantwortet werden.

Kann ich das aktuelle Problem in dem Beispiel aus #14 nachvollziehen? Dann schaue ich mit das einmal heute Abend an.

Jens Hartmann 12. Apr 2016 08:06

AW: VirtualTreeView Editfelder, ComboBox und andere
 
Ich denke schon, aber Du meinst glaube ich #34


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:42 Uhr.
Seite 4 von 5   « Erste     234 5      

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