Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.10.25;
Скачать: CL | DM;

Вниз

Запуск расчета сразу после отрисовки формы   Найти похожие ветки 

 
Franzy   (2009-09-01 13:43) [0]

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

Если пуск прописать в OnCreate, окошко не рисуется вообще до окончания расчета. В OnShow - окошко не активируется. Вставка form1.activate не помогает. Т.е. программа статует как бы в свернутом состоянии. Причем при этом "висит" и не разворачивается, несмотря на вставки Application.processmessages при каждом обновлении отчета.

Как это реализовать правильно?


 
clickmaker ©   (2009-09-01 13:48) [1]

> Как это реализовать правильно?

Запускать расчет в отдельном потоке. Тогда не суть важно, в каком событии.
Оповещать различные компоненты отчета о прогрессе расчета можно через PostMessage форме.


 
Franzy   (2009-09-01 13:50) [2]

Забыл уточнить: сами расчетные процедуры находятся в подключаемой dll.


 
Медвежонок Пятачок ©   (2009-09-01 13:50) [3]

и правильно что забыл. ибо уточнение лишнее.


 
Franzy   (2009-09-01 14:03) [4]

А еще варианты есть?


 
clickmaker ©   (2009-09-01 14:09) [5]

> А еще варианты есть?

Application.ProcessMessages в цикле расчета после очередной итерации.
А чем поток не устраивает?


 
sniknik ©   (2009-09-01 14:11) [6]

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


 
Медвежонок Пятачок ©   (2009-09-01 14:14) [7]

у него же уже колбаки вовсю прогресс расчета рисуют. чем не место для процессмессаджес?


 
Franzy   (2009-09-01 14:16) [8]

А внутри потока можно обращаться к объектам формы?


 
Медвежонок Пятачок ©   (2009-09-01 14:17) [9]

можно, если поток главный.


 
Franzy   (2009-09-01 14:22) [10]

Я так понимаю, проблема в том, что onCreate и onShow вызываются прямо ПЕРЕД тем, как окончатся соотв. процессы. А мне нужно ПОСЛЕ их окончания :( Похоже, придется использовать треды. Кстати, сразу вопрос по ним: можно ли обращаться внутри треда к элементам формы (если я объвлю класс треда внутри модуля формы)?


 
Медвежонок Пятачок ©   (2009-09-01 14:26) [11]

если я объвлю класс треда внутри модуля формы)?

Модуль формы - понятие времени написания программы.
После F9 никаких модулей уже нет и нет разницы где задекларирован класс потока.


 
Сергей М. ©   (2009-09-01 14:29) [12]


> Franzy   (01.09.09 14:22) [10]



> мне нужно ПОСЛЕ их окончания


Просто создавай форму ПОСЛЕ их окончания.


 
Медвежонок Пятачок ©   (2009-09-01 14:29) [13]

Автор, в обработчике OnCreate посылай сам себе сообщение c помощью postmessage

в обработчике сообщения все уже будет отрисовано. в нем и запускай свои мега-расчеты.


 
Сергей М. ©   (2009-09-01 14:31) [14]


> можно ли обращаться внутри треда к элементам формы


Это смотря что ты подразумеваешь под "элементами формы"


 
Franzy   (2009-09-01 14:41) [15]

Я хочу разобраться с тредами, мне это может пригодиться в других приложениях :)

Сделал через треды так:


unit Main;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, Math;

type
 TForm1 = class(TForm)
 .....
 end;

 TMyThread = class(TThread)
 private
   { Private declarations }
 protected
   procedure Execute; override;
 end;

var
 Form1: TForm1;
 GridThread : TMyThread;

///////////////////////////////  

implementation

{$R *.dfm}

.......

procedure TMyThread.Execute;
begin

....

end;

procedure TForm1.FormCreate(Sender: TObject);
begin

 GridThread:=TMyThread.Create(false);
 GridThread.Execute;

end;

end.


Вылетает с ошибкой "Canvas does not allow drawing"


 
Медвежонок Пятачок ©   (2009-09-01 14:45) [16]

Это очень мудро, привести здесь весь код, а тот который имеет отношение к ошибке заменить многоточием


 
Franzy   (2009-09-01 14:46) [17]

Сделал тестовое приложение, в котором только тред, меняющий капшн формы - все работает нормально, ошибки нет. Может быть, дело в том, что из треда у меня вызывается процедура длл, которая вызывает коллбэк, который находится внутри основной программы?


 
Franzy   (2009-09-01 14:46) [18]


> Это очень мудро, привести здесь весь код, а тот который
> имеет отношение к ошибке заменить многоточием


Там не один десяток страниц :(


 
Anatoly Podgoretsky ©   (2009-09-01 14:47) [19]

> Franzy  (01.09.2009 14:41:15)  [15]

GridThread.Execute; запускай в отдельном методе, после начальных обработчиков.


 
Медвежонок Пятачок ©   (2009-09-01 14:48) [20]

Там не один десяток страниц :(

Может тебе и ответы давать многоточием?
:)))


 
Franzy   (2009-09-01 14:49) [21]

Закомментиовал коллбэк (в смысле, функция теперь ничего не делает), но ошибка все равно выскакивает.


 
Медвежонок Пятачок ©   (2009-09-01 14:50) [22]

Сделал тестовое приложение, в котором только тред, меняющий капшн формы - все работает нормально, ошибки нет.

мало тредов потому и нет. а еще просто потому нет потому что повезло.

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


 
Медвежонок Пятачок ©   (2009-09-01 14:52) [23]

но ошибка все равно выскакивает.

в [9] можно узнать почему это происходит.


 
Franzy   (2009-09-01 14:54) [24]


> GridThread.Execute; запускай в отдельном методе, после начальных
> обработчиков.


Вот такой код прекрасно работает:


unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs;

type
 TForm1 = class(TForm)
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

 TMyThread = class(TThread)
 private
   { Private declarations }
 protected
   procedure Execute; override;
 end;

var
 Form1: TForm1;
 MyThread: TMyThread;

implementation

{$R *.dfm}

procedure TMyThread.Execute;
begin
 form1.caption:="Hello World";
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 MyThread:=TMyThread.create(false);
 MyThread.Execute;
end;

end.


 
clickmaker ©   (2009-09-01 14:55) [25]

> GridThread.Execute;

это не нужно.
если параметр в конструкторе false, он сразу запустится.
если true, то после установки свойств треда нужно вызвать Resume


 
Медвежонок Пятачок ©   (2009-09-01 14:56) [26]

ну так и используй его. а тот код,  что с ошибкой сотри.


 
clickmaker ©   (2009-09-01 14:57) [27]

> Вот такой код прекрасно работает

потому что ты просто запустил метод Execute явно и в основном потоке. Смысла отдельного потока здесь теряется. С таким же успехом это мог быть TSomeObject.Execute


 
Franzy   (2009-09-01 14:57) [28]

Объясните, тогда как правильно, я не понимаю и хочу разобраться. В справке все очень кратко, только про Synchronize что-то упоминается.


 
Franzy   (2009-09-01 15:05) [29]

Ага, ошибка появляется, если внутри execute использовать ShowMessage! Почему так?


 
Медвежонок Пятачок ©   (2009-09-01 15:27) [30]

у попа была собака, он ее любил ....


 
Franzy   (2009-09-01 15:36) [31]

2Медвежонок Пятачок
Если не можете ничего сказать по существу, не флеймите, пожалуйста, для этого, кажется, есть отдельный подфорум. У меня есть реальная проблема и я хочу с ней разобраться.


 
clickmaker ©   (2009-09-01 15:36) [32]

> Почему так?

потому что
When you use objects from the class hierarchy, their properties and methods are not guaranteed to be thread-safe. That is, accessing properties or executing methods may perform some actions that use memory which is not protected from the actions of other threads.

Если уж сильно приспичило показать сообщение в потоке, используй апишную MessageBox()


 
Amoeba ©   (2009-09-01 15:37) [33]


> только про Synchronize что-то упоминается.

Вот-вот! И не просто так упоминается! И не только в справке, а также и в тексте, который автоматически генерируется при создании модуля потока.


 
Franzy   (2009-09-01 15:41) [34]

2sniknik

Вариант с postmessage самому себе сработал, спасибо.

Хотя с тредами по-прежнему не понятно :(


 
Leonid Troyanovsky ©   (2009-09-01 15:44) [35]


> Franzy   (01.09.09 15:36) [31]

>  У меня есть реальная проблема и я хочу с ней разобраться.

Проблема не одна.
В dll от Synchronize практической пользы нет.

--
Regards, LVT.


 
sniknik ©   (2009-09-01 15:45) [36]

> мало тредов потому и нет. а еще просто потому нет потому что повезло.
и еще потому, что каптион присваивается посылкой сообщения (WM_SETTEXT), т.е. код с ним вообще не показатель.


 
Юрий Зотов ©   (2009-09-01 15:50) [37]

> Franzy   (01.09.09 15:05) [29]

1. Расчет запускаете в отдельном потоке из OnShow главной формы. При создании объекта TMyThread форма передает ему свой хэндл и тот запоминает полученный хэндл в своем поле с именем MainFormHandle.

2 Определяете структуру данных, которые поток будет передавать форме, например:
type
 TMyData = record
   data1: integer;
   data2: string[255];
   ...
 end;
 PMyData = ^TMyData;


3. В секции interface модуля потока определяете сообщение для передачи данных:
const
 WM_UserPlus100 = WM_USER + 100;


4. Метод Execute потока:
procedure TMyThread.Execute;
var
 MyData : TMyData;
begin
 while not Terminated do
 begin
   MyData.data1 := ...;
   MyData.data2 := ...;
   ...
   PostMessage(MainFormHandle, WM_UserPlus100, @MyData, 0);
   ... // Здесь выполняем шаг расчета
 end
end;


5. В секции protected формы делаете метод:
procedure WMUserPlus100(var Message: TMessage); message WM_UserPlus100;
и реализуете этот метод:
procedure TForm1.WMUserPlus100(var Message: TMessage);
begin
 inherited;
 with PMyData(Message.WParam)^ do
 begin
   ProgressBar1.Position := data1;
   Edit1.Test := data2;
   ...
 end
end;


 
Franzy   (2009-09-01 15:56) [38]

2clickmaker
А, т.е. они имели ввиду class hierarchy в широком смысле, т.е. вообще все объекты и контролы? Я просто так понял, что речь идет об объектах, которые одновременно используются в разных потоках. Ясно. Т.е. нужно избегать прямого обращения к свойствам и методам объектов, а вместо это использовать WinAPI и мессаджи?


 
Franzy   (2009-09-01 15:59) [39]


> Расчет запускаете в отдельном потоке из OnShow главной формы


А при этом расчет не будет перезапускаться каждый раз, когда окно сворачивается на панель задач и затем разворачивается?


 
Amoeba ©   (2009-09-01 16:01) [40]

http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1370



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

Текущий архив: 2009.10.25;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.014 c
2-1251902073
Merlin_88
2009-09-02 18:34
2009.10.25
Помогите с Классами


15-1250592835
abun
2009-08-18 14:53
2009.10.25
Backdoor.Hupigon.bnln и Heuristic.BehavesLike.Win32.O - что это??


2-1251814973
Del
2009-09-01 18:22
2009.10.25
BDS 2006 hint


2-1251817288
EH
2009-09-01 19:01
2009.10.25
Скрыть ячейки StringGrid


15-1250935575
El
2009-08-22 14:06
2009.10.25
Предварительный просмотр сообщения