Создание дочернего окна из потока (WTL)
От: Charniauski_Pavel  
Дата: 29.05.06 08:57
Оценка:
Добрый день всем.

Во время написания проекта столкнулся с проблемой, сам которую решить пока не могу.

Суть проблемы:

есть окно, в которое выводится видеосигнал с любого источника. Поверх этого окошка необходимо выводить другое, которое будет отобраджать строку некоторого содержания в течение скажем 5 секунд, затем оконко уничтожается.

Окошко со строкой выводится по HTTP запросу, тоесть его вызов не статический, а в какие-либо прмежутки времени. Причём таких окошек может быть много, единственное ограничение — размеры окна-родителя.

Мое решение состояло из объекта-менеджера потоков, ссылка на который имелась в объекте окна-родителя. Менеджер-потоков получал строку по HTTP и на основе её содержания создавал поток, который отображал бы окошко. Менеджер следил за количество созданных потоков (окошек).

Текст в окошке прорисовывалмя с помощью GDI+

Проблема оказалась в том, что при создании окошка из потока, оно не получет карту сообщений, а следовательно я не могу обработать WM_PAINT. Причём "валится" окошко в методе OnCreate() в блоке:

CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT(pLoop != NULL); ( !!! ТУТ !!! )
pLoop->AddMessageFilter(this);
pLoop->AddIdleHandler(this);

Пробовал передавать ссылку на CMessageLoop прямо в поток, никакого результата.

Что не так? Может кто уже сталкивался.

Есть одно предположение: у меня SDI проект без выставленного флага Multithreading.
Если это действительно оно, то может кто подскажет, как быстро перевести проект на поддержку multithreading.

Заранее благодарен всем откликнувшимся.
Re: Создание дочернего окна из потока (WTL)
От: Edge  
Дата: 28.07.06 07:17
Оценка:
Здравствуйте, Charniauski_Pavel, Вы писали:

C_P>Проблема оказалась в том, что при создании окошка из потока, оно не получет карту сообщений, а следовательно я не могу обработать WM_PAINT. Причём "валится" окошко в методе OnCreate() в блоке:


C_P>CMessageLoop* pLoop = _Module.GetMessageLoop();

C_P>ATLASSERT(pLoop != NULL); ( !!! ТУТ !!! )
C_P>pLoop->AddMessageFilter(this);
C_P>pLoop->AddIdleHandler(this);

C_P>Пробовал передавать ссылку на CMessageLoop прямо в поток, никакого результата.


C_P>Что не так? Может кто уже сталкивался.


В потоке где создается окно, уже должен быть создан объект класса CMessageLoop и добавлен в _Module. Вот например код, который генерится WTL визардом:


int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT)
{
    CMessageLoop theLoop;
    _Module.AddMessageLoop(&theLoop);
.,,
.,,
}
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
...
...
...
    hRes = _Module.Init(NULL, hInstance);
...
    int nRet = Run(lpstrCmdLine, nCmdShow);
...
    _Module.Term();
...
...
...
    return nRet;
}


Как видно, в основном потоке создается theLoop и добавляется в _Module, после чего диалог спокойно может звать _Module.GetMessageLoop. Без этого _Module не будет знать, что у вас в конкретном потоке есть обработка сообщений.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.