AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi VST IVTEditLink AccessViolation bei WindowProc
Thema durchsuchen
Ansicht
Themen-Optionen

VST IVTEditLink AccessViolation bei WindowProc

Ein Thema von Hobbycoder · begonnen am 1. Feb 2021 · letzter Beitrag vom 2. Feb 2021
Antwort Antwort
Hobbycoder

Registriert seit: 22. Feb 2017
955 Beiträge
 
#1

VST IVTEditLink AccessViolation bei WindowProc

  Alt 1. Feb 2021, 19:00
Hi,

ich benötige in einer VST einen Editor in zwei Spalten. Ich habe mir die Klasse mit dem implementiern Interface IVEditLink gemäß den zahlreichen Beispielen erstellt. Jedoch als Edit-Komponente habe ich TJvValidateEdit genommen, weil mir da das Editieren von z.B: Currency besser gefällt.
Soweit scheint das auch zu funktioniere, jedoch bekomme ich in der Methode "TEditValueEditLink.ProcessMessage" immer eine AV in der Zeile FEdit.WindowProc(Message); , wobei ich leider den Wert von Message im Debugger nicht auslesen kann.

Ich habe schon JvValidateEdit gegen ein normales TEdit getauscht, aber der Fehler bleibt der gleiche. Mit dem integrierten Editor des VST gibt es keine Probleme.

Das FEdit existiert. Wenn ich das WindowProc auskommentiere, läuft es, jedoch werden ja die Fensterbotschaften nicht mehr an das Control weitergeleitet (Es wird auch an der falschen STelle gezeichnet).

Hier mal meine Unit:
Delphi-Quellcode:
unit TNSLagerWareneingang;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VirtualTrees, Vcl.ExtCtrls, uArtikel, JvValidateEdit, JvEdit;

type
  IVTEditLink = interface
    ['{2BE3EAFA-5ACB-45B4-9D9A-B58BCC496E17}']
    function BeginEdit: Boolean; stdcall; // Called when editing actually starts.
    function CancelEdit: Boolean; stdcall; // Called when editing has been cancelled by the tree.
    function EndEdit: Boolean; stdcall; // Called when editing has been finished by the tree. Returns True if successful, False if edit mode is still active.
    function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall;
                                                           // Called after creation to allow a setup.
    function GetBounds: TRect; stdcall; // Called to get the current size of the edit window
                                                           // (only important if the edit resizes itself).
    procedure ProcessMessage(var Message: TMessage); stdcall;
                                                           // Used to forward messages to the edit window(s)-
    procedure SetBounds(R: TRect); stdcall; // Called to place the editor.
  end;

  TEditValueEditLink = class (TInterfacedObject, IVTEditLink)
  private
    FEdit: TJvValidateEdit;
    FTree : TVirtualStringTree;
    FNode : PVirtualNode;
    FColumn : Integer;
    procedure GetNodeText;
  public
    destructor Destroy; override;
    function BeginEdit: Boolean; virtual; stdcall;
    function CancelEdit: Boolean; virtual; stdcall;
    function EndEdit: Boolean; virtual; stdcall;
    function GetBounds: TRect; virtual; stdcall;
    function PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall;
    procedure ProcessMessage(var Message: TMessage); virtual; stdcall;
    procedure SetBounds(R: TRect); stdcall;
  end;

  TfrmTNSLagerWareneingang = class(TForm)
    pnlBottom: TPanel;
    vstArtikel: TVirtualStringTree;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure vstArtikelInitNode(Sender: TBaseVirtualTree; ParentNode,
      Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
    procedure vstArtikelGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
      Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
    procedure FormShow(Sender: TObject);
    procedure vstArtikelCreateEditor(Sender: TBaseVirtualTree;
      Node: PVirtualNode; Column: TColumnIndex; out EditLink: IVTEditLink);
    procedure vstArtikelEditing(Sender: TBaseVirtualTree; Node: PVirtualNode;
      Column: TColumnIndex; var Allowed: Boolean);
    procedure vstArtikelFocusChanged(Sender: TBaseVirtualTree;
      Node: PVirtualNode; Column: TColumnIndex);
  private
    procedure BuildArtikelList;
    { Private-Deklarationen }
  public
    ArtikelList: TArtikelList;
    { Public-Deklarationen }
  end;

var
  frmTNSLagerWareneingang: TfrmTNSLagerWareneingang;

implementation

{$R *.dfm}

procedure TfrmTNSLagerWareneingang.BuildArtikelList;
begin
  vstArtikel.BeginUpdate;
  try
    vstArtikel.Clear;
    vstArtikel.RootNodeCount:=ArtikelList.Count;
  finally
    vstArtikel.EndUpdate;
  end;
end;

procedure TfrmTNSLagerWareneingang.FormCreate(Sender: TObject);
begin
  ArtikelList:=TArtikelList.Create(true);
end;

procedure TfrmTNSLagerWareneingang.FormDestroy(Sender: TObject);
begin
  ArtikelList.Free;
end;

procedure TfrmTNSLagerWareneingang.FormShow(Sender: TObject);
begin
  BuildArtikelList;
end;

procedure TfrmTNSLagerWareneingang.vstArtikelCreateEditor(
  Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
  out EditLink: IVTEditLink);
begin
  case Column of
    3, 5: EditLink:=TEditValueEditLink.Create;
  end;
end;

procedure TfrmTNSLagerWareneingang.vstArtikelEditing(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean);
begin
  Allowed:=(Column=3) or (Column=5);
end;

procedure TfrmTNSLagerWareneingang.vstArtikelFocusChanged(
  Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex);
begin
// Sender.EditNode(Node, 3);
end;

procedure TfrmTNSLagerWareneingang.vstArtikelGetText(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
  var CellText: string);
var
  a: TArtikel;
begin
  a:=TArtikel(vstArtikel.GetNodeData(Node)^);
  if Assigned(a) then
    case Column of
      0: CellText:=a.ArtikelNummer;
      1: CellText:=a.Beschreibung;
      2: CellText:=a.Count.ToString;
      3: CellText:=a.CountGelief.ToString;
      4: CellText:=FormatFloat('#,##0.00 €', a.EK);
      5: CellText:=FormatFloat('#,##0.00 €', a.EKGelief);
      6: CellText:=a.Distributor;
    end;
end;

procedure TfrmTNSLagerWareneingang.vstArtikelInitNode(Sender: TBaseVirtualTree;
  ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
begin
  vstArtikel.SetNodeData(Node, ArtikelList[Node.Index]);
end;

{ TEditValueEditList }

function TEditValueEditLink.BeginEdit: Boolean;
begin
  Self.FEdit.Show;
  Self.FEdit.SetFocus;
  Self.GetNodeText;
  Self.FEdit.SelectAll;
end;

function TEditValueEditLink.CancelEdit: Boolean;
begin
  Result := True;
  FEdit.Hide;
end;

destructor TEditValueEditLink.Destroy;
begin
  FEdit.Free;
  inherited Destroy;
end;

function TEditValueEditLink.EndEdit: Boolean;
begin
  try
    case FColumn of
     3: TArtikel(FTree.GetNodeData(FNode)^).CountGelief:=FEdit.Value;
     5: TArtikel(FTree.GetNodeData(FNode)^).EKGelief:=FEdit.Value;
    end;
    FTree.InvalidateNode(FNode);
  except
    on e: Exception do
      MessageBox(FTree.Parent.Handle, PChar(e.Message), 'Fehler', MB_OK or MB_ICONERROR or MB_TASKMODAL);
  end;
  Result := True;
end;

function TEditValueEditLink.GetBounds: TRect;
begin
  Result := FEdit.BoundsRect;
end;

procedure TEditValueEditLink.GetNodeText;
begin
  case FColumn of
    3: Self.FEdit.Value := TArtikel(FTree.GetNodeData(FNode)^).CountGelief;
    5: Self.FEdit.Value := TArtikel(FTree.GetNodeData(FNode)^).EKGelief;
  end;
end;

function TEditValueEditLink.PrepareEdit(Tree: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex): Boolean;
begin
  Result := True;
  FTree := Tree as TVirtualStringTree;
  FNode := Node;
  FColumn := Column;
  FEdit := TJvValidateEdit.Create(FTree);
  FEdit.Visible := False;
  FEdit.Parent := FTree;
  case FColumn of
    3: self.FEdit.DisplayFormat:=dfInteger;
    5: self.FEdit.DisplayFormat:=dfCurrency;
  end;
end;

procedure TEditValueEditLink.ProcessMessage(var Message: TMessage);
begin
  if Assigned(FEdit) then
    FEdit.WindowProc(Message);
end;

procedure TEditValueEditLink.SetBounds(R: TRect);
var
  Dummy : Integer;
begin
  FTree.Header.Columns.GetColumnBounds(FColumn, Dummy, R.Right);
  R.Left := Dummy;// + FTree.Margin * 2;
  FEdit.Width := R.Width;
  R.Bottom := Abs(R.Top) + Abs(FTree.NodeHeight[FTree.FocusedNode]);
  InflateRect(R, 0, 1);
  FEdit.BoundsRect := R;
end;

end.
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: VST IVTEditLink AccessViolation bei WindowProc

  Alt 2. Feb 2021, 10:20
Ich kann so auf die Schnelle jetzt nichts erkennen. Ein Vergleich mit meinen EditLinks die ich seit Jahren im Einsatz habe zeigt jetzt auch nichts ungewöhnliches. Habe allerdings den Code jetzt auch nicht in ein Projekt reingenommen und dort getestet. Hilft der StackTrace eventuell weiter? Woher kommt die Message?
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:58 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