Уважаемые жители Королевства, помогите!Плиз!
Я в Delphi совсем недавно, потребовалось изучать при написании диплома.Задача следующего содержания: есть расчетные модули в MathCAD, мне надо передать туда ряд значение, провести расчет без визуализации,потом вытащить от туда другие значения и работать с ними в delphi (все это надо сделать несколько раз, а именно 7). Все это сделала через OLE, считать то считает, но при разрушении оле-контейнера выдает ошибку сперва Privileged instruction, а потом еще и AcessVialetion, причем на втором шаге цикла в котором это все происходит перерасчет документа не происходит, так же выдает AcessVialetion. Чтоя только ни делала :( сил уже нет. Вот этот проклятый цикл:
for w6:=0 to 6 do
begin
ShellExecute(Application.Handle,'open','mathcad.exe',nil,nil,SW_HIDE);
Sleep(15000);
for asa:=0 to 6 do
begin
for aza:=0 to Pred(j) do
begin
case asa of
0 : (TSL_K_fm.FindComponent('Temp' + IntToStr(w6+1)) as TChart).Series[asa].AddXY(aza,int1[aza]);
1 : (TSL_K_fm.FindComponent('Temp' + IntToStr(w6+1)) as TChart).Series[asa].AddXY(aza,int2[aza]);
2 : (TSL_K_fm.FindComponent('Temp' + IntToStr(w6+1)) as TChart).Series[asa].AddXY(aza,int3[aza]);
3 : (TSL_K_fm.FindComponent('Temp' + IntToStr(w6+1)) as TChart).Series[asa].AddXY(aza,int4[aza]);
4 : (TSL_K_fm.FindComponent('Temp' + IntToStr(w6+1)) as TChart).Series[asa].AddXY(aza,int5[aza]);
5 : (TSL_K_fm.FindComponent('Temp' + IntToStr(w6+1)) as TChart).Series[asa].AddXY(aza,int6[aza]);
6 : (TSL_K_fm.FindComponent('Temp' + IntToStr(w6+1)) as TChart).Series[asa].AddXY(aza,int7[aza]);
end;
end;
end;
for ik:=0 to Pred(k) do
begin
for ij:=0 to Pred(j) do
begin
n_mas[ik,ij]:=d0[l];
inc(l);
(GraphicFm.FindComponent('GrTemp_' + IntToStr(w6+1)) as TChart).Series[ik].AddXY(ij,n_mas[ik,ij]);
end;
end;
for it:=0 to 1 do
begin
for ir:=0 to Pred(j) do
begin
n_mas1[it,ir]:=d1[p];
inc(p);
end;
end;
FileName:='C:\Program Files\Borland\Delphi7\Projects\1\LumMono'+IntToStr(w6+1)+'.prn';
AssignFile (LumMono,FileName);
Rewrite (LumMono);
for ir:=0 to Pred(j) do
begin
writeln (LumMono,n_mas1[0,ir],' ',n_mas1[1,ir]);
TSL_fm.TCL.Series[w6].AddXY(ir,n_mas1[1,ir]);
end;
CloseFile (LumMono);
Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
29-03-2009 23:43 | Сообщение от автора вопроса
Ура!Товарищи свершилось!Все работает идеально!
После того как убрала
>>>OLEContainer.Destroy();
ошибка выскакивала в конце программы, там у меня еще есть пара моментов где приходится работать с оле. Попробовала Free поставить, не помогло. Потом нашла
>>>FreeAndNil(OleContainer);
Классная штука!
Спасибо за совет, но метод Free мне тоже не помог, выкрутилась вот как (конечно неправельно скорее всего):я вообще убрала
>>>OLEContainer.Destroy();
а оставила только
>>>OLEContainer.Close;
и после, закрытие приложения MathCAD
>>>PostMessage(MatchCADWHandle,WM_QUIT,0,0);
пока все работает без ошибок.
Вы логику потеряли при чтении хелпа. Перевожу: Никогда не вызывайте Destroy непосредственно из приложения. И далее по тексту хелпа. Ваша ошибка заключается в том, что вы вызываете деструктор компонента перед вызовом унаследованного деструктора. В том же хелпе написано: Вызывайте метод Free . Вот этот метод корректно уничтожит ваш объект. И есть большая вероятность, что и память корректно освободится и ресурсы вернутся системе. А по поводу граблей в функции CreateOLEObject в двух словах ответить очень сложно. Все дело в том, что при позднем связывании не зная интерфейса COM-сервера вам с этим может быть очень трудно работать (при условии, что вы этого никогда не делали). Попробуйте импортировать таблицу типов (Project|Import Type Library) и попытаться разобраться с типами и интерфейсами MathCAD. Возможно, что в будущем это может пригодиться.
25-03-2009 22:48 | Комментарий к предыдущим ответам
А если не сложно подскажите как перейти от OLEContainer.CreateObjectFromFile к CreateOLEObject, какие грабли меня тут могут поджидать?Буду безумно благодарна если на моем примере продемонстрируете:)
что значит "при нормальном вызове деструктора", что у меня то не нормально...help прочитала еще раз...не доходит до меня...наверно после рабочего дня мозг совсем отказывает:(
Так Вы его, судя по вашему вопросу, так и не разрушили. А при нормальном вызове деструктора и объект разрушается и память, выделенная под него, освобождается. Внимательно прочтите хелп для TOLEContainer.Destroy.
я и один раз пробовала его создавать и после отработки разрушать, так тоже не работает, виртуальную память забивает до отказа, а
>>>ShellExecute(Application.Handle,'open','mathcad.exe',nil,nil,SW_HIDE);
пришлось написать потому что по другому даные из маткада не вытаскиваются, на простом примере когда изучала всё это дело все работало нормально, но когда свои модули подключила вот тут и начались проблемы, честно говоря даже не знаю почему:(
>>>OLEContainer.CreateObjectFromFile(ExtractFilePath(Application.ExeName)+mcdFileName,false);
разве не анологично CreateOLEObject?
простите конечно если туплю, но с делфи знакома всего 3 месяца.
И как-то несовсем понятно:
провести расчет без визуализации .
Тогда зачем
ShellExecute(Application.Handle,'open','mathcad.exe',nil,nil,SW_HIDE);.
Импортируйте библиотеку типов и пользуйтесь MathCAD как COM-сервером. И не нужен тут никакой OLEContainer. Есть такая функция CreateOLEObject. И еще вопрос: зачем в цикле семь раз создавать объект и разрушать его? Может быть проще один раз создать, отработать цикл и уничтожить?
Цитата из хелпа:
Do not call Destroy directly in an application. Instead, call Free. Free verifies that the TOleContainer reference is not nil, and only then calls Destroy.Destroy frees the OLE object before calling the inherited destructor.
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.