Streaming IPicture object

Sample Image

Environment: VC++ 5.0-6.0, NT 4.0,Win2000, Win95/98

I really like the IPicture object. This COM object works very fine. However, I had some problem when I was trying to use it in a Document-View architecture. The main problem is implementation of serialization. To resolve this problem I built two classes.

The first class called CPictureObj. This class is responsible for drawing the picture. The second class, CPictureObjList, is a collection of picture objects. By using both of these classes it is easy to implement the following functionality:

  • Load one or more images into document (*.bmp, *.jpeg,
  • Scale images(Zoom In, Zoom Out)
  • Move images by cursor
  • Alignment
  • Save/Load images to/from compound document file.


class CPictureObj :
public CPictureHolder, public CObject
CPictureObj(const CRect position);
virtual ~CPictureObj();
void RemoveAndDestroy();

virtual void Copy( CPictureObj &right);
virtual HRESULT WriteToStream(IStream* pStream);
virtual HRESULT ReadFromStream(IStream* pStream);

// Attributes

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


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();


void CalcZoom();
void SetZoomToPosition();


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*}

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

Define inside of document object the picture collection like here:

CPictureObjList  m_objects;

Now, you can insert picture by simple way:

CPictureObj* pObj =  new CPictureObj;

Also, you can load picture directly from the file:

CPictureObj* pObj =  new CPictureObj;

For scaling picture you can use ZoomIn, ZoomOut member functions:

CPictureObj* pObj = m_objects.FindSelected();

Moving the selected picture is easy:

CPoint delta = point – c_last;
CPictureObj* pSel = m_objects.FindSelected();
CRect position = pSel->GetPosition();
position += delta;
pSel->MoveTo(position, this);

Drawing collection of pictures is also easy:


Implementation of picture serialization you can get from here:

void CYourDoc::Serialize(CArchive& ar)
CWaitCursor wait;
if (ar.IsStoring())


Download demo project – 150 Kb
Download source – 6.48 Kb

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read