Einzelnen Beitrag anzeigen

Benutzerbild von Jens Hartmann
Jens Hartmann

Registriert seit: 11. Jan 2009
Ort: Wilnsdorf
1.439 Beiträge
 
Delphi XE2 Professional
 
#35

AW: VirtualTreeView Editfelder, ComboBox und andere

  Alt 11. Apr 2016, 20:22
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
Jens Hartmann
Das Leben selber ist zu kurz, also nutze jeden Tag wie er kommt.
  Mit Zitat antworten Zitat