Qt setParent (WinAPI) |
Здравствуйте, гость ( Вход | Регистрация )
Qt setParent (WinAPI) |
Гость_Andrey_* |
24.11.2010, 1:09
Сообщение
#1
|
Гости |
Есть такая проблема. Внедрил main form qt приложения в vcl mdi форму сишного приложения средствами Win API. Все отлично внедрилось, отрисовка работает, клавиатурные события обрабатываются, но мышь...
Вобщем qt форма продолжает использовать глобальные координаты вместо локальных. При этом весьма странное дело, какие то виджеты используют локальные координаты и ведут себя нормально, а какие глобальные и гонят... Че токо не пробовал со стороны сишного приложения чтобы исправить дело (средствами winapi), но ниче не помогает. Видимо придется менять в qt части (код доступен), вот только с чего начать не знаю. Какие будут предложения коллеги Забегая вперед скажу что пенести все в одну среду пока не вариант. Каждая составляющая 10000яч строк кода и написана разными людьми, так что пока нет возможности собрать все в кучу. |
|
|
Алексей1153 |
24.11.2010, 8:03
Сообщение
#2
|
фрилансер Группа: Участник Сообщений: 2941 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: 34 |
какие то виджеты используют локальные координаты и ведут себя нормально, а какие глобальные и гонят... а зависимость улавливается ? Или это всё случайно происходит. И как узнал, что координаты используются глобальные ? Может быть, ты просто пересчитываешь в самом виджете их некорректно Сообщение отредактировал Алексей1153 - 24.11.2010, 8:04 |
|
|
Гость_Andrey_* |
24.11.2010, 11:15
Сообщение
#3
|
Гости |
какие то виджеты используют локальные координаты и ведут себя нормально, а какие глобальные и гонят... а зависимость улавливается ? Или это всё случайно происходит. И как узнал, что координаты используются глобальные ? Может быть, ты просто пересчитываешь в самом виджете их некорректно Есть такая зависимость. Объекты которые лежат на floating window (прицепленное к форме qt) обрабатываются некокрректно. Сцена вроде работает. Есть еще splitter тоже работает корректно. Видимо закономерность есть. А узнал просто окно qt прицеплено к mdi форме моего приложения. координаты 0,0. Соотвественно если пододвинуть mdi окно к глобальный x=0 и y смещенный на ширину заголовка main window+menu+заголовок mdi window то в списке дереве выбирается элемент смещенный на этот глобальный y, а не тот что под мышью. Те такое чувство что глобальные координаты не пересчитываются в локальные. В некоторых виджетах действительно некоретно мной считается("самопальные"), те корректно если предполагать что qt window overllaped а не child. но события клика на стандартных виджетах обрабатываются qt а не мной. курил qtwincontrol там тот же winapi и тотже setparent. есть конечно еще хуки на системные события типа tab и выход на системное меню, но это уже другой вопрос. единственное что форма qt после создания сразу определябтся как child и только потом крепяться виджеты, а у меня уже после всего конструктора. |
|
|
Алексей1153 |
24.11.2010, 11:55
Сообщение
#4
|
фрилансер Группа: Участник Сообщений: 2941 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: 34 |
В винде есть такой прикол (случай из MFC, но он тем более показателен, так как тут классы, в отличие от чистого Си в АПИ) - в конструкторе класса окна хендл ещё не создан, поэтому дочерние окна оказываются в свободном полёте. Выхода два:
1) создавать дочерние после конструктора (WM_INITDIALOG или MFC::CView::OnInitDialog, или MFC::CDialog::OnInitialUpdate , либо в любой другой удобный момент) 2) после создания хендла окна задать родителя дочерям заново (в том же WM_INITDIALOG ) PS Конечно же, если использовался чистый WinAPI, то всё это неактуально, разве что был передан нулевой хендл в качестве родителя Сообщение отредактировал Алексей1153 - 24.11.2010, 13:27 |
|
|
sadhu |
24.11.2010, 15:18
Сообщение
#5
|
Новичок Группа: Новичок Сообщений: 9 Регистрация: 22.11.2010 Пользователь №: 2209 Спасибо сказали: 0 раз(а) Репутация: 0 |
Вот здесь nokia держит проект qt-solutions, его частью яввляеться QtMfc migration toolkit (папка winmigrate) и пусть упопинание MFC никого не смущает, потому что, с любыми winApi приложениями оно дружит ни разу не меньше.
Там имеються примеры и документация так что в деталях описывать не буду, упомяну только что иееться возможность без всяких плясок с бубном и извращений использовать большинство Qt кода из WinApi приложений и у меня эта вещь пока не вызывала никаких нареканий, по крайней мере сложные окна типа QWebWiew вставляються без каких либо проблем. P.S. Если уже используешь этот тулкит, то попробуй отписаться разработчикам. |
|
|
Гость_Andrey_* |
24.11.2010, 19:58
Сообщение
#6
|
Гости |
Вот здесь nokia держит проект qt-solutions, его частью яввляеться QtMfc migration toolkit (папка winmigrate) и пусть упопинание MFC никого не смущает, потому что, с любыми winApi приложениями оно дружит ни разу не меньше. Там имеються примеры и документация так что в деталях описывать не буду, упомяну только что иееться возможность без всяких плясок с бубном и извращений использовать большинство Qt кода из WinApi приложений и у меня эта вещь пока не вызывала никаких нареканий, по крайней мере сложные окна типа QWebWiew вставляються без каких либо проблем. P.S. Если уже используешь этот тулкит, то попробуй отписаться разработчикам. Спасибо QWinWidget дейстивтельно решил проблему при прямом использовании. Будет значит он... но тем не менее для меня осталось загадкой почему через него пошло а на чистом winapi нет. те если посмотреть его код и выбросить пляски вокруг фокуса (почти все его методы именно для этого). то там ничего такого нет. только смутило вот что (идет следом за setparent winapi) QEvent e(QEvent::EmbeddingControl); QApplication::sendEvent(this, &e); кто нить знает че за событие такое. похоже что корень моей проблемы был именно в этом... |
|
|
Гость_Andrey_* |
24.11.2010, 20:08
Сообщение
#7
|
Гости |
В винде есть такой прикол (случай из MFC, но он тем более показателен, так как тут классы, в отличие от чистого Си в АПИ) - в конструкторе класса окна хендл ещё не создан, поэтому дочерние окна оказываются в свободном полёте. Выхода два: 1) создавать дочерние после конструктора (WM_INITDIALOG или MFC::CView::OnInitDialog, или MFC::CDialog::OnInitialUpdate , либо в любой другой удобный момент) 2) после создания хендла окна задать родителя дочерям заново (в том же WM_INITDIALOG ) PS Конечно же, если использовался чистый WinAPI, то всё это неактуально, разве что был передан нулевой хендл в качестве родителя Для встройки в MFC использовался чистый winapi уже в созданное окно с известным хендлом. делалось по нажатию на кнопку например. И встроилось все корректно и события qt работали корректно, единственное была проблма только с мышью.... Пост выше. Проблема решилась, но мне интересна суть проблемы, точнее что именно решило проблему. Ну и видимо можно сразу сказать что извне qt приложения его окно встроитть нормально не получиться. А жаль, на многих других приложениях все это работает на ура... |
|
|
Алексей1153 |
24.11.2010, 21:09
Сообщение
#8
|
фрилансер Группа: Участник Сообщений: 2941 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: 34 |
MFC никого не смущает, потому что, с любыми winApi приложениями оно дружит ни разу не меньше. ибо это практически одно и то же Только с классами использовался чистый winapi уже в созданное окно с известным хендлом. делалось по нажатию на кнопку например. И встроилось все корректно и события qt работали корректно, единственное была проблма только с мышью.... в отладчике можно глянуть, как путешествует координата. В оконной процедуре для сообщений WM_*BUTTON* Цитата (http://msdn.microsoft.com/en-us/library/ms645607(VS.85).aspx) lParam The low-order word specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area. The high-order word specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area. и ты дальше перекидывал координаты без изменений? Вот и будет косяк. Примени MapWindowPoints http://msdn.microsoft.com/en-us/library/dd145046(VS.85).aspx |
|
|
Гость_Andrey_* |
24.11.2010, 23:41
Сообщение
#9
|
Гости |
MFC никого не смущает, потому что, с любыми winApi приложениями оно дружит ни разу не меньше. ибо это практически одно и то же Только с классами использовался чистый winapi уже в созданное окно с известным хендлом. делалось по нажатию на кнопку например. И встроилось все корректно и события qt работали корректно, единственное была проблма только с мышью.... в отладчике можно глянуть, как путешествует координата. В оконной процедуре для сообщений WM_*BUTTON* Цитата (http://msdn.microsoft.com/en-us/library/ms645607(VS.85).aspx) lParam The low-order word specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area. The high-order word specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area. и ты дальше перекидывал координаты без изменений? Вот и будет косяк. Примени MapWindowPoints http://msdn.microsoft.com/en-us/library/dd145046(VS.85).aspx да я их вообще не перекидывал все равно как только мышь над qt то mfc больше события эти не получит(если только хук не поставить). это нормально так и должно быть (нормальная виндовая схема). пусть qt живет своей жизнью, со своими событиями и сообщениями (как я буду взаимодействовать с qt на уровне данных это уже другой вопрос). Мне надо чтобы у qt формы было parent HWND не desktop а мое окно. Понятно что это визуальная фикция (тк потенциально qt и mfc могут быть даже в разных процессах, в лучшем случае в разных нитях). но мне именно это и нужно. Видимо тут играет не последнюю роль кроссплатформенность... HWND используется тк по другому в виндах нельзя и главная форма или виджет будет лежать на подложке из HWND которую qt создает только из за "других вариантов нет", события из этого HWND транслируются qt и все бы ничего, но qt application знает что я не плагин а application поэтому создавая верхнее HWND всегда берет за основу координатную систему рабочего стола. если сделать winapi setparent реальный родитель меняется, но qt не отслеживает это, продолжая использовать координатную сетку рабочего стола (пересчет координат надо полагать не winapi опять кроссплатформеность). вот эту проблему решает qwinwidget.... после установки setparent средствами winapi он принудительно заставляет сменить координатную сетку на реального нового родителя, после чего мышь работает корректно. Кто знает суть данного события QEvent e(QEvent::EmbeddingControl); QApplication::sendEvent(this, &e); не могу найти толкового описания, как будет описание смогу точно сказать правда ли все вышенаписанное |
|
|
Текстовая версия | Сейчас: 27.12.2024, 8:27 |