|
|
|
Supreme Being
      
участник
Last Login: 12.06.2008 11:23
Сообщ.: 96,
Visits: 535
|
|
Доброе время суток!
Я использовал поток в приложении CreateThread().. Примерно такая струкура приложения получилась:
interface
uses
....
procedure НазвниеПроцедуоры; stdcall;
type
TfrmMain = class(TForm)
...
var
ID: Cardinal;
implementation
...
procedure НазвниеПроцедуоры();
begin
....
ExitThread(0);
end;
procedure TfrmMain.cmdThreadClick(Sender: TObject);
begin
CreateThread(nil, 0, @НазвниеПроцедуоры, nil, 0, ID);
end;
Поток запускается нормально.. А когда завершаю работу прилодения появляется ошибка:
Exception EOSError in module ....
System error. Code: 1400.
Invalid window handle.
С чего может возникать такая ошибка?
Заранее благодарен за помощь!
|
|
|
|
|
Supreme Being
      
участник
Last Login: 12.06.2008 11:23
Сообщ.: 96,
Visits: 535
|
|
Заметил странную вещь! Ошибка возникает, когда я меняю possition на ProgressBar..
Немного пояню. Поток делает visible:= true у ProgressBar'а и по ходу выполнения комманд меняет possition, чтобы наглядно было видно выполнение потока. После выполнения visible устанавливается на false..
Если я убираю какие либо манипуляции с ProgressBar'ом, то и ошибка не возникает.
|
|
|
|
|
Supreme Being
      
участник
Last Login: 12.06.2008 11:23
Сообщ.: 96,
Visits: 535
|
|
Еще уточняю. Объект ProgressBar сначала скрыт и из потока, когда visible устанавливается в true возникает ошибка, только дебагер ничего о ней не говорит..
Я не знаю с чем она связана. Но при заврешении приложения появляется ошибка "Invalid window handle".
Я подумал, что может ProgressBar не успевает за потоком производить изменения внутри себя и сделал следующее:
ProgressBar.Visible:= True;
WaitForSingleObject(ProgressBar.Handle, INFINITE);
Но это не помогло!
Как можно еще решить эту проблему?
|
|
|
|
|
Supreme Being
модератор
Last Login: 04.05.2008 13:32
Сообщ.: 7 240,
Visits: 65 445
|
|
| Попробуй вынести изменение свойств ProgressBar в отдельный метод и вызывай его через Synchronize.
|
|
|
|
|
Supreme Being
      
участник
Last Login: 12.06.2008 11:23
Сообщ.: 96,
Visits: 535
|
|
Я тоже думал, что Synchronize спасет.. Но почему-то он не хочет работать..
Создал новую процедуру procedure set_ProgressBar(Visible: Boolean; Possition: Integer), куда передаю нужные параметры.. А в функции, которую выполняет поток добавил Synchronize(set_ProgressBar(True, 20)), на что Delphi говорит "Missing operator or semicolon"..
|
|
|
|
|
Supreme Being
модератор
Last Login: 04.05.2008 13:32
Сообщ.: 7 240,
Visits: 65 445
|
|
| В Synchronize надо передавать только имя метода. Параметры придется передавать как-то по другому. Например, через private поля класса.
|
|
|
|
|
Supreme Being
      
участник
Last Login: 12.06.2008 11:23
Сообщ.: 96,
Visits: 535
|
|
| Странно, но все равно не хочет работать Synchronize.. А что если через TThread сделать тоже самое? Вообще есть ли разница между CreateThread, BeginThread и классом TThread.
|
|
|
|
|
Supreme Being
модератор
Last Login: 04.05.2008 13:32
Сообщ.: 7 240,
Visits: 65 445
|
|
| Хорошая мысль. Я и не обратил внимание что ты WinAPI функцию CreateThread вызываешь. Работая в Delphi лучше всего использовать ее родные классы/методы, обращаясь к WinAPI только при реальной необходимости. Разница между CreateThread, BeginThread и классом TThread конечно же есть. CreateThread это функция WinAPI которая ничего не знает о VCL. В то же время BeginThread и TThread являются родными средствами VCL и делают дополнительную работу. Подробности смотри в документации. Я бы на твоем месте создал наследника от TThread.
|
|
|
|
|
Supreme Being
      
участник
Last Login: 12.06.2008 11:23
| | | |