Streaming IPicture object
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, *.ico,etc...)
- Scale images(Zoom In, Zoom Out)
- Move images by cursor
- Alignment
- Save/Load images to/from compound document file.
Classes
classCPictureObj: publicCPictureHolder, publicCObject{ DECLARE_SERIAL(CPictureObj);public: CPictureObj(); CPictureObj(const CRect position);virtual~CPictureObj(); void RemoveAndDestroy();virtualvoid Copy( CPictureObj &right);virtualHRESULT WriteToStream(IStream* pStream);virtualHRESULT ReadFromStream(IStream* pStream); // Attributespublic: 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(); // Operationspublic: 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; };classCPictureObjList: publicCTypedPtrList{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.
classCYourDoc :publicCOleDocument
Define inside of document object the picture collection like here:
CPictureObjList m_objects;
Now, you can insert picture by simple way:
CPictureObj* pObj =newCPictureObj; pObj->CreateFromFile(CPoint(10,10)); m_objects.AddHead(pObj);
Also, you can load picture directly from the file:
CPictureObj* pObj =newCPictureObj; pObj->Load("MyFile.jpg"); m_objects.AddHead(pObj);
For scaling picture you can use 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 collection of pictures is also easy:
GetDocument()->m_objects.Draw(pDC);
Implementation of picture serialization you can get from here:
voidCYourDoc::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(); } }
Downloads
Download demo project - 150 KbDownload source - 6.48 Kb

Comments
There are no comments yet. Be the first to comment!