Название: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: Caduceus от Сентябрь 02, 2009, 21:39 Все дело под Windows.
Есть формочка с кучей кнопок, контролов. И есть один виджет, который явлется просто указателем места, над которым я создаю свое окно. Причем окно это создается в другом потоке. Родитель этого окна - то что возвращает этот виджет через winId. Окно создает, все нормально работает. Но: все конролы на форме недоступны, то есть видны, но не нажимаются. И сразу после того, как я пытаюсь запустить Spy++, вываливается ошибка, что QAppication шлет евент объекту, созданному в другом потоке. Вот такая штука. Запустался уже. Что это может быть? Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Па Отправлено: Авварон от Сентябрь 02, 2009, 22:09 нельзя создавать окна в потоке, отличном от главного
Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: Caduceus от Сентябрь 02, 2009, 22:12 если я создаю окно в главном потоке, то весь цикл обработки его сообщений гасит вообще все - весь главный ГУИ просто умирает и не отрисовывается, не то что отвечать на нажатия
Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Па Отправлено: ufna от Сентябрь 02, 2009, 22:25 значит, нужно что то модифицировать. Опиши поподробней, что делает это окно.
Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: Caduceus от Сентябрь 02, 2009, 22:28 Это второе окно - прикрученный к Qt-шной проге игровой движок.
В нем все хорошо там крутиться. На события мыши и клавы реагирет. А вот Qt-шный GUI не нажимается. Более того, если внутрь второго окна не нажмать, то Qt-шное таскается и ресазиться, а если по второму окну кликнуть (там анимация проигрывается), то qt-ное окно перестает отвечать на сдивги за заголовок и ресайзы за уголки. Надо щелкнуть вообе на другуое приложние, потом щелкуть на qt-шное окно — и вот огда оно реагирует на перемещения и ресайзы, хотя контролы все равно не нажимаются Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: BlackTass от Сентябрь 03, 2009, 00:57 Почему бы не пробрасывать обработку в отдельный тред, откуда она тоже соответственно будет пробрасываться обратно на отрисовку?
Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: Caduceus от Сентябрь 03, 2009, 08:43 Все что касается этого нативного окна и так в отдельном потоке. Вопрос немного перефразирую - не отслеживает ли Qt все дочерние окна (даже если они не qt шные а наивные) и не рулит ли как-то их циклом обработки сообщений сам?
Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: Tonal от Сентябрь 03, 2009, 10:23 Я уже на rsdn-е ответил: во втором потоке нужен свой цикл выборки сообщений.
Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: Caduceus от Сентябрь 03, 2009, 10:44 Так там он, там. Во втором потоке
Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: BlackTass от Сентябрь 03, 2009, 11:11 если в главном потоке обработка событий сводится к эмитам и при этом умирает гуй, то сколько же там валится событий?
Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: Caduceus от Сентябрь 03, 2009, 11:16 Игровой движок, можно представить что там куча всего.
НО! есть одно НО. Я делал те же самые действия, то только через ActiveX - то есть я создавал ATLный ActiveX - в нем над окном Конрола создавал во втором потоке окно движка и ВСЕ суперско работало. Я кидал этот контрол на C#-ную форму и все зашибись Сейчас я это дело перевел на Qt - то есть создаю окно движка надQt виджетом - и все кроме движка засыпает... Продебажил конкретно вглубь Qt - при нажатии на конролы он даже в QtWndProc не заходит. Кто-то конкретно перехватывает это все дело. Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: BlackTass от Сентябрь 03, 2009, 13:40 там ваших собственных событий куча или каких? если ваших собственных смело кидайте их в другой поток да и все. У вас точно во втором потоке eventLoop работает в этом самом втором потоке, а не в гуевом?
Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: Caduceus от Сентябрь 03, 2009, 13:43 моих сообщений там вобще никаких нету. Цикл нативного окна 100% во втором потке.
Всё, уже не знаю куда копать. Все перепробовал Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: BlackTass от Сентябрь 03, 2009, 13:45 ну так как libastral и телепатия пока еще только развиваются, я думаю стоит выложить исходники (желательно обрезанные до самого минимума).
Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: Caduceus от Сентябрь 03, 2009, 14:01 О, получилось воспроизвести без игрового движка. Короче, есть наиримитвнейшая формочка с двумя кнопками и кастомным виджетом. При нажатии на кнопку кастомному виджету шлтеся сигнал. Вот функция слота:
Код: void EngineWidget::StartEngine() Примитивно? Примитивно. А сейчас вот самое интересное - потоковая функция threadFunc: Код: static DWORD WINAPI threadFunc(LPVOID pWidg) Во. Вот если так сделать - то все кнопки на qt-шной форме перестают нажиматься. Это я в очень приближенной форме написал как работает окно игрового движка. Разумеется там не DefWindowProc оконная функция, но и так уже виснет. Кто что думает? PS Предвижу сразу фразы типа "Ага, у тебя нативное окно прям поверх всего делается из угла окна - кординаты 0 -0". Отвечу - опускал я это окно, было оно точно под кнопками, то есть кнопки не перекрывало - но они все равно не нажимались Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: Caduceus от Сентябрь 03, 2009, 14:11 А вот как это выглядит с движком:
Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: Caduceus от Сентябрь 03, 2009, 21:48 Тот минимальныйпример что я привел никого на мысль не натолкнул?
Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: Tonal от Сентябрь 04, 2009, 08:28 Я как-то наткнулся на то, что если для окна не реализовать обработку WM_GETTEXT + WM_GETTEXTLEN, то любой кто попросит его имя - зависнит. :)
Например зависала функция FindWindow если не указан класс. Причём в любом приложении. :) Посмотри в исходники Qt/MFC Migration Framework (http://qt.nokia.com/products/appdev/add-on-products/catalog/4/Windows/qtwinmigrate/) Может поможет. Кстати, гугель, по запросу "winapi child window in other thread" выдал интересную ссылку: http://www.eggheadcafe.com/software/aspnet/33723942/childrenparent-window-in.aspx Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: Caduceus от Сентябрь 04, 2009, 08:56 Спасибо большое.
ОБработка WM_GETTEXT + WM_GETTEXTLEN ситуацию не изменило. А вот Ваша сссылка с Гугла оченно меня огорчила. Дело значит совсем не в Qt. Не понтяно тогда, почему если я это окно вешаю над ActiveX -ом, то все нормально... Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: Tonal от Сентябрь 04, 2009, 09:57 Про WM_GETTEXT я привёл просто для примера, не ожидая что они на что-нибудь повлияют.
По ссылке, вроде упоминали о каких-то обходных путях? Про ActiveX - точно не уверен, но, возможно там не настоящее дочернее окно - не даром протокол встраивания дублирует функции и события WinApi. В любом случае, MS туда очень много наворочили... Название: Re: Создаю свое окно, дочернее к qt-шному через CreateWindow в другом потоке. Падает Отправлено: Caduceus от Сентябрь 04, 2009, 10:08 Ураа, проблема решена. Видимо, если выносить окно в отделный поток, то гасится только цикл сообщений родителя этого кона в другом потоке. У меня сначала гасились все сообщения моего диалога, так как оно было родителем окна из второго потока. Выход из ситуации - сделать окно-заглушку в первом потоке и уже оно будет родителем окна во втором потке. То есть его цикл может и гасится - но пофигу становится. Именно поэтому у меня и работало с ActiveX-ом - там же ActiveX сам был этим окном-заглушкой.
И сейчас у меня полнофункциональная красота: |