![]() |
VST IVTEditLink AccessViolation bei WindowProc
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
Delphi-Quellcode:
, wobei ich leider den Wert von Message im Debugger nicht auslesen kann.
FEdit.WindowProc(Message);
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. |
AW: VST IVTEditLink AccessViolation bei WindowProc
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?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:22 Uhr. |
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