![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
формы, потоки и TWebBrowser [D7]
HikTronic © (2010-07-05 09:47:00)первый вопрос такой - пишу прогу консольную, создаю окно через winapi, инициализирую в нем огл, и мне надо в месте с параллельно отрисовкой окна и выполнением в ней вычислений отображать форму, которая не стопорила бы эту прогу.
пробовал через потоки делать
//основная программа
CreateWND(true); // Создание окна
GLInit; // Инициализация Ogl'a
Looker:=TLooker.Create(false);
Looker.FreeOnTerminate:=true;
Looker.Priority:=tpLowest;
while Done=FALSE do цикл программы...
//TLooker.Execute:
Application.Initialize;
Application.CreateForm(TForm1, Form1);
logWrite('CreateForm',3); Application.Run;
Form1.Visible:=true;
Form1.Visible:=false;
но зависает и приложение и форма, по логу видно, что доходит до Onshow и все, дальше никак. подскажите, как решить?
и еще такой вопрос - у TWebBrowser можно ли управлять полосой прокрутки?
например, чтобы полоса прокрутки в определённый момент вставала в крайнее нижнее положение
Deltas (2010-07-06 03:00:00) [21]
> form1:=Tform1.Create(nil);
> form1.Show;
> while Done=FALSE do sleep(10);
Вот это к чему вообще? Окно будет отображено и после этого оконная функция не обработает ни одного сообщения. Поток практически засыпает навсегда.
В первом случае у Вас цикл занимает все процессорное время, во втором случае пустой цикл просто "вешает" программу.
Еще раз повторяю, отрисовку нужно выполнять в оконной процедуре, обрабатывая сообщение WM_PAINT. У Вас в первом цикле сообщение WM_PAINT обрабатывает DefWindowProc(). Функция ничего не рисует, все что она делает это просто утверждает область обновления окна (validates the update region). Кстати, окно вообще не будет получать сообщения WM_PAINT, потому что оно отправляется системой окну только тогда, когда область обновления не пуста, а она у Вас пуста (хотя это зависит от того, как Вы реализовали свою процедуру Draw()). Для того, чтобы ее сделать не пустой, необходимо вызывать InvalidateRect() или InvalidateRgn().
sniknik (2010-07-06 02:14:00) [22]> while Done=FALSE do sleep(10);
>
> то все равно все встает в тот же момент, что и раньше
и где здесь выборка сообщений? так чему удивляться, "встает" правильно, там где остановил.
хочешь обойтись без VCL? пиши ему замену. в смысле изучи как работает, попробуй на нем, и пиши свое...
HikTronic (2010-07-05 20:36:00) [23]думаю, что проблема все таки не в этом, потому что если сделать
form1:=Tform1.Create(nil);
form1.Show;
while Done=FALSE do sleep(10);
то все равно все встает в тот же момент, что и раньше
Deltas (2010-07-05 20:06:00) [24]Если нужна постоянная смена кадров в клиентской области окна, определите какая частота кадров вам нужна, установите таймер SetTimer() и по таймеру отрисовывайте новое изображение в окне, предварительно подготавливая его в оперативной памяти, пока в очереди нет сообщений.
Deltas (2010-07-05 20:02:00) [25]У Вас поток отнимает все процессорное время, если только, конечно, Вы не вызываете Sleep() или прочие функции Win API, переводящие поток в режим ожидания, внутри процедур Draw() и Phys(), что очень врядли. WM_PAINT имеет низкий приоритет обработки по сравнению с другими сообщениями, и ему просто некогда обрабатываться.
> разве причина в этом?
Есть только один способ узнать - проверить.
HikTronic (2010-07-05 19:41:00) [26]2Deltas:
разве причина в этом?
Deltas (2010-07-05 19:24:00) [27]А загрузку процессора не смотрели? Не удивлюсь, если 100%. Сравните функции PeekMessage() и GetMessage(). Отрисовку нужно выполнять в оконной процедуре, обрабатывая сообщение WM_PAINT.
HikTronic (2010-07-05 19:09:00) [28]я окно инициализирую средствами winApi, хочу быть как можно меньше привязан к делфи.
while Done=FALSE do
if (PeekMessage(msg, 0, 0, 0, PM_REMOVE)) then
begin
if Msg.message=WM_QUIT then Done:=TRUE;
TranslateMessage(Msg);
DispatchMessage(Msg);
end
else
begin
if forDraw then Draw;
Phys;
end;
в процедурах Draw и Phys идет отрисовка огл и рассчет физики соответственно.
обработка:
case msg of
WM_CLOSE : PostQuitMessage(0); // Auee??aiea ieia
WM_SIZE : if forLoad then ResizeWnd(LOWORD(lParam),HIWORD(lParam)); // Eciaiaiea ?acia?a
WM_KEYDOWN:keys[wParam]:= TRUE;
WM_KEYUP :
begin
keys[wParam]:= FALSE;
keysD[wParam]:= FALSE;
keysHold[wParam]:= FALSE;
end;
else Result:=DefWindowProc(Wnd,Msg,wParam,LParam);
Deltas (2010-07-05 18:52:00) [29]Хотелось бы посмотреть на Ваш "цикл программы" и как Вы организовали обработку сообщений из очереди главного потока.
И не понятно, почему в [0] сказано про Win API, когда работа с окнами выполняется с помощью VCL.
HikTronic (2010-07-05 18:48:00) [30]сделал перед основным циклом
form1:=Tfrom1.Create(nil);
form1.Show;
опять зависло на form1.Show;
Deltas (2010-07-05 18:45:00) [31]
> stas © (05.07.10 17:34) [4]
> если сделать form.show, то основной поток будет продолжать
> работу.
> если form.ShowModal, то остановиится, до закрытия формы.
Полный бред. Главный поток продолжает работать, при чем все окна (в том числе не модальные) продолжают обрабатывать сообщения.
stas (2010-07-05 17:37:00) [32]да и наверное можно обойтись без Application.
А просто
form1:=Tfrom1.Create(nil);
form1.Show;
stas (2010-07-05 17:34:00) [33]если сделать form.show, то основной поток будет продолжать работу.
если form.ShowModal, то остановиится, до закрытия формы.
HikTronic (2010-07-05 17:29:00) [34]но тогда ведь весь основной поток остановиться до того момента, когда форма не будет закрыта, нет? просто я раньше с формами не работал, только с консольными приложениями
stas (2010-07-05 16:50:00) [35]...и отображена тоже.
stas (2010-07-05 16:48:00) [36]Форма должна быть создана в основном потоке.