Streaming IPicture to Compound Document file






4.76/5 (9 votes)
Oct 29, 2001
1 min read

113457

3018
Serialization of IPicture object
Introduction
I really like the IPicture
object. This COM object works very well.
However, I met some problems when I was trying to use this object in the Document-View architecture.
The main problem is implementation of serialization. I built two classes to resolve those problems.
The first class called CPictureObj
. This class is responsible for drawing picture. The second one is collection of picture objects.
By using both of them it is easy to implement the following functionality:
- Load one or more images into document (*.bmp, *.jpeg, *.ico,...)
- Scaling images (Zoom In, Zoom Out)
- Move images by cursor
- Alignment
- Save/Load images to/from compound document file.
Classes
class <code>CPictureObj : public CPictureHolder, public CObject { DECLARE_SERIAL(CPictureObj); public: CPictureObj(); CPictureObj(const CRect position); virtual ~CPictureObj(); void RemoveAndDestroy(); virtual void Copy( CPictureObj &right); virtual HRESULT WriteToStream(IStream* pStream); virtual HRESULT ReadFromStream(IStream* pStream); // Attributes public: HorzAlign GetHorzAlign( void ) const; void SetHorzAlign( HorzAlign eHorzAlign ); VertAlign GetVertAlign( void ) const; void SetVertAlign( VertAlign eVertAlign ); BOOL GetSelected( void ) const; void SetSelected( BOOL bValue ); void SetVisible(BOOL bValue); BOOL GetVisible(); CRect GetPosition(); void SetPosition(const CRect pos); CRect GetStartRect(); void SetStartRect(const CRect pos); CString GetPathName(); void SetPathName(const CString pathname); OLE_HANDLE GetHandle(); CSize GetSize(); // in himetric CSize GetSize(CDC*pDC); // in pixel CSize GetSize(CWnd*pWnd); // in pixel BOOL IsValidPicture(); // Operations public: BOOL Load(LPCTSTR szFile); BOOL CreateFromFile(const CPoint pt); void ReleasePicture(); void MoveTo(const CRect& position, CWnd* pView); // Drawing picture void Draw(CDC* pDC); void Draw(CDC* pDC, CRect& rcBounds); void Draw(CDC* pDC, const CRect& rcPosition, const CRect& rcBounds); void DrawTracker(CDC* pDC); void DrawTracker(CDC* pDC, const CRect& rect); void ZoomIn(); void ZoomOut(); protected: void CalcZoom(); void SetZoomToPosition(); protected: HorzAlign m_eHorizAlign; VertAlign m_eVertAlign; BOOL m_bSelected; BOOL m_bVisible; CRect m_rcPosition; // in pixels CRect m_startRect; // in pixels int m_trackerStyle; int m_zoomX,m_zoomY; // Not serialized CString m_strPathName; }; class CPictureObjList : public CTypedPtrList {CObList, CPictureObj*} { public : ~CPictureObjList(); void RemoveAndDestroy(); void DeselectAll(); CSize ComputeMaxSize(); // in himetric CSize ComputeMaxSize(CDC* pDC); // in pixel CSize ComputeMaxSize(CWnd* pWnd); // in pixel CRect GetRect(); // in pixel CPictureObj* FindSelected(); CPictureObj* ObjectAt(const CPoint& pt); bool Remove(CPictureObj* pObj); void Draw(CDC* pDC); // Streaming HRESULT WriteToStream(IStream* pStream); HRESULT ReadFromStream(IStream* pStream); BOOL WriteToStorage(LPSTORAGE lpRootStg); BOOL ReadFromStorage(LPSTORAGE lpRootStg); };
Using the classes
For use streaming picture create your document object derived from COleDocument
.
class CYourDoc : public COleDocument
Inside of the document object define a picture collection like here:
CPictureObjList m_objects;
Now, you can insert picture by this simple method:
CPictureObj* pObj = new CPictureObj; pObj->CreateFromFile(CPoint(10,10)); m_objects.AddHead(pObj);
Also, you can load picture directly from the file:
CPictureObj* pObj = new CPictureObj; pObj->Load("MyFile.jpg"); m_objects.AddHead(pObj);
For scaling pictures you can use the ZoomIn, ZoomOut member functions:
CPictureObj* pObj = m_objects.FindSelected();
if(pObj)
{
pObj->ZoomIn();
}
Moving the selected picture is easy:
CPoint delta = point - c_last; CPictureObj* pSel = m_objects.FindSelected(); if(pSel) { CRect position = pSel->GetPosition(); position += delta; pSel->MoveTo(position, this); }
Drawing a collection of pictures is also easy:
GetDocument()->m_objects.Draw(pDC);
Implementation of picture serialization you can get from here:
void CYourDoc::Serialize(CArchive& ar) { CWaitCursor wait; COleDocument::Serialize(ar); if (ar.IsStoring()) { m_objects.WriteToStorage(m_lpRootStg); } else { m_objects.ReadFromStorage(m_lpRootStg); m_objects.DeselectAll(); } }
Good luck!