Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > OnInitDialog() или где?


Автор: Blade 17.8.2002, 23:02
Необходимо сделать следующее: после того как появляется диалоговое окно, должен быть запущен модуль даунлоада, при этом должен ползти ползунок. Всё вроде просто, а проблема в следующем: при описании этого модуля в OnInitDialog() он запускается раньше, чем появляется диалоговое окно, т.е. сначало он завершит работу, затем окно появится. Кто знает, где нужно описать этот модуль?
Заранее спасибо.

Автор: suborg 17.8.2002, 23:22
сделай отдельным трэдом - вообще зашибись будет.
CreateThread почитай.
Или можешь на таймер повесить OnTimer() в методах диалога.

Автор: Blade 18.8.2002, 00:36
Почитал я в MSDN о CWinThread::CreateThread(...). Честно говоря, не очень понял, как им пользоваться. А по-поводу второго варианта, мне кажется это как-то неправильно, даже смешно. Всё равно спасибо.

Автор: Temnozor 19.8.2002, 17:22
Диалог всегда появляется после того, как завершается функция OnInitDialog(). Это своего рода конструктор диалога (хотя это не совсем так). Так что, если хочешь что-то увидеть расчеты/отрисовки должны быть в другой функции.

Автор: Seregy 19.8.2002, 19:23
AfxBeginThread

Пример дать или сам MSDN посмотришь? :)

Автор: Blade 19.8.2002, 22:26
В МСДНе посмотрел пример, но опять-таки не вьехал, почему в параметре AfxBeginThread передаём класс, в котором описан метод этого класса. Собственно у меня и задач, состоит только в том, чтобы как только появится окно, запустить метод этого самого класса, описывающего диалог.

Автор: suborg 19.8.2002, 22:47
Без потоков ничего не получится.
Дело в том, что когда ты из основного потока своей программы запускаешь какую либо свою функцию или метод, то весь поток утекает в эту функцию, и пока он обратно не вытечет, окно вообще не будет жить. Не будет перерисовываться, реагировать на клавиатуру и мышку и т.п. потому что функция обработки сообщений, приходящих в окно находится в том же потоке.
Поэтому чтобы выполнялась какая-то задача беспрерывная, а её статус выводился в окно, задача должна работать в отдельном потоке.
По-правильному надо, конечно, AfxBeginThread, но в принципе можно просто CreateThread. Выглядеть будет примерно так:

глобальная функция
DWORD WINAPI LThread(LPVOID lpParameter);

ля ля тополя, определили эту функцию и т.п., дальше внутри диалога:

DWORD lThread=0;
CreateThread(NULL,0,LThread,NULL,0,&lThread);

соответственно после CreateThread появится новый поток, который будет работать параллельно основному. Тут придется обратить внимание на синхронизацию потоков, завершение и т.п.

Автор: Blade 19.8.2002, 22:54
А не проще-ли к диалоговому окну привезать обработчик события, которое происходит, когда диалоговое окно показывается на экране. Кокое - не знаю. Перебрал кучу: и WM_CREATE и WM_SHOWWINDOW и т.д. Все почему-то происходят до того как, окно показывается на экране.   ???

Автор: Blade 19.8.2002, 22:57
Цитата(suborg @ 19.8.2002, 15:47)
Поэтому чтобы выполнялась какая-то задача беспрерывная, а её статус выводился в окно, задача должна работать в отдельном потоке.

Это не есть проблема, всё и так работает, только для этого нужно после появления диалога нажать кнопочку "Скачать" :) А мне нужно просто без кнопочки.

Автор: Temnozor 19.8.2002, 23:19
Цитата(Blade @ 19.8.2002, 17:57)
Цитата(suborg @ 19.8.2002, 15:47)
Поэтому чтобы выполнялась какая-то задача беспрерывная, а её статус выводился в окно, задача должна работать в отдельном потоке.

Это не есть проблема, всё и так работает, только для этого нужно после появления диалога нажать кнопочку "Скачать" :) А мне нужно просто без кнопочки.

Дак тогда пиши рабочий код вне класса диалога!
И сделай диалог с прогрессом закачки немодальным.

Автор: Grey 19.8.2002, 23:26
В конце обработчика WM_PAINT напиши, не ошибешься :)
Только без дополнительного процесса ползунок ползти
все равно не будет :)

Автор: Temnozor 19.8.2002, 23:28
И вообще не обязательно самому создавать отдельный поток. В MFC есть специальный класс CProgressCtrl. Сам заботится о перерисовке.

Автор: Temnozor 19.8.2002, 23:35
Цитата(Grey @ 19.8.2002, 18:26)
В конце обработчика WM_PAINT напиши, не ошибешься :)
Только без дополнительного процесса ползунок ползти
все равно не будет :)

Будет!
Пишешь RedrawWindow() и усе! Перерисует и обновит.

Автор: Grey 20.8.2002, 00:47
Не будет :)
Штука то, насколько я понял, примерно такая: в определенном событии диалога вызывается функция или компонент, не важно, которая качает файл и пока файл не скачаестся событие не завершится, поэтому диалог другие события обрабатывать не будет в том числе и WM_PAINT. А вот если скачивание работает в отдельном процессе, то оно может переодически сообщать тому же прогресу, что скачалось уже что-то. А сам по себе CProgressCtrl ничем не поможет.

Автор: Blade 20.8.2002, 02:11
Даже смешно, какая полемике разгорелась тут. Правда вот и выход нашёлся в конце концов. У меня всё заработало. Фишка была в следуёщем: во-первых я использовал класс CProgressCtrl, во-вторых качалось много небольших файлов, поэтому ползунок менялся по одному файлу, в третьех я просто не сообразил насчёт WM_PAINT'а :) В общем, огромное СПАСИБО всем, кто принимал участие в этих спорах и рассуждениях.  :hehe  :hehe  :hehe  :hehe  :hehe  :hehe

Автор: Temnozor 20.8.2002, 02:22
Когда поток вызывает RedrawWindow(), в тот же момент окно и обновляется.
Естественно, если поток стопорнулся на закачке файла, то и функцию он не вызовет.
Вообще, проблем быть не должно...

Автор: Blade 20.8.2002, 03:18
Да нету уже никаких проблем - всё ТИП-ТОП.  :thumbs-up

Автор: Blade 21.8.2002, 06:46
Возвращаясь к старому... Появилась новая прлоблема: из этого OnPaint'а дурацкого OnOK() хреново работает, выдаётся виндовская ошибка, правда диалог прячится. Каким образом избавиться от проблемки?  :0

Автор: Grey 21.8.2002, 17:21
Поподробнее про проблему, что за ошибка, пример кода в OnPaint и OnOk.

Автор: Baa 22.8.2002, 11:05
А чем вам OnActivate не понраился?

Автор: Grey 22.8.2002, 16:57
Может и понравится. Вопрос только в том срабытавыет ли оно при создании окна, помоему нет.

Автор: Blade 22.8.2002, 22:17
Цитата(Grey @ 21.8.2002, 10:21)
Поподробнее про проблему, что за ошибка, пример кода в OnPaint и OnOk.

Проблема в том, ччто внутри обработчика OnPaint(), OnOK() срабатывает только с выдачей ошибки(непонятной). Т.е. диалог закрывается, возвращает значение IDOK,но, при этом, вылетает ошибка.

Автор: Blade 22.8.2002, 22:20
Цитата(Baa @ 22.8.2002, )
А чем вам OnActivate не понраился?

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

Автор: Grey 23.8.2002, 00:00
Хорошо бы увидеть код.
А так могу только предположить, что ошибка происходить во время освобождения памяти диалогом, т.е. что-то криво дестроится.

Автор: Blade 23.8.2002, 01:44
Не в коде дело.
Код

OnPaint(...)
{
OnOK();
}

Ошибка виндовоза вылетает.

Автор: Grey 23.8.2002, 02:08
А если убрать и OnPaint этот вызов и закрывать диалог нажатием на кнопку ОК, что происходит?

Автор: Blade 23.8.2002, 02:41
Для начала кнопки OK там нет. Хотя если привезать OnOK() к какой-нибудь кнопке то всё в порядке. Вообще я полагаю, это типичная ситуация. Попробуй у себя на VC это сотворить. Думаю будет тот же эффект.

Автор: Grey 23.8.2002, 17:05
Все работает нормально, правда я шестой студии проверил.

Автор: Blade 24.8.2002, 20:58
Странно, а у меня во многих диалогах (но не во всех) тот же эффект, т.е. запускаю OnOK() в OnPaint(...) и, бац, ошибка. В чём всё-таки дело? :bored

Автор: Blade 25.8.2002, 17:02
:baaa Неужели никто ничего не знает?  :butbut Гляньте, пожалуйста.  :(

Автор: Blade 26.8.2002, 21:20
:baaa PLZZZZZZZZZZZZ :baaa

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)