Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.08.01;
Скачать: [xml.tar.bz2];

Вниз

Отчет в Word в отдельном потоке Thread   Найти похожие ветки 

 
Виталя ©   (2004-07-15 14:12) [0]

Я пытаюсь "отвести" создание отчета в Wordе(при помощи OLE) в отдельный поток, так чтобы пользователь мог работать с программой пока он формируется.

    TWordThread = class(TThread)
    private
     fWF:WordFuncs;
//это мой класс в нем хранятся настройки для Word и процедуры вывода отчетов (вполне рабочие)
     fIBQ:TIBQuery;
    protected
     procedure Execute; override;
    public
     constructor Create(AWF:WordFuncs;AIBQ:TIBQuery);
    end;

implementation
     constructor TWordThread.Create(AWF:WordFuncs;AIBQ:TIBQuery);
     begin
       inherited Create(true);
       fWF:=aWF;
       fIBQ:=AIBQ;
       Resume;
     end;

     procedure TWordThread.Execute;
     begin
       fWF.SaveQueryToWord(fIBQ);//эта процедура откр.Word, создает новый документ , в нем табл. и заполняет ее инф. из Query
       fWF.Done;
       fIBQ.Transaction.Commit;
       Destroy;//После вывода данных поток уничтожается
     end;

В теле программы я опред. переменную
WordThread:TWordThread;

и создаю поток
WordThread:=TWordThread.Create(WF,IBQ_);

Word открывается, но документ не создается - выдается ошибка класса EOleSysError с сообщ "CoInitialize has not been called".

Может нельзя использовать Tread для таких целей(я его вообще-то первый раз использую). Помогите разобраться пожалуйста.


 
Суслик   (2004-07-15 14:14) [1]


> CoInitialize has not been called

вам пересвести?
"CoInitialize не был вызван"
Значит что?
Надо вызвать?
Точно.
Первой строчкой execute поставте coinitialize(не помню праметров)
Такой вызов нужно делать для каждого потока - в главном за вас дельфи уже это сделал. В доппотоках - делайте сами.


 
Суслик   (2004-07-15 14:15) [2]

и еще сомневаюсь, что word переварит многопоточный доступ к себе.


 
Виталя ©   (2004-07-15 15:22) [3]

а вы не подскажите в каком модуле описана эта ф-ция, а то у меня Delphi ее не узнает, хотя ComObj в список включен, а в хелпе на эту функцию модуль не указан.


 
clickmaker ©   (2004-07-15 15:27) [4]


> Виталя ©   (15.07.04 15:22) [3]
> а вы не подскажите в каком модуле описана эта ф-ция

ActiveX


 
Суслик   (2004-07-15 15:31) [5]


> Виталя ©   (15.07.04 15:22) [3]

понятия не имею, но total comander + alt f7 в диркетории с исходниками отвечают на все вопросы.


 
Sha ©   (2004-07-15 15:40) [6]

Виталя ©   (15.07.04 14:12)

И еще.

Идеологически неверно писать Resume в конструкторе потока, да и не вседа безопасно к тому же.
В твоем случае лучше вызывать
inherited Create(false);


 
Виталя ©   (2004-07-15 15:43) [7]

спасибо,
хотя теперь оно говорит, что приложение вызвало интерфейс, маршалированный для другого потока...


 
Суслик   (2004-07-15 15:46) [8]


>
> Виталя ©   (15.07.04 15:43) [7]
> спасибо,
> хотя теперь оно говорит, что приложение вызвало интерфейс,
> маршалированный для другого потока...

вот я про это и говорил - не все ком сервера позволяют так себя насиловать. Создавай объект (т.е. CreateOleObject) прямо в потоке - в функции exeсute. Проблем не будет.


> Sha ©   (15.07.04 15:40) [6]

Александр, почему?
Вроде все нормально


 
Sha ©   (2004-07-15 15:50) [9]

Суслик   (15.07.04 15:46) [8]

AfterConstruction проверяет CreateSuspended(или как-то так), и если оно false, то делает Resume. Проверка приводит к AV, если поток успеет закончить вычисления к этому времени. Вполне реальная ситуация.


 
Суслик   (2004-07-15 15:54) [10]


> Sha ©   (15.07.04 15:50) [9]

Вы что-то путаете.
У нее (автора) же CreateSuspended = true.


 
Sha ©   (2004-07-15 15:55) [11]

Суслик   (15.07.04 15:54) [10]

Но проверка-то выполняется всегда.


 
Суслик   (2004-07-15 15:58) [12]


> Sha ©   (15.07.04 15:55) [11]
> Суслик   (15.07.04 15:54) [10]
>
> Но проверка-то выполняется всегда.

И?
FreeOnTerminate равно false.
Поэтому к моменту отработки указанной вами проверки с объектом ничего не случится - ни в случае, если поток уже закончит работу, ни в случае если еще будет продолжнать. Проверка даст false и никакого resume не будет.


 
Виталя ©   (2004-07-15 15:59) [13]

насчет идеологии не знаю, а конструкция из статьи на этом форуме, хотя похоже код
constructor TWordThread.Create(AWF:WordFuncs;AIBQ:TIBQuery);
    begin
      fWF:=aWF;
      fIBQ:=AIBQ;
      inherited Create(false);
    end;
будет эквивалентен.

> Суслик   (15.07.04 15:46) [8]
> вот я про это и говорил - не все ком сервера позволяют так
> себя насиловать. Создавай объект (т.е. CreateOleObject)
> прямо в потоке - в функции exeсute. Проблем не будет.

Действительно получилось, спасибо.


 
Суслик   (2004-07-15 16:01) [14]


> Действительно получилось, спасибо.

Спасибо, буду знать, т.к. советовал я исключительно по книгам - не по опыту.


 
Sha ©   (2004-07-15 16:01) [15]

Суслик   (15.07.04 15:58) [12]

Естественно AV будет только при FreeOnTerminate = true. Именно поэтому я и написал, что
Идеологически неверно писать Resume в конструкторе потока, да и не всегда безопасно к тому же.


 
Суслик   (2004-07-15 16:12) [16]

Идеология - штука сложная.
Я вообще не пользуюсь FreeOnTerminate, поэтому мне (как и примеру кода автора) такое не грозит.


 
Sha ©   (2004-07-15 16:12) [17]

> Виталя ©   (15.07.04 15:59) [13]

Нет никакой необходимости вызывать inherited конструктор после операторов присваивания, можно писать как обычно:
constructor TWordThread.Create(AWF:WordFuncs;AIBQ:TIBQuery);
begin
  inherited Create(false);
  fWF:=aWF;
  fIBQ:=AIBQ;
end;


 
Sha ©   (2004-07-15 16:15) [18]

Суслик   (15.07.04 16:12) [16]

У меня наоборот, почти всегда FreeOnTerminate = true,
и на вызове Resume из конструктора, было дело, обжигался.


 
Суслик   (2004-07-15 16:19) [19]


> Sha ©   (15.07.04 16:15) [18]

Согласен, наверное (внимаетльно не смотрел).
Я вообще перестал пользоваться tthread :)))
CreateThread и дело с концом.


 
Sha ©   (2004-07-15 16:22) [20]

Суслик   (15.07.04 16:19) [19]

Это да, но часто удобно пользоваться методами.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.08.01;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.035 c
14-1089718802
Aldor_
2004-07-13 15:40
2004.08.01
Как работать с IDL файлами в Delphi?


14-1089974061
Депрессирующий Человек
2004-07-16 14:34
2004.08.01
Программизм -> импотенция, геморрой :(


8-1084547525
WH
2004-05-14 19:12
2004.08.01
TCanvas тороза создаёт


1-1089965306
gdima
2004-07-16 12:08
2004.08.01
exec


3-1089203075
Fast
2004-07-07 16:24
2004.08.01
как поймать момент когда DBGrid переходит в режим редактирования





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский