Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: silart от Сентябрь 22, 2008, 11:39



Название: Платформенно-зависимый код.
Отправлено: silart от Сентябрь 22, 2008, 11:39
Добрый день всем!

Возникла следующая проблема:
Функция QWidget::find() почему-то всегда возвращает нулевой указатель. Я ей передаю правильный HWND, но возвращаемое значение всегда ноль. Единственный раз удалось мне у нее получить указатель на виджет. Я сделал следующее: В конструкторе класса-виджета с помощью API функции FindWindow() получил HWND этого окна, и передал его QWidget::find(). Она вернула указатель такой же, что и this.
Может каким-то другим образом можно получить указатель QWidget через HWND?


Название: Re: Платформенно-зависимый код.
Отправлено: ритт от Сентябрь 22, 2008, 12:23
а можно код?


Название: Re: Платформенно-зависимый код.
Отправлено: Alex03 от Сентябрь 22, 2008, 12:42
silart

FindWindow() - зачем? есть же WId QWidget::winId () const

А подсовываешь HWND окна этого же приложения?


Название: Re: Платформенно-зависимый код.
Отправлено: silart от Сентябрь 22, 2008, 18:29
а можно код?

Мне нужно получить QWidget из HWND.

Код:
HWND h;
pI->GetHWND(&h); // получаем валидный HWND какого-нибудь окна
QWidget* pMainWnd = QWidget::find(h); // Почему-то всегда получаем нулевой указатель.

Хотя если извратиться, получить каким-то образом HWND моего же Qt-шного окна (я это делал с помощью виндовой функции FindWindow()), и потом передать этот HWND функции QWidget::find(), то она возвратит валидный указатель, идентичный this (если мы все это делаем внутри оконного класса). Я все это проделал чтобы проверить работоспособность QWidget::find.
Так вот, каким образом можно получить QWidget из HWND?


Название: Re: Платформенно-зависимый код.
Отправлено: SASA от Сентябрь 22, 2008, 18:44
Assistant
Цитировать
QWidget * QWidget::find ( WId id )   [static]

Returns a pointer to the widget with window identifer/handle id.

The window identifier type depends on the underlying window system, see qwindowdefs.h for the actual definition. If there is no widget with this identifier, 0 is returned.

По-моему работает только с кутэшными окнами.


Название: Re: Платформенно-зависимый код.
Отправлено: ритт от Сентябрь 22, 2008, 19:37
только с кутэшными окнами

в виджетпривате создаётся карта всех виджетов [вид => указатель]


Название: Re: Платформенно-зависимый код.
Отправлено: silart от Сентябрь 23, 2008, 04:48
только с кутэшными окнами

в виджетпривате создаётся карта всех виджетов [вид => указатель]

Ну а как же тогда мне сделать модальное окно на Qt, если известен родительский HWND?
Почему нельзя обернуть любой HWND в QObject?


Название: Re: Платформенно-зависимый код.
Отправлено: Alex03 от Сентябрь 23, 2008, 06:35
Почему нельзя обернуть любой HWND в QObject?
Потому что find() только возвращает указатель на QWiidget() этого же приложения, ничего при этом не создавая. Другие приложения не обязательно написаны на Qt, и соответственно у них может не быть QWiidget-объекта, да и доступ к объектам др. приложения Вам никто не даст.

Вы опишите задачу в целом, а не то как Вы её пытаетесь решить.


Название: Re: Платформенно-зависимый код.
Отправлено: silart от Сентябрь 23, 2008, 07:04
Вы опишите задачу в целом, а не то как Вы её пытаетесь решить.

Я делаю внешнюю компоненту для программы 1С. Это внутрипроцессный COM-сервер. Внутрь передается указатель на COM-объекты самого 1С из которого можно выдрать HWND его окна. А мне нужно окно сделать на QT и сделать окно модальным, то есть пока окно будет видимым, 1С не должен быть доступен. Вот я и хочу обернуть HWND в QWidget. Окно уже создается. С помощью SetParent() я присвоил ему родителя - окно 1С. (кстати функция QWidget::winId() работает нормально). Одна проблема щас - сделать наше окно модальным. Вы не подскажете, может виндовыми функциями это можно сделать?


Название: Re: Платформенно-зависимый код.
Отправлено: Tonal от Сентябрь 23, 2008, 07:45
В Qt Solutions есть qtwinmigrate как раз для нормального взаимодействия с окнами написанными на чём попало не на Qt. :)

Но твоя задача проще. Можно обойтись и без qtwinmigrate.
Тебе нужно наследовать своё окно от QDialog,
и при вызове функции показа окна:
1) Создать экземпляр QApplication
2) Создать окно
3) Сделать ему exec.
Примерно так:
Код:
int invoceMyQtWindow(params...) {
  QApplication app;
  QMyWindow win(params...);
  return win.exec();
}


Название: Re: Платформенно-зависимый код.
Отправлено: kirill от Сентябрь 23, 2008, 07:49
Кури в сторону QWinWidget из пакета QtWinMigrate.
Код:
                     //HWND hParentWnd
QWinWidget *m_winparent = new QWinWidget(hParentWnd);
QVBoxLayout *vl = new QVBoxLayout;
vl->addWidget(new QlineEdit());
m_winparent->setLayout(vl);
m_winparent->setGeometry(m_parent->geometry());
m_winparent->show();


Название: Re: Платформенно-зависимый код.
Отправлено: silart от Сентябрь 23, 2008, 09:02
В Qt Solutions есть qtwinmigrate как раз для нормального взаимодействия с окнами написанными на чём попало не на Qt. :)

Но твоя задача проще. Можно обойтись и без qtwinmigrate.
Тебе нужно наследовать своё окно от QDialog,
и при вызове функции показа окна:
1) Создать экземпляр QApplication
2) Создать окно
3) Сделать ему exec.
Примерно так:
Код:
int invoceMyQtWindow(params...) {
  QApplication app;
  QMyWindow win(params...);
  return win.exec();
}

Я и делаю примерно так. Кстати, QApplication насколько мне известно не имеет параметров по умолчанию.
Только дело в том, что мое окно создается в другом потоке (не в том, который обрабатывает главное окно 1С) и получается так, что на панеле задач 2 окна: мое и 1С. Но я пошел дальше, с помощью функции SetParent() я задал родителя моему окну. Окна также остались активными, но теперь на панеле задач одно окно 1С. Да, вот еще, я имею HWND не главного окна 1С, а какого-то его предка, рабочая область короче. Вот мне и надо сделать так, чтобы рабочая область бла неактивна во время работы с моим окном. EnableWindow() почему-то делает оба окна неактивными.


Название: Re: Платформенно-зависимый код.
Отправлено: silart от Сентябрь 23, 2008, 09:04
Кури в сторону QWinWidget из пакета QtWinMigrate.
Код:
                     //HWND hParentWnd
QWinWidget *m_winparent = new QWinWidget(hParentWnd);
QVBoxLayout *vl = new QVBoxLayout;
vl->addWidget(new QlineEdit());
m_winparent->setLayout(vl);
m_winparent->setGeometry(m_parent->geometry());
m_winparent->show();

Подскажите пожалуйста, где взять этот пакет? У меня Qt 4.4.0, там вроде такого нету...


Название: Re: Платформенно-зависимый код.
Отправлено: silart от Сентябрь 23, 2008, 10:02
Товарищи, где можно взять Qt/MFC Migration Framework? С официального сайта не дают скачать. В гугле рылся, тоже пока не нашел. Кирилл, если у вас есть, может поделитесь?


Название: Re: Платформенно-зависимый код.
Отправлено: kirill от Сентябрь 23, 2008, 11:00
Сорри, у меня комерциал, не могу.


Название: Re: Платформенно-зависимый код.
Отправлено: Tonal от Сентябрь 23, 2008, 11:13
Можно предварительно пройтись по всем окнам верхнего уровня и задизаблить их.
А после уже своё показывать.

Ну а Qt/MFC Migration Framework продаётся в составе Qt Solutions - так что простой ответ - покупать. :)

П.С. Насчёт параметров - тык я жеж шаблон показал а не код готовый. :)