Использование IPersistStream
От: alexby81  
Дата: 19.01.05 09:29
Оценка:
Всем доброго времени суток!
Такой трабл, необходимо сохранить компонент в контроле в бинарном виде (не текст). Где-то нашел что это можно реализовать используя IPersistStream. Может кто занимался этим, подскажите как енто сделать, либо примерчик.
Re: Использование IPersistStream
От: Аноним  
Дата: 08.02.05 09:31
Оценка:
Здравствуйте, alexby81, Вы писали:

A>Всем доброго времени суток!

A>Такой трабл, необходимо сохранить компонент в контроле в бинарном виде (не текст). Где-то нашел что это можно реализовать используя IPersistStream. Может кто занимался этим, подскажите как енто сделать, либо примерчик.

C этим я разобрался, и в общем вопрос можно переиначить использование IStorage, IStream в своем приложение, ну да ладно. Вопрос теперь в другом:
Для сохранения данных, например Word, использует интерфейс IPersistStorage, IE — IPersistProprtyBag. Типа по умолчанию в карте своиств прописываются переменные размеры моего контрола, которые и использует интерфейс IPersistPropertyBag при сохранении, и собственно при открытии html страницы я вижу свой контрол с теми размерами которые я задал. Так трабл такой: как собственно сделать чтобы такой эффект наблюдался и при сохранении в Word'e, то есть сейчас у меня при открытии документа Word, размеры моего контрола устанавливаются по умолчанию.
Что отвечает за размеры контрола?
Re[2]: Использование IPersistStream
От: algol Россия about:blank
Дата: 08.02.05 10:28
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Для сохранения данных, например Word, использует интерфейс IPersistStorage, IE — IPersistProprtyBag. Типа по умолчанию в карте своиств прописываются переменные размеры моего контрола, которые и использует интерфейс IPersistPropertyBag при сохранении, и собственно при открытии html страницы я вижу свой контрол с теми размерами которые я задал. Так трабл такой: как собственно сделать чтобы такой эффект наблюдался и при сохранении в Word'e, то есть сейчас у меня при открытии документа Word, размеры моего контрола устанавливаются по умолчанию.

А>Что отвечает за размеры контрола?

На чем контрол написан — ATL, MFC или чистом C?
Re[3]: Использование IPersistStream
От: Аноним  
Дата: 08.02.05 11:32
Оценка:
Здравствуйте, algol, Вы писали:

A>Здравствуйте, Аноним, Вы писали:


А>>Для сохранения данных, например Word, использует интерфейс IPersistStorage, IE — IPersistProprtyBag. Типа по умолчанию в карте своиств прописываются переменные размеры моего контрола, которые и использует интерфейс IPersistPropertyBag при сохранении, и собственно при открытии html страницы я вижу свой контрол с теми размерами которые я задал. Так трабл такой: как собственно сделать чтобы такой эффект наблюдался и при сохранении в Word'e, то есть сейчас у меня при открытии документа Word, размеры моего контрола устанавливаются по умолчанию.

А>>Что отвечает за размеры контрола?

A>На чем контрол написан — ATL, MFC или чистом C?

смесь выше перечисленного ATL + MFC
Re[4]: Использование IPersistStream
От: algol Россия about:blank
Дата: 08.02.05 11:56
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>>Для сохранения данных, например Word, использует интерфейс IPersistStorage, IE — IPersistProprtyBag. Типа по умолчанию в карте своиств прописываются переменные размеры моего контрола, которые и использует интерфейс IPersistPropertyBag при сохранении, и собственно при открытии html страницы я вижу свой контрол с теми размерами которые я задал. Так трабл такой: как собственно сделать чтобы такой эффект наблюдался и при сохранении в Word'e, то есть сейчас у меня при открытии документа Word, размеры моего контрола устанавливаются по умолчанию.

А>>>Что отвечает за размеры контрола?

A>>На чем контрол написан — ATL, MFC или чистом C?

А>смесь выше перечисленного ATL + MFC

Продолжим допрос. Какие IPersist интерфейсы реализованы, и каким образом, через IPersistStreamInitImpl, IPersistPropertyBagImpl или как-то еще? Есть ли PROP_MAP c
PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)?
Re[5]: Использование IPersistStream
От: alexby81  
Дата: 08.02.05 12:32
Оценка:
Здравствуйте, algol, Вы писали:

A>Продолжим допрос. Какие IPersist интерфейсы реализованы, и каким образом, через IPersistStreamInitImpl, IPersistPropertyBagImpl или как-то еще? Есть ли PROP_MAP c

A> PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
A> PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)?

Итак, полный листинг таблицы свойств
BEGIN_PROP_MAP(CMyCtrl)
    PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
    PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
    PROP_ENTRY("BackColor", DISPID_BACKCOLOR, CLSID_StockColorPage)
    PROP_ENTRY("BorderColor", DISPID_BORDERCOLOR, CLSID_StockColorPage)
    PROP_ENTRY("ForeColor", DISPID_FORECOLOR, CLSID_StockColorPage)
    PROP_ENTRY("BorderVisible", DISPID_BORDERVISIBLE, CLSID_NULL)
    PROP_ENTRY("BorderWidth", DISPID_BORDERWIDTH, CLSID_NULL)    
END_PROP_MAP()


Контрол наследует следующие интерфейсы (я могу ошибаться в терминологии, так что звиняйте, от силы этим занимаюсь чуть больше месяца):
class ATL_NO_VTABLE CMyCtrl : 
    //...
    public IPersistStreamInitImpl<CMyCtrl>,
    public IPersistStorageImpl<CMyCtrl>,
    public IPersistPropertyBagImpl<CMyCtrl>
    //..
{
//...
}


COM карта контрола:
BEGIN_COM_MAP(CShapeCtl)
//...
    COM_INTERFACE_ENTRY(IPersistStreamInit)
    COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
//...
    COM_INTERFACE_ENTRY(IPersistPropertyBag)
//...
    COM_INTERFACE_ENTRY(IPersistStorage)
//...
END_COM_MAP()


Для наследуемых интерфейсов в контроле реализованы следующие методы
// IPersistStreamImpl
STDMETHOD(Load)(IStream *pStream);
STDMETHOD(Save)(IStream *pStream, BOOL fClearDirty);
STDMETHOD(GetSizeMax)(ULARGE_INTEGER* pcbSize);

// IPersistStorageImpl
STDMETHOD(Load)(IStorage *Storage); 
STDMETHOD(Save)(IStorage *pStorage, BOOL fSameAsLoad);

// IPersistPropertBag
STDMETHOD(Load)(IPropertyBag *pPropBag, IErrorLog* pErrorLog);
STDMETHOD(Save)(IPropertyBag *pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties);


что отвечает за размеры контрола в контейнере (IE в расчет не берем)?
Re[6]: Использование IPersistStream
От: algol Россия about:blank
Дата: 08.02.05 12:42
Оценка:
Здравствуйте, alexby81, Вы писали:

A>Итак, полный листинг таблицы свойств

A>
A>BEGIN_PROP_MAP(CMyCtrl)
A>    PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
A>    PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
A>    PROP_ENTRY("BackColor", DISPID_BACKCOLOR, CLSID_StockColorPage)
A>    PROP_ENTRY("BorderColor", DISPID_BORDERCOLOR, CLSID_StockColorPage)
A>    PROP_ENTRY("ForeColor", DISPID_FORECOLOR, CLSID_StockColorPage)
A>    PROP_ENTRY("BorderVisible", DISPID_BORDERVISIBLE, CLSID_NULL)
A>    PROP_ENTRY("BorderWidth", DISPID_BORDERWIDTH, CLSID_NULL)    
A>END_PROP_MAP()
A>


Скорее всего, эта проблема описана в Q241936

SYMPTOMS
Microsoft Word does not appear to save the properties of an Active Template Library (ATL) ActiveX control when the document is saved and then re-opened. Trace statements in ATL show that IPersistStorage and IPersistStreamInit are being called to both save and load the control's settings, but the control appears to be initialized to a new state every time the document is opened.

CAUSE
The problem occurs because ATL's implementation of IPersistStreamInit::Save and IPersistStreamInit::Load performs a QueryInterface call to get the IDispatch of the root control from which it will persist stock properties. Because Word wraps all embedded controls in an aggregated extender object, the QueryInterface call is returning the IDispatch of the Word extender and not the internal control. This causes the persist methods to fail when saving and loading the control in certain circumstances.

RESOLUTION
To resolve the problem, you need to overwrite the IPersistStreamInit_Load and IPersistStreamInit_Save functions for your control, and create modified versions of the global functions AtlIPersistStreamInit_Load and AtlIPersistStreamInit_Save. See the sample below for the steps to needed to resolve the issue.

Re[7]: Использование IPersistStream
От: alexby81  
Дата: 08.02.05 12:47
Оценка:
Ладно, будем разбираться. Спасибо.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.