DELPHI 7->TXmlDocument->DocumenElement->Problem

5 отговора 78 прегледа
#1

DELPHI 7->TXmlDocument->DocumenElement->Problem

Здравейте !
Проблема е следния :

..........................
var xmlDocument : TxmlDocument;
..................................
xmlDocument := TXmlDocument.Create(nil);
xmlDocument.FileName :='.\Xml\File.xml';
xmlDocument.DOMVendor := GetDomVendor('MSXML');
xmlDocument.Active := true;
//Test
ShowMessage(xmlDocument.DocumentElement.ChildNodes [0].ChildNodes[0].Text); // <- ей тука гърми
..........................................


Този код се намира в клас ,който от своя страна се намира в DLL , която пък се достъпва от .EXE.
Когато се изпълни , програмата гърми еи тука :
ShowMessage(xmlDocument.DocumentElement.ChildNodes [0].ChildNodes[0].Text;
и то точно в DocumentElement /който би трябвало да съсържа root node на XML файла/.
Абсолютно същия код, разписан във форма /дори и във форма намираща се във същия DLL / се изпълнява без никакъв проблем ...Но когато се изпълнява така както аз искам /като метод на различен от TForm1 клас/ гърми с EAccessViolation exception at address ..................
Някой може ли да ми каже къде е проблема ?

П.С. Става въпрос за Delphi 7

Благодаря предварително !

Отговор
в отговор на БOИЛ #2

Re: DELPHI 7-&gt;TXmlDocument-&gt;DocumenElement-&gt;Problem

Значи проблема е ясен ;-)))) - за да ползваш форми в DLL (в частност ShowMessage също е форма - мисля,че не е ползва стандартната функция на Win) - трябва да предадеш Application.Handle - a и да инициализираш този в библиотеката с него при използването на библиотеката, като запазиш стария - и преди unload-а да върнеш старата стойност. Този трик се ползва за правене на plug-in-и и поставяне на форми в библиотеки. Идеята е, че библиотеката има собствена Application променлива която не е инициализирана "коректно" в контекста на приложението.

Ето малко код: - май - Screen обекта не беше нужен

procedure ShowMyForm(App : TApplication; Scr : TScreen); stdcall;
var
a: TForm2;
begin
Application := App;
Screen := Scr;
a := TForm2.Create(Application.MainForm);
{"Application.MainForm" could also be "nil" or any valid value}
a.ShowModal;
a.Free;
end;

exports
ShowMyForm;

end.

Add to the "uses" clause "Forms". Add a new form unit to the project. In the
"Implementation" area of the form put:

var
OldApp : TApplication;
OldScr : TScreen;

initialization
OldApp := Application;
OldScr := Screen;
finalization
Screen := OldScr;
Application := OldApp;
end.

P.S. Надявам се съм познал проблема.
Кажи ако проработи или ако не работи - но това което съм казал ми се струва най-близко до проблема.

Редактирано от PhantomAS на

Отговор
в отговор на PhantomAS #3

Друг пример...

Още по нагледен пример - обаче имам едно питане - защо си решил да оставиш функционалност която се занимава с визуализацията - в библиотека а не в главната програма ??? - не ми изглежда чисто решение - е освен ако така ти се налага.

-------------------------------
library testDLL;

uses
myTestFrom, SysUtils, Controls;


var
OldApphandle:longint = 0;

{ these functions are used with the mode-less form: }

{ AppHandle is the *calling* applications Handle }
function ShowTestForm(AppHandle:integer):longint;
var F:TmyTestForm;
begin
{ save current handle unless it's already done }
if Application.Handle <> AppHandle then
OldAppHandle := Application.Handle;
{ assign new }
Application.Handle := AppHandle;
{ create and show form }
F := TmyTestForm.Create(Application);
F.Show;
Result := longint(F);
end;

{ the input value, Handle, must be the same value as returned by ShowTestForm }
function CloseTestForm(Handle:longint):integer;
var F:TmyTestForm;
begin
{ typecast back to TForm (some sanity checks here would not be bad...}
F := TmyTestForm(Handle);
Result := F.SomeIntValue;
F.Close;
F.Free;
{ restore previous handle }
Application.Handle := OldAppHandle;
end;

{ this function is used to show the form modally }
function ShowTestFormModal(AppHandle:integer):longint;
var F:TmyTestForm;
begin
OldAppHandle := Application.Handle;
try
Application.Handle := AppHandle;
F := TmyTestForm.Create(Application);
try
if F.ShowModal = mrOK then
Result := F.SomeIntValue
else
Result := -1;
finally
F.Free;
end;
finally
Application.Handle := OldAppHandle;
end;
end;

{ finally export the functions: }

exports ShowTestForm name 'ShowTestForm', CloseTestForm name 'CloseTestForm',
ShowTestFormModal name 'ShowTestFormModal';

begin
end.

---
Колкото повече, толкова повече.
Отговор
в отговор на БOИЛ #4

Re: DELPHI 7-&gt;TXmlDocument-&gt;DocumenElement-&gt;Proble

Проблема е в самия TXMLDocument а решението ще намериш на

[линк]

AquilaX

____________
умният знае кога да говори, мъдрият знае кога да мълчи
Отговор
в отговор на AquilaX #5

Re: DELPHI 7-&gt;TXmlDocument-&gt;DocumenElement-&gt;Proble

Точно в десятката !!!!
Благодаря ти много!

Отговор
в отговор на PhantomAS #6

Re: Друг пример...

Балгодаря и на теб за отделеното внимание ..!
Диалоговата форма в DLL-а я сложих само за тестване /както и другата форма в която се изпълняваше кода/ , защото ми направи впечатление,че същия код въврви без проблем във форма , а след като му направя COPY/PASTE в друг клас -> избива грешка ....
Благодаря ти още веднъж !
Всичко най-добро!

Отговор