![]() |
|
![]() ![]() ![]() |
|
ifndef |
|
||||||||||
![]() Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 25.5.2008 Где: Россия, Москва Репутация: нет Всего: нет |
Здравствуйте, Уважаемые!
Прошу помощи в решение следующей проблемы: Имеется самодельный composite ActiveX control: написан с использованием ATL, оформлен в виде dll (inproc server), является контейнером для других стандартных ActiveX элементов - кнопочек, надписей и т.п.. Выглядит примерно так:
Нужно сделать так, что бы в ходе выполнения программы его можно было динамически воткнуть на форму (к примеру на форму диалога, созданного с помощью MFC wisard`a) и получить к нему доступ для ресайза и модификации, причем модификация элемента должна быть реализована в каком-нибудь переопределенном стандартном методе стандартных интерфейсов, от которого унаследован класс элемента ActiveX (я использовал метод SetExtent интерфейса IOleObject). Динамически воткнуть удалось с использованием ProgId ActiveX`а и метода CreateControl класса CWnd. Вот пример кода - это обработчик нажатия кнопки на форме MFCшного диалога. При нажатии контрол должен просто появиться на форме:
Затем пытаюсь до него достучаться: На форме диалога помещаю кнопочку, по нажатию на которую контрол должен изменить свои размеры, вот обработчик ее нажатия:
Переопределяю в ActiveX`е метод SetExtent интерфейса IOleObject:
Когда дело доходит до метода GetDlgItem, выскакивает Assert из этой функции и выполнение программы завершается ошибкой:
Видимо, проблема в отсутствии окна, точнее его описателя, но сколько ни бился, не могу понять какого и как это решить.. :( Если ресайз делать по нажатию кнопочки внутри самого контрола (т.е. любой кнопки из контейнера), все работает... Разъясните пожалуйста поподробнее в чем моя ошибка и как реализовать описанное выше! Заранее благодарен! С уважением, Сергей. |
||||||||||
|
|||||||||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
У вас в void CDynPropAppDlg::OnShowPPage() создается один ActiveX control, а в void CDynPropAppDlg::OnBnClickedResize() - еще один. Нужно не создавать еще одну копию, а брать уже созданный в окне (см. метод page->QueryControl или метод CreateControlEx, 4й параметр ppUnkControl)
|
|||
|
||||
ifndef |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 25.5.2008 Где: Россия, Москва Репутация: нет Всего: нет |
xvr, спасибо за помощь!
Объект page в моем случае - это объект класса CWnd, поэтому метода CreateControlEx не содержит. Попробовал его сделать объектом класса CAxWindow, но так как в методе CreateControlEx нет параметра типа CWnd* pParentWnd как в методе CWnd::CreateControl, то при запуске вылезает ассерт уже отсюда:
Т.е., как я понимаю, мой объект page не является окошком, так как не зарегистрирован, по типу RegisterClassEx и не создано окошко (аля методом Create). |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
Тогда для доступа к созданному ActiveX надо звать GetControlUnknown |
|||
|
||||
ifndef |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 25.5.2008 Где: Россия, Москва Репутация: нет Всего: нет |
Через GetControlUnknown тоже самое - ассерт при вызове метода GetDlgItem в переопределенном методе SetExtent в контроле...
Загвоздка, видимо, вот в этом: переопределенный метод SetExtent в контроле:
Когда вызывается этот метод, создается новый объект класса CWindow, для того, чтобы в него сохранить указатель на контрол внутри контейнера. Потом вызывается метод GetDlgItem. Если взглянуть на этот метод:
то можно увидеть, что он проверяет переменную m_hWnd, а потом вызывает APIшную(??) функцию, в которую этот HWND и передается.. Вопрос в том, что это за m_hWnd и как его сюда передать из MFCшного диалога... Повторюсь, что если этот метод (SetExtent), вызывается из обработчика висящего на кнопке, расположенной в контейнере, то все нормально работает и хэндл передается, если же используется обработчик кнопки на MFC диалоге - затык... ![]() Это сообщение отредактировал(а) ifndef - 26.5.2008, 18:38 |
||||
|
|||||
ifndef |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 25.5.2008 Где: Россия, Москва Репутация: нет Всего: нет |
xvr, спасибо большое за участие, все заработало!
В предыдущем посте я допустил ошибку - при создании контрола, вызывается метод SetExtent, ассерт выскакивал потому, что окна контрола еще не было на тот момент. Надо было писать так:
Еще раз спасибо! ![]() Это сообщение отредактировал(а) ifndef - 27.5.2008, 11:18 |
|||
|
||||
ifndef |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 25.5.2008 Где: Россия, Москва Репутация: нет Всего: нет |
Господа, кто-нибудь знаком с методом интерфейса IViewObject SetExtent?
Не могу понять как он функционирует и для чего нужен.. :( Мне необходимо реализовать масштабирование элемента ActiveX в контейнере. Вычитал в умной книжке, что этот метод, вроде как, выполняется в случае, если надо изменить размеры внедренного элемента, т.е. если написать так:
то после выполнения этого метода мой ActiveX-элемент должен быть отмасштабирован в область с размерами 50 на 100, или я ошибаюсь? Пробую это сделать, размеры элемента не меняются.. :( Прошу совета! Это сообщение отредактировал(а) ifndef - 4.6.2008, 15:09 |
|||
|
||||
xvr |
|
||||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
Может все же IOleObject::SetExtent? Читаем MSDN:
|
||||||
|
|||||||
ifndef |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 25.5.2008 Где: Россия, Москва Репутация: нет Всего: нет |
xvr, спасибо за помощь! Уже вроде разобрался!
![]() Насчет IViewObject - виноват, переклинило что-то... SetExtent вернул S_OK.. Требуется сделать так, чтобы при изменении окна внедренный элемент масштабировался. Окошко с элементом выглядит следующим образом: ![]() Сам ActiveX - composite control, включающий в себя следующие элементы: - GroupBox - Static - Button Вот он: ![]() Думал сделать масштабирование так: 1. Создаем контрол.
2. В случае ресайза окна вызываем метод IOleObject::SetExtent на стороне элемента 3. Метод SetExtent выглядит примерно так:
Это правильно, как по-Вашему, или можно как-нибудь пограмотнее написать? Это сообщение отредактировал(а) ifndef - 4.6.2008, 21:37 |
||||
|
|||||
ifndef |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 25.5.2008 Где: Россия, Москва Репутация: нет Всего: нет |
Кстати такой еще вопрос:
Для отображения контрола я использую метод CWnd::CreateControl(). В этом методе создается объект класса COleControlContainer и объект COleControlSite. Пытался вручную создать контейнер, подключить к нему ControlSite и создать контрол, да что-то не выходит.. Вот код:
Не понимаю методки создания контрола и где какое окно подключать, например: методы CreateContainer(this) и CreateControl(this,cls77,L"",WS_VISIBLE,CRect(0,0,270,200),1002) Оба первым параметром имеют m_hWnd окна. Как я понимаю, в случае создания контейнера необходимо указать само окно диалога, а в случае создания контрола - окно контрола (т.е. просто любой объект типа CWnd, например тот же самый CWnd* page, см выше), или я не прав? Программа завершается на последней строчке приведенного кода в методе COleControlSite::QuickActivate() на строчке pWndContain->OnAmbientProperty(this, _afxAmbients[i].dwDispID, &var). Выскакивает ассерт:
Что я делаю не так? Это сообщение отредактировал(а) ifndef - 5.6.2008, 06:55 |
||||
|
|||||
xvr |
|
||||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 8 Всего: 223 |
CreateControlSite переопределен? Его default имплементация для CWnd пустая.
PS. С SetExtent вроде все Ок |
||||||
|
|||||||
ifndef |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 25.5.2008 Где: Россия, Москва Репутация: нет Всего: нет |
xvr, ОГРОМНЕЙШЕЕ спасибо, Вы очень мне помогли!
Вопрос снят, вроде как во всем разобрался!! ![]() |
|||
|
||||
Finarfin |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 9.6.2009 Репутация: нет Всего: нет |
Тоже нужен этот пример. Это должно поставляться с Visual Studio? Microsoft Visual Studio 10.0\Samples\1049\VC2010Samples.zip - здесь нет. О, сорри, нашел Добавлено через 7 минут и 20 секунд Блин, там то же самое. Нет там vcterm никакого Это сообщение отредактировал(а) Finarfin - 25.7.2010, 20:48 |
|||
|
||||
![]() ![]() ![]() |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: COM/DCOM/ActiveX/ATL/CORBA | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |