![]() |
XML schliessen
Hi,
ich möchte folgendes machen. In Form2 habe ich eine Listview, die Einträge aus einer XML-Datei einliest. Dann klicke ich ein Item an und dann auf "Bearbeiten". Form8 ist das Formular zum Bearbeiten. Im OnActivate steht folgendes drin:
Delphi-Quellcode:
Da erhalte ich eine Zugriffsverletzung. Ich denke, dass kommt daher, da die Datei schon in Gebrauch ist... wie kann ich sie schließen?
var
id:String; node: IXMLDOMNode; begin id:=Form2.ListView1.Items[Form2.ListView1.ItemIndex].Caption; node:= xmldoc.DocumentElement.selectSingleNode( '/verzeichnis/eintrag[id=' + id + ']'); node.selectSingleNode('1').text:=Edit2.Text; node.selectSingleNode('2').text:=Edit3.Text; node.selectSingleNode('3').text:=Edit4.Text; node.selectSingleNode('4').text:=Edit5.Text; node.selectSingleNode('5').text:=Edit6.Text; node.selectSingleNode('6').text:=Memo1.Text; end; Danke im Vorraus |
Re: XML schliessen
Hi,
wenn dein "xmlDoc" ein Interfacezeiger (IXMLDocument oder Ähnlich.) wurde dieser eventuell schon in einer anderen Routine wg. der Referenzzählung freigegben und daher die Zugriffsverletzung. Erstelle xmlDoc einfach mal neu. mfG mirage228 |
Re: XML schliessen
Hi,
in jeder FormCreate (Form1-9) habe ich folgendes:
Delphi-Quellcode:
Ist doch neu erstellt, oder=
fAppPath:=ExtractFilePath(Application.ExeName);
xmlDoc:=CoDOMDocument40.Create; xmlDoc.setProperty('NewParser', true); if not FileExists(fAppPath+DataBase) then begin xmlDoc.loadXML('<?xml vesion="1.0"?><movieorganizer></movieorganizer>'); end else xmlDoc.load(fAppPath+Database); |
Re: XML schliessen
Hi,
versuche mal das xmlDoc in das public deines Hauptformulares zu schieben und die anderen Forms drauf zugreifen zu lassen (du kannst xmlDoc auch den anderen Forms zuweisen). Ansonsten kann ich mir vorstellen, dass dein xmlDoc nach dem FormCreate freigegben wird und in FormActivate nicht mehr verfügbar ist. mfG mirage228 |
Re: XML schliessen
Wie sieht das aus, oder wie kann ich das Dokument freigeben?
|
Re: XML schliessen
Das benutzte XML-Objekt kannst du durch ein einfaches
Delphi-Quellcode:
freigeben. Aber egal, ich persönlich würde die Idee von mirage vorziehen; sprich: ein XML-Objekt, das von allen Forms genutzt werden kann. Es wird allerdings noch einfacher, diese Idee umzusetzen, wenn du vor oder nach dem Aufruf der jeweiligen Form die Werte zuweist. Das hängt von der Situation ab.
xmldoc := nil;
Wenn ich mir aber dein Beispiel von ganz oben ansehe, dann ergibt das für mich nicht viel Sinn. Im "OnActivate" steht bei dir drin, dass er dem XML-Knoten einen neuen Wert zuweisen soll? Oder wolltest du das anders herum; dass er dem Editfeld den Wert aus dem Knoten zuweisen soll? Wie dem auch sei, du hast Codeteile von Chakotays MovieOrganizer zitiert. Darum verstehe ich persönlich das Problem nicht ganz, denn du könntest einen Blick in das Original werfen und gucken wie Chris und ich das gelöst haben. In der aktuellen Version (1.8.3) gibt es nur noch ein einziges XML-Objekt. Und das liegt in der Hauptform. Wenn man bspw. den Bearbeiten-Dialog aufrufen will, dann sieht der Code so aus:
Delphi-Quellcode:
Ich gebe zu, der Code ist ein bisschen umfangreich. Aber wie du vllt. erkennen kannst, ist nur ein einziges XML-Objekt in der Hauptform notwendig. Auf die Weise vermeidet man Überschneidungen und evtl. Fehler, und nebenbei wird der Code auch kürzer und effizienter. ;)
procedure TMO18Form.IDM_EDITMOVIEClick(Sender: TObject);
var curNode : IXMLDOMNodeList; idx : integer; i : integer; li : TListItem; begin // nothing selected, or XML parser is blowin' in the wind ... if(MovieList.Selected = nil) or (xmldoc = nil) then exit; // get the node, using Movie's title idx := -1; curNode := xmldoc.selectNodes('/' + mainnode + '/' + movienode + '[name="' + MovieList.Selected.Caption + '" and ' + 'format="' + MovieList.Selected.SubItems[0] + '"]'); if(curNode.length > 1) then begin DoubleItems.ListView1.Items.Clear; DoubleItems.ListView1.Items.BeginUpdate; for i := 0 to curNode.length - 1 do begin li := DoubleItems.ListView1.Items.Add; li.Caption := inttostr(i); li.SubItems.Add(curNode.item[i].selectSingleNode(szMovieArray[1]).text); li.SubItems.Add(curNode.item[i].selectSingleNode(szMovieArray[2]).text); end; DoubleItems.ListView1.Items.EndUpdate; // show form if(DoubleItems.ShowModal = mrOk) then idx := DoubleItems.ListView1.Selected.Index; end // only 1 item else if(curNode.length = 1) then idx := 0 // there's nothing else exit; // nothing's selected if(idx < 0) then exit; with AddingForm do begin // Hier werden die Werte aus der Datei an die entsprechenden // Eingabefelder der "AddingForm"-Form übergeben Caption := EDITMOVIE; Edit1.Text := curNode.item[idx].selectSingleNode(szMovieArray[1]).text; ComboBox1.ItemIndex := ComboBox1.Items.IndexOf( curNode.item[idx].selectSingleNode(szMovieArray[2]).text); ComboBox2.ItemIndex := ComboBox2.Items.IndexOf( curNode.item[idx].selectSingleNode(szMovieArray[3]).text); Edit2.Text := curNode.item[idx].selectSingleNode(szMovieArray[4]).text; Edit3.Text := curNode.item[idx].selectSingleNode(szMovieArray[5]).text; ComboBox3.ItemIndex := ComboBox3.Items.IndexOf( curNode.item[idx].selectSingleNode(szMovieArray[6]).text); ComboBox4.ItemIndex := ComboBox4.Items.IndexOf( curNode.item[idx].selectSingleNode(szMovieArray[7]).text); Edit4.Text := curNode.item[idx].selectSingleNode(szMovieArray[8]).text; Memo1.Lines.Text := curNode.item[idx].selectSingleNode(szMovieArray[9]).text; Edit5.Text := curNode.item[idx].selectSingleNode(szMovieArray[10]).text; // Wenn der User diese Form mit OK schließt, dann bedeutet // das, er möchte die neuen Werte speichern; und das passiert // dann hier if(AddingForm.ShowModal = mrOk) then begin curNode.item[idx].selectSingleNode(szMovieArray[1]).text := Edit1.Text; curNode.item[idx].selectSingleNode(szMovieArray[2]).text := ComboBox1.Items[ComboBox1.ItemIndex]; curNode.item[idx].selectSingleNode(szMovieArray[3]).text := ComboBox2.Items[ComboBox2.ItemIndex]; curNode.item[idx].selectSingleNode(szMovieArray[4]).text := Edit2.Text; curNode.item[idx].selectSingleNode(szMovieArray[5]).text := Edit3.Text; curNode.item[idx].selectSingleNode(szMovieArray[6]).text := ComboBox3.Items[ComboBox3.ItemIndex]; curNode.item[idx].selectSingleNode(szMovieArray[7]).text := ComboBox4.Items[ComboBox4.ItemIndex]; curNode.item[idx].selectSingleNode(szMovieArray[8]).text := Edit4.Text; curNode.item[idx].selectSingleNode(szMovieArray[9]).text := Memo1.Lines.Text; curNode.item[idx].selectSingleNode(szMovieArray[10]).text := Edit5.Text; self.UpdateList(ColumnToSort); end; end; end; Das müsstest du mal ausprobieren. |
Re: XML schliessen
Ja das sieht doch mal gut aus. Zumal verstehe ich ihn weitestgehend. Nur das Problem ist, dass ich noch ein ganz altes TUT von Chakotay bzw euch habe. Das neuere konnte ich nicht downloaden. Kannst du mir mal bitte einen Link posten, oder es hier uploaden, falls du es nicht schon irgendwo gemacht hast.
Diese Variante ist echt viel besser. Außerdem beschleunigt es (in meinem Falle) auch den Start des Programmes, da nicht von Form1.Create bis Form9.Create die XML-Daten initialisiert werden müssen. Vielen Dank erstmal und über den Link würde ich mich freuen :wink: Bye |
Re: XML schliessen
Liste der Anhänge anzeigen (Anzahl: 2)
Zitat:
So gab es damals eine Form zum Hinzufügen von neuen Filmen und eine weitere zum Bearbeiten von Filmen. Jetzt gibt´s nur noch eine, mit der man einen Film sowohl hinzufügen als auch bearbeiten kann. Ob es ein neueres Tutorial gibt, das weiß ich nicht. Das wird dir Chakotay beantworten können/müssen. Ich denke aber, irgendwann wird sicher was kommen. Ich hänge mal die Version 1.8.3 von MO ran, so wie ich ihn auf meiner Platte habe. Es ist zwar ein Setup (NSIS), aber du brauchst keine Admin-Rechte o.ä. Nur einen Ordner, in dem du Schreibzugriff hast wenn du nicht der Admin sein solltest. Die Filmdatenbank wird übrigens im Programmverzeichnis angelegt. Beim echten Setup würde in dem Fall ein Hilfsprogramm dem Ordner "users" das Schreibrecht für alle Benutzer geben. Das funktioniert, weil der Admin das Setup ausführt, und weil damit das Hilfsprogramm natürlich auch die Möglichkeit hat, dieses Schreibrecht zu setzen. Damit konnte man auch als Benutzer seine Datenbanken anlegen, selbst wenn man keine Admin-Rechte hatte. Und die Deinstallation war einfacher. Irgendwo habe ich auch noch das Setup für die Release-Version liegen. Allerdings wollte ich das eher Chris überlassen. Es ist ja immerhin sein Programm. Einstweilen viel Spaß mit dem Quellcode. Aber schau nicht zu sehr ins Tutorial, es hat sich zuviel verändert. :) PS: Ich sehe gerade, im Setup fehlt die Manifest-Datei. Ich hänge sie auch mal mit ran, sonst hast du von den ganzen XP-Spielereien nichts. Die muss mit ins Hauptverzeichnis, in dem auch die XSD-Datei ist. PPS: Wenn du einen Fehler wg. der XML-Typbibliothek bekommst, dann bitte zwei Sachen bedenken 1. Ich habe einen Hauptordner für meine Delphiprojekte. In dem befinden sich gemeinsam genutzte Units. Der Pfad dürfte bei dir also nicht stimmen. Aber das ist das geringste Problem, denke ich. Schau in die DPR-Datei und ändere es entsprechend. 2. Ich nutze neben XML 4 und XML 3, darum tragen meine Units entsprechende Namen. Wenn deine Unit nicht "MSXML4_TLB.pas" heißt, dann müsstest du das ebenfalls anpassen. Oder du benennst deine Unit einfach um. |
Re: XML schliessen
Hi,
Zitat:
Chris PS: Sorry, für's kurze OT. |
Re: XML schliessen
Version 2.0? Ist das nicht ein Rückschritt, wo es doch v2.1 auf deiner Seite gibt?
Oder passt du dich einfach nur der wirtschaftlichen Situation in Deutschland an? :mrgreen: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:58 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