![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Запуск расчета сразу после отрисовки формы
Franzy © (2009-09-01 13:43:00)Есть программа, выполняющая некий трудоемкий расчет. Нужно, чтобы расчет начинался сразу после запуска программы, при этом окно программы должно быть активировано, т.е. в фокусе и поверх остальных окон, т.к. на форму в соотв. оконшки выводятся различные компоненты отчета о прогрессе расчета.
Если пуск прописать в OnCreate, окошко не рисуется вообще до окончания расчета. В OnShow - окошко не активируется. Вставка form1.activate не помогает. Т.е. программа статует как бы в свернутом состоянии. Причем при этом "висит" и не разворачивается, несмотря на вставки Application.processmessages при каждом обновлении отчета.
Как это реализовать правильно?
Leonid Troyanovsky (2009-09-01 17:48:00) [1]
> Franzy (01.09.09 16:18) [44]
> Так, с потоками разобрался, кажется, спасибо. Я правильно
> понял, что "главный поток" - это само приложение
MainThreadId - идентификатор первичного потока, т.е., того, что
создает CreateProcess и возвращает в PROCESS_INFORMATION structure.
Для обычных дельфийский приложений он же и VCL thread.
--
Regards, LVT.
oldman (2009-09-01 16:27:00) [2]
> Franzy (01.09.09 13:43)
Будь проще.
Запусти нужный тебе расчет в отдельном потоке из TTimer.
При запуске потока дизабли таймер.
Форма отрисуется, будет активной, поток пойдет.
Время старта таймера поставь опытным путем.
Franzy (2009-09-01 16:18:00) [3]Так, с потоками разобрался, кажется, спасибо. Я правильно понял, что "главный поток" - это само приложение, в котором все эти треды объявляются?
Но сделал все через отправку сообщения самому себе :) Там мороки существенно меньше.
Leonid Troyanovsky (2009-09-01 16:15:00) [4]
> sniknik © (01.09.09 15:45) [36]
> каптион присваивается посылкой сообщения (WM_SETTEXT),
А там не SendMessage, but Perform, так что и с заголовком не все чисто.
--
Regards, LVT.
clickmaker (2009-09-01 16:15:00) [5]> Т.е. нужно избегать прямого обращения к свойствам и методам
> объектов, а вместо это использовать WinAPI и мессаджи?
в не главных потоках, и смотря, к каким методам и свойствам. К тем, которые затрагивают vcl-ную часть UI - да.
Юрий Зотов (2009-09-01 16:11:00) [6]> Franzy (01.09.09 15:59) [39]
> А при этом расчет не будет перезапускаться каждый раз, когда
> окно сворачивается на панель задач и затем разворачивается?
Не будет. Событие OnShow возникает, когда свойство Visible формы меняется и становится равным True. Вы же не собираетесь "моргать" главной формой, насколько я понимаю?
:o)
Amoeba (2009-09-01 16:01:00) [7]http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1370
Franzy (2009-09-01 15:59:00) [8]
> Расчет запускаете в отдельном потоке из OnShow главной формы
А при этом расчет не будет перезапускаться каждый раз, когда окно сворачивается на панель задач и затем разворачивается?
Franzy (2009-09-01 15:56:00) [9]2clickmaker
А, т.е. они имели ввиду class hierarchy в широком смысле, т.е. вообще все объекты и контролы? Я просто так понял, что речь идет об объектах, которые одновременно используются в разных потоках. Ясно. Т.е. нужно избегать прямого обращения к свойствам и методам объектов, а вместо это использовать WinAPI и мессаджи?
Юрий Зотов (2009-09-01 15:50:00) [10]> 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;
sniknik (2009-09-01 15:45:00) [11]> мало тредов потому и нет. а еще просто потому нет потому что повезло.
и еще потому, что каптион присваивается посылкой сообщения (WM_SETTEXT), т.е. код с ним вообще не показатель.
Leonid Troyanovsky (2009-09-01 15:44:00) [12]
> Franzy (01.09.09 15:36) [31]
> У меня есть реальная проблема и я хочу с ней разобраться.
Проблема не одна.
В dll от Synchronize практической пользы нет.
--
Regards, LVT.
Franzy (2009-09-01 15:41:00) [13]2sniknik
Вариант с postmessage самому себе сработал, спасибо.
Хотя с тредами по-прежнему не понятно :(
Amoeba (2009-09-01 15:37:00) [14]
> только про Synchronize что-то упоминается.
Вот-вот! И не просто так упоминается! И не только в справке, а также и в тексте, который автоматически генерируется при создании модуля потока.
clickmaker (2009-09-01 15:36:00) [15]> Почему так?
потому что
When you use objects from the class hierarchy, their properties and methods a re 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()
Franzy (2009-09-01 15:36:00) [16]2Медвежонок Пятачок
Если не можете ничего сказать по существу, не флеймите, пожалуйста, для этого, кажется, есть отдельный подфорум. У меня есть реальная проблема и я хочу с ней разобраться.
Медвежонок Пятачок (2009-09-01 15:27:00) [17]у попа была собака, он ее любил ....
Franzy (2009-09-01 15:05:00) [18]Ага, ошибка появляется, если внутри execute использовать ShowMessage! Почему так?
clickmaker (2009-09-01 14:57:00) [19]> Вот такой код прекрасно работает
потому что ты просто запустил метод Execute явно и в основном потоке. Смысла отдельного потока здесь теряется. С таким же успехом это мог быть TSomeObject.Execute
Franzy (2009-09-01 14:57:00) [20]Объясните, тогда как правильно, я не понимаю и хочу разобраться. В справке все очень кратко, только про Synchronize что-то упоминается.