Re[4]: Как в MFC заставить прорисовываться окна вовремя испо
От: BlackSpy  
Дата: 15.06.04 07:12
Оценка:
Здравствуйте, m16, Вы писали:

m16>Здравствуйте, Odi$$ey, Вы писали:


OE>>насчет отдельного потока тоже пожалуй облом, окно-то с ActiveX живет в интерфейсном потоке. Тут разве что перед началом загрузки выводить клиенту картинку и пусть себе расслабляется...


m16>Попробовал размесить загрузку в отдельную нить (AfxBeginThread), но при вызове функций ActiveX программа вылетает. Выглядит это забавно. По верх главного окна приложения отображено сообщение о фатальной ошибке с предложением закрыть программу при этом можно работать с меню.


m16>Пожалуйста, подскажите, в чем дело? Как с этим бороться?



Создай на основном окне чайлдовый диалог, и хость этот ActiveX на нем.
Причем создавай этот диалог в отдельном потоке. Тогда замирать будет только этот диалог, а основное окно будет спокойно жить. Дергать методы ActiveX-а можно будет только из этого отдельного потока. Поэтому садишься и пишеш враппер/врапперы: из основного UI-шного потока SendMessage-ми посылается сообщение диалогу, с которым ты передаешь инфу о том, какой метод нужно вызвать и параметры для вызова. Диалог в своем message pump ловит мессагу, дергает ActiveX и возвращает результат.
Re[9]: Как в MFC заставить прорисовываться окна вовремя испо
От: m16  
Дата: 16.06.04 14:28
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Вот пример. Можно и красивее, наверно.

RB>Есть диалог на MFC. На нем кнопка. По нажатию кнопки делаем следующее.

RB>
RB>#include <process.h>
RB>#include <atlbase.h>
RB>...........

RB>struct ThreadData
RB>{
RB>    CTestMFCDlg*    pDlg;
RB>    HANDLE            hEvent;
RB>};

RB>UINT __stdcall ThreadProc(void* lParam)
RB>{
RB>    ThreadData* pstData = (ThreadData*)lParam;
RB>    CTestMFCDlg* pDlg = pstData->pDlg;
RB>    HANDLE hEvent = pstData->hEvent;

RB>    CProgressCtrl ctrl;
RB>    ctrl.Create(WS_CHILD|WS_VISIBLE, CRect(10, 10, 100, 30), pDlg, 101);
RB>    ctrl.SetRange(0, 100);
RB>    ctrl.SetPos(0);

RB>    SetEvent(hEvent);

RB>    UINT nTimer = ctrl.SetTimer(1, 100, NULL);

RB>    MSG msg;
RB>    while (GetMessage(&msg, NULL, 0, 0))
RB>    {
RB>        if (WM_TIMER == msg.message && msg.wParam == nTimer)
RB>            ctrl.SetPos(ctrl.GetPos() + 1);
RB>        DispatchMessage(&msg);
RB>    }

RB>    ctrl.KillTimer(nTimer);
RB>    ctrl.DestroyWindow();

RB>    return 0;
RB>}

RB>void CTestMFCDlg::OnButton1() 
RB>{
RB>    ThreadData stData;
RB>    stData.pDlg = this;
RB>    stData.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

RB>    UINT nID;
RB>    HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, &stData, 0, &nID);

RB>    AtlWaitWithMessageLoop(stData.hEvent);
RB>    CloseHandle(stData.hEvent);

RB>    Sleep(10000);    //  мертвый код. Вызываем ActiveX

RB>    ::PostThreadMessage(nID, WM_QUIT, 0, 0);
RB>    AtlWaitWithMessageLoop(hThread);
RB>    CloseHandle(hThread);
RB>}
RB>


RB>ЗЫ

RB>atlbase нужна только для функции AtlWaitWithMessageLoop — ожидание с прокруткой сообщений. Ее можно просто скопировать себе и забыть об atlbase.


На параллельную нить я повесил прогрессбар.
Неожиданно всплыла такая проблема. В ситуации, когда времяемкую процедуру инициирует главное окно, то Прогрессбар рисуется, если же процедуру инициирует плавающая панель, то не прорисовывается, пока не будет выполнена процедура главного окна. Однако если перед этой времяемкой процедурой вставить messageBox, то Прогрессбар прорисовывается. Что делать?
Re[10]: Как в MFC заставить прорисовываться окна вовремя исп
От: rus blood Россия  
Дата: 16.06.04 14:56
Оценка:
Здравствуйте, m16, Вы писали:


RB>>
overquoting
RB>>



m16>На параллельную нить я повесил прогрессбар.

m16>Неожиданно всплыла такая проблема. В ситуации, когда времяемкую процедуру инициирует главное окно, то Прогрессбар рисуется, если же процедуру инициирует плавающая панель, то не прорисовывается, пока не будет выполнена процедура главного окна. Однако если перед этой времяемкой процедурой вставить messageBox, то Прогрессбар прорисовывается. Что делать?

Честно говоря не очень понятно, что значит "пока не будет выполнена процедура главного окна". Что за процедура?
И как вызывается MessageBox?

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

Смысл цикла сообщений в том, что при создании child окна оно взаимодействует с родительским — посылает ему сообщения. Если эти сообщения не обработать, вызов CreateWindowEx для child окна блокируется.

ЗЫ Может быть тебе лучше создать ActiveX-контрол в отдельном потоке? А в основной поток промаршалить его IDispatch, чтобы дергать методы. Тогда у тебя не будет "мерзнуть" весь UI приложения.
Имею скафандр — готов путешествовать!
Re[11]: Как в MFC заставить прорисовываться окна вовремя исп
От: m16  
Дата: 16.06.04 15:23
Оценка:
RB>Честно говоря не очень понятно, что значит "пока не будет выполнена процедура главного окна". Что за процедура?
RB>И как вызывается MessageBox?

Суть в следующем:
В ActiveX есть некоторое дерево элементов, эта процедура пробегается по нему и формирует Уже мое дерево. Проблема в том, что эта процедура вызывается из обработчика кнопки и соответственно блокирует цикл обработки сообщений главного окна надолго. Как разблокировать главный цикл?

Параллельные потоки не подходят…


RB>Смысл цикла сообщений в том, что при создании child окна оно взаимодействует с родительским — посылает ему сообщения. Если эти сообщения не обработать, вызов CreateWindowEx для child окна блокируется.


А можно поподробнее..
Re[12]: Как в MFC заставить прорисовываться окна вовремя исп
От: rus blood Россия  
Дата: 16.06.04 15:46
Оценка:
m16>Суть в следующем:
m16>В ActiveX есть некоторое дерево элементов, эта процедура пробегается по нему и формирует Уже мое дерево. Проблема в том, что эта процедура вызывается из обработчика кнопки и соответственно блокирует цикл обработки сообщений главного окна надолго. Как разблокировать главный цикл?

А эта процедура написана тобой? Или опять какой-то метод в ActiveX, который сам все делает?


RB>>Смысл цикла сообщений в том, что при создании child окна оно взаимодействует с родительским — посылает ему сообщения. Если эти сообщения не обработать, вызов CreateWindowEx для child окна блокируется.


m16>А можно поподробнее..


В приведенном примере основной поток вызывает крутит цикл сообщений и ждет сигнала от рабочего потока. Рабочий поток создает прогресс-бар и сигналит основному, что все ок. Если основной поток не будет крутит цикл сообщений и не будет ждать, пока прогресс-бар будет создан в рабочем потоке, то вызов функции Create для прогресс-бара блокируется.
Имею скафандр — готов путешествовать!
Re[13]: Как в MFC заставить прорисовываться окна вовремя исп
От: m16  
Дата: 17.06.04 06:52
Оценка:
RB>А эта процедура написана тобой? Или опять какой-то метод в ActiveX, который сам все делает?

Эта процедура написана мной. В ней содержится каскад циклов, в котором идет чтение данных из ActiveX
Re[14]: Как в MFC заставить прорисовываться окна вовремя исп
От: rus blood Россия  
Дата: 17.06.04 07:09
Оценка:
m16>Эта процедура написана мной. В ней содержится каскад циклов, в котором идет чтение данных из ActiveX

Тогда ответ тебе уже дан
Автор: Odi$$ey
Дата: 16.06.04
.
Вызывай эту функцию в каждой итерации каждого цикла.
Имею скафандр — готов путешествовать!
Re[13]: Как в MFC заставить прорисовываться окна вовремя исп
От: m16  
Дата: 17.06.04 07:42
Оценка:
RB>В приведенном примере основной поток вызывает крутит цикл сообщений и ждет сигнала от рабочего потока. Рабочий поток создает прогресс-бар и сигналит основному, что все ок. Если основной поток не будет крутит цикл сообщений и не будет ждать, пока прогресс-бар будет создан в рабочем потоке, то вызов функции Create для прогресс-бара блокируется.


Похоже, что так и есть. Вопрос только в том, почему если эту штуку повесить на открытие отчета, то все нормально, а если на фильтрацию, то create прогрессбара блокируется?
Почему вызов MessageBox в главном или рабочем прочесе оказывает такое магическое воздействие? Подскажите что делать?
Re[14]: Как в MFC заставить прорисовываться окна вовремя исп
От: rus blood Россия  
Дата: 17.06.04 10:02
Оценка:
Здравствуйте, m16, Вы писали:

RB>>В приведенном примере основной поток вызывает крутит цикл сообщений и ждет сигнала от рабочего потока. Рабочий поток создает прогресс-бар и сигналит основному, что все ок. Если основной поток не будет крутит цикл сообщений и не будет ждать, пока прогресс-бар будет создан в рабочем потоке, то вызов функции Create для прогресс-бара блокируется.



m16>Похоже, что так и есть. Вопрос только в том, почему если эту штуку повесить на открытие отчета, то все нормально, а если на фильтрацию, то create прогрессбара блокируется?

"Открытие отчета" и "фильтрация" — это методы ActiveX контрола?

m16>Почему вызов MessageBox в главном или рабочем прочесе оказывает такое магическое воздействие? Подскажите что делать?

MessageBox переводит поток в модальное состояние — крутит цикл сообщений внутри себя.
Имею скафандр — готов путешествовать!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.