Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Ab und an AV bei VirtualStringTree (https://www.delphipraxis.net/194239-ab-und-av-bei-virtualstringtree.html)

Hobbycoder 1. Nov 2017 16:51

Ab und an AV bei VirtualStringTree
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe eine ObjectList die als Datenquelle für das VST dient.

Zu Aufbauen der VST dient folgen Procedure:
Delphi-Quellcode:
procedure TfrmMainServer.BuildList;
var
  i: Integer;
  Node: PVirtualNode;
begin
  vrtlstrngtrAnrufliste.BeginUpdate;
  try
    vrtlstrngtrAnrufliste.Clear;
    for i:=AnrufList.Count-1 downto 0 do
      Node:=vrtlstrngtrAnrufliste.AddChild(nil, AnrufList[i]);
  finally
    vrtlstrngtrAnrufliste.EndUpdate;
  end;
end;
Zur Anzeige dann:
Delphi-Quellcode:
procedure TfrmMainServer.vrtlstrngtrAnruflisteGetText(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
  var CellText: string);
var
  Anruf: TAnruf;
begin
  if node<>nil then
  begin
    Anruf:=TAnruf(vrtlstrngtrAnrufliste.GetNodeData(Node)^);
    case Column of
      0: CellText:=FormatDateTime('dd.mm.yy hh:nn:ss',Anruf.Zeit);
      1: if Anruf.name<>'' then
           CellText:=Anruf.RN + ' ('+Anruf.name+')' else
           CellText:=Anruf.RN;
      2: CellText:=Anruf.MSN;
      3: case Anruf.Service of
           csALL: CellText:='Alle';
           csTELEPHONY: CellText:='Telefonie';
           csANALOG_TELEPHONY: CellText:='Analogtelefonie';
           csDIGITAL_TELEPHONY: CellText:='Digitaltelefonie';
           csFAX3: CellText:='Fax G3';
           csFAX4: CellText:='Fax G4';
           csDATA_64K: CellText:='Daten 64k';
           csDATA_56K: CellText:='Daten 56k';
           csPACKET_MODE: CellText:='Packetmode';
           csUNKNOWN: CellText:='Unbekannt';
         end;
      4: Case Anruf.AMStatus of
           lsUnbekannt: CellText:='Unbekannte MSN';
           lsProtokolliert: CellText:='Nur Aufzeichnen';
           lsGesendet: CellText:='An Client senden';
         End;
    end;
  end;
end;
Mittels DblClick soll dann eine Eigenschaft des hinter dem Node stehenden Objects bearbeitet werden:
Delphi-Quellcode:
procedure TfrmMainServer.vrtlstrngtrAnruflisteNodeDblClick(
  Sender: TBaseVirtualTree; const HitInfo: THitInfo);
var
  anruf: TAnruf;
  oldname, newname: string;
  name: TName;
begin
  vrtlstrngtrAnrufliste.BeginUpdate;
  try
    anruf:=TAnruf(vrtlstrngtrAnrufliste.GetNodeData(HitInfo.HitNode)^);
    if anruf.name<>'' then
      oldname:=anruf.name else
      if NameList.IndexOfRN(anruf.RN)>-1 then
        oldname:=NameList[NameList.IndexOfRN(anruf.RN)].name else
        oldname:='';
    newname:=InputBox('Namenzuordnung','Geben sie einen Namen zu der Rufnummer an:', oldname);
    if newname<>oldname then
    begin
      if newname='' then
      begin
        if NameList.IndexOfRN(anruf.RN)>-1 then
          NameList.Delete(NameList.IndexOfRN(anruf.RN));
      end else begin
        if NameList.IndexOfRN(anruf.RN)>-1 then
        begin
          Name:=NameList[NameList.IndexOfRN(anruf.RN)];
        end else begin
          Name:=TName.Create;
          NameList.Add(name);
          name.rn:=anruf.RN;
        end;
        name.name:=newname;
      end;
      NameList.SaveToFile;
      AnrufList.ReplaceName(anruf.RN, newname);
      AnrufList.SaveToFile;
      BuildList;
    end;
  finally
    vrtlstrngtrAnrufliste.EndUpdate;
  end;
end;
Soweit alles schick. Ich kann auch mehrere Male TAnruf.name verändern.

Aber nach ein paar Veränderungen (unregelmäßig viele) tritt immer eine AV in der VST-Procedure GetPreviousVisibleNoInit aus der Unit VirtualTrees auf. Und über den Stack kann ich leider keine Rückschlüsse ziehen, auf Grund welches Ereignisses er in diese Procedure springt.

Hat jemand eine Tipp für mich, wie ich dem Fehler auf die Spur kommen könnte?
Den Aufruf-Stack habe ich mal als Image angehängt.

nahpets 1. Nov 2017 17:07

AW: Ab und an AV bei VirtualStringTree
 
Hier würd ich erstmal das ändern:
Delphi-Quellcode:
anruf:=TAnruf(vrtlstrngtrAnrufliste.GetNodeData(HitInfo.HitNode)^);
if anruf.name<>'' then
Delphi-Quellcode:
anruf:=TAnruf(vrtlstrngtrAnrufliste.GetNodeData(HitInfo.HitNode)^);
if Assigned(anruf) then begin
  if anruf.name<>'' then
...
end else begin
  // Passende Fehlermeldung, wenn erforderlich.
end;
Wenn man beim Doppelclick keinen Node richtig getroffen hat, geht das, so wie es ist, schief.

Hobbycoder 1. Nov 2017 17:31

AW: Ab und an AV bei VirtualStringTree
 
Könnte man machen. Bei einem Listview oder einer Listbox wäre das auch zwingend notwendig, da dort ja der Event OnDblClick verwendet wird, der auch ausgelöst wird, wenn man kein Item auswählt.

Bei VST nutze ich aber OnNodeDblClick, welcher nur ausgelöst wird wenn der DblClick auch auf einem Node stattfindet. Klickt man im freien Bereich, so wird wie beim Listview/ListBox zwar das OnDblClick-Ereignis ausgelöst, nicht aber das OnNodeDblClick.

Zwar würde das von dir nicht schaden, ist aber nicht die Ursache für meine AV.

ich werde da aber trotzdem so machen, wie du geschrieben hat, den es könnte ja auch noch andere Gründe geben, warum das VST bei GetNodeData keinen Zeiger zurückliefern kann.

Außerdem tritt die AV "immer" hinter der Zeile
Delphi-Quellcode:
newname:=Inputbox(....);
auf.

Hobbycoder 1. Nov 2017 17:39

AW: Ab und an AV bei VirtualStringTree
 
Ich habe jetzt aber mal deine Tipp in OnGetText umgesetzt. Jetzt scheint der Fehler nicht mehr aufzutreten.
Was mich ein wenig wundert. Denn dort wird nur aus der AnrufList gelesen. Und der werden über den DblClick keine Element hinzugefügt oder entfernt. Einzig wird die Property name verändert.


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