При закрытии подписчики были переданы в рассылку "RFpro.ru: Программирование на C / C++" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
Информационный Канал Subscribe.Ru |
![]() |
![]() |
Главная | Новости | Статьи | Каталог | Софт | Регистрация | Поиск |
Новые статьи |
Свежие компьютерные новости |
Объекты OLE |
OLE это сокращение от Objects Linking and Embedding, т. е. объекты связанные и внедренные. Наверняка вы знакомы с таким редактором как Word. Вспомните, что картинка, которую вы переносите в текстовый редактор, действительно может быть либо внедрённой, либо связанной. Внедрённая картинка будет храниться в файле документа, часто значительно увеличивается его объём. Связанная картинка хранится в отдельном файле, а в файле документа хранится лишь ссылка на эту картинку. В последнем случае доступ к объекту могут иметь одновременно несколько приложений, что позволяет, в частности, проводить групповую разработку документов. Сказанное, разумеется, относится не только к графическому объекту, но, к любому другому, поддерживаемому приложением. Контейнеры и серверыВ механизме OLE присутствуют два приложения – приложения, содержащие объект, и приложения, вызываемые для редактирования объекта. Приложение, содержащее объект, называется контейнером. Приложение, используемое для редактирования объекта, называется сервером. Особо отметим, что одна и та же программа может одновременно выполнять и роль контейнера, и роль сервера. Контролёры и серверы автоматизацииСервер автоматизации предоставляет свои методы и свойства другим приложениям. Приложение, которое пользуется возможностью управлять сервером, называется контролёром автоматизации. Заметим в этой связи, что элементы ActiveX являются ни чем иным, как сервером автоматизации. Создание проекта
Откомпилируйте наш проект и запустите его. В меню Edit мы увидим единственный активный пункт Insert New Object. Этот пункт и позволяет нам поместить в наш документ выбранный нами объект. Выберем этот пункт. В появившемся окне вы можете выбрать, объект какого типа будет помещен в наш контейнер. Выберем в списке пункт Документ Microsoft Word и нажмём OK. В окне нашего приложения появится объект – документ Word. Обратите внимание на изменившееся меню. Это меню программы Word. Исключение является только пункт File, который соответствует нашему приложению. Кроме того, в окне появится и панели инструментов MS Word. При помощи мыши изменим, размеры нашего объекта и в нем наберём некоторый текст. Нажмём на клавишу Esc – объект исчезнет из нашего окна, хотя набранный в нем текст останется. Обратим внимание на то, что наш объект не активизируется и не де активизируется с помощью щелчков мыши, как это положено в стандарте OLE. Устранение этого недостатка и будет одним из пунктов нашего дальнейшего рассмотрения. Чтобы снова активизировать наш проект (ранее де активизированный клавишей Esc), нужно обратиться к пункту меню Edit/Объект/Изменить. Вот что должно, на мой взгляд, заинтересовать вас в первую очередь. Как сохранить и восстановить объект в контейнере. Обратимся к пункту меню File/Save As и сохраним документ в файле Untitled. Просмотр сохранённого файла наводит на мысль, что созданный нами объект действительно сохранился в этом файле. Для того, чтобы удалить объект из контейнера можно воспользоваться пунктом меню File/New. Удалим объект из нашего контейнера, и попытаемся восстановить его с помощью пункта File/Open. Пункт срабатывает без каких-либо сообщений об ошибке, но объект в нашем контейнере не появляется. Стало быть, первое, чем мы сейчас займемся, это проблема сохранения и восстановления из архива. Изучение модулей проекта приводит нас к странному, на первый взгляд, открытию. В проекте имеются две функции. void ColeDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // дополнительный код сохранения документа в архиве } else { // дополнительный код восстановления данный из архива } // вызов функции сериализации базового класса, вызывает // сохранения объекта, находящегося в данный момент в контейнере. COleDocument::Serialize(ar); } Особо надо обратить внимание на последний вызов: COleDocument::Serialize(ar); Это очень важный вызов. Маленькое исследование, которое я предлагаю провести вам, дорогой читатель, показывает, что при этом вызывается функция сериализации из модуля CntrItem.cpp. Вот эта функция: void ColeCntrItem::Serialize(CArchive& ar) { ASSERT_VALID(this); // сохранить (восстановить) объект, находящийся // Since в данный момент в контейнере COleClientItem::Serialize(ar); if (ar.IsStoring()) { // можно сохранить другие данные из класса поддержки // объекта к контейнере } else { // восстановить другие данные из класса поддержки // объекта в контейнере } } Интуитивно понятно, что всё дело в этой функции. Примем за исходное, что сохранение данных осуществляется правильно. Следовательно, дело в восстановлении данных. Поскольку и восстанавливаются данные той же функцией, то, очевидно, восстановление данных также производится правильно. Таким образом, причину не появления объекта нужно искать в методах класса ColeClientItem. По смыслу самым подходящим методом оказывается метод DoVerb. virtual BOOL DoVerb ( LONG nVerb, CView* pView, LPMSG lpMsg = NULL ) Данный метод используется для произведения действия, которое определяется значением первого параметра. Второй и третий параметры обычно полагают равным NULL, но можно поместить туда указатель на объект-предоставление. Действие «представить для редактирования объект» определяется значением первого параметра -1 (или 0). Значение -2 определяет редактирование объекта в отдельном окне. В результате функция сериализации, позволяющая загрузить в контейнер и представить для редактирования объект, будет иметь следующий вид. Вместо функции DoVerb можно использовать метод Activate(-1, this->GetActiveView()). void ColeCntrItem::Serialize(CArchive& ar) { ASSERT_VALID(this); COleClientItem::Serialize(ar); if (ar.IsStoring()) { } else { this->DoVerb(0, this->GetActiveView()); GetActiveView()->m_pSelection=this; GetDocument()->UpdateAllViews(NULL); } } Мы продемонстрировали вам примерный ход рассуждений, которому приходится часто следовать, работая программистом и не имею под рукой полной документации. Итак, мы можем сохранить и восстановить объект контейнера. Теперь продолжим совершенствовать наш проект. Поставим перед собой следующую задачу: объект можно перемещать и менять его положение. Добавим в класс ColeCntrItem новый член m_rect типа CRect. В этой переменной будет храниться информация о визуальном положении объекта. Позаботимся теперь о том, чтобы данная переменная сохранялась при сериализации. Для этого ещё раз перепишем функцию сериализации void ColeCntrItem::Serialize(CArchive& ar) { ASSERT_VALID(this); COleClientItem::Serialize(ar); if (ar.IsStoring()) { ar<<m_rect; } else { ar>>m_rect; this->DoVerb(0, this->GetActiveView()); GetActiveView()->m_pSelection=this; GetDocument()->UpdateAllViews(NULL); } } Перепишем конструктор класса ColeCntrItem так, чтобы инициализировать начальное значение положения объекта. ColeCntrItem::ColeCntrItem(ColeDoc* pContainer) : COleClientItem(pContainer) { m_rect=CRect(20,20,300,300); } Найдём в модуле oleView.cpp функцию void ColeView::OnDraw(CDC* pDC) В ней найдём вызов m_pSelection->Draw(pDC, rect); и заменим его на m_pSelection->Draw(pDC, m_pSelection->m_rect); Член m_pSelection класса ColeView осуществляет связь между представлением и объектом, содержащимся в контейнере. Обратимся теперь к функции void ColeCntrItem::OnGetItemPosition(CRect& rPosition) Эта функция должна возвращать прямоугольник объекта. Измените данную функцию так, чтобы она содержала одну-единственную строку. void ColeCntrItem::OnGetItemPosition(CRect& rPosition) { rPosition=m_rect; } В жёсткой фиксации объектов нет ничего хорошего. Чтобы сделать систему более гибкой, давайте обратимся к функции ColeCntrItem::OnChangeItemPosition. Эта функция вызывается каждый раз, когда меняется положение и размер объекта в контейнере. Вот текст этой функции. BOOL ColeCntrItem::OnChangeItemPosition(const CRect& rectPos) { ASSERT_VALID(this); if (!COleClientItem::OnChangeItemPosition(rectPos)) return FALSE; return TRUE; } Параметром этой функции как раз и является новое место положение объекта. Добавим в функцию следующие функции. //запомнить новый размер m_rect=rectPos; //установить флаг изменения изображения GetDocument()->SetModifiedFlag(); //обновить отображение GetDocument()->UpdateAllViews(NULL); В результате мы пришли к приложению, которое позволяет помещать в контейнер объект, редактировать его, изменять его размеры и положение, сохранять объект и его состояние в файле и восстанавливать его оттуда. Пример к статье здесь. |
Subscribe.Ru
Поддержка подписчиков Другие рассылки этой тематики Другие рассылки этого автора |
Подписан адрес:
Код этой рассылки: comp.soft.prog.visualc Архив рассылки |
Отписаться
Вспомнить пароль |
В избранное | ||