将 IPicture 流式传输到复合文档文件






4.76/5 (9投票s)
2001年10月29日
1分钟阅读

113939

3018
IPicture 对象的序列化
引言
我非常喜欢 IPicture
对象。这个 COM 对象工作得很好。然而,当我尝试在文档-视图架构中使用这个对象时遇到了一些问题。主要问题是序列化的实现。我构建了两个类来解决这些问题。第一个类叫做 CPictureObj
。这个类负责绘制图片。第二个类是图片对象的集合。通过使用这两个类,很容易实现以下功能:
- 将一个或多个图像加载到文档中(*.bmp、*.jpeg、*.ico,...)
- 缩放图像(放大、缩小)
- 通过光标移动图像
- 对齐
- 将图像保存/加载到/从复合文档文件中。
类
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); };
使用这些类
要使用流式传输图片,请创建从 COleDocument
派生的文档对象。
class CYourDoc : public COleDocument
在文档对象内部,像这样定义一个图片集合:
CPictureObjList m_objects;
现在,您可以使用这个简单的方法插入图片:
CPictureObj* pObj = new CPictureObj; pObj->CreateFromFile(CPoint(10,10)); m_objects.AddHead(pObj);
您也可以直接从文件加载图片:
CPictureObj* pObj = new CPictureObj; pObj->Load("MyFile.jpg"); m_objects.AddHead(pObj);
要缩放图片,可以使用 ZoomIn、ZoomOut 成员函数:
CPictureObj* pObj = m_objects.FindSelected();
if(pObj)
{
pObj->ZoomIn();
}
移动选定的图片很简单:
CPoint delta = point - c_last; CPictureObj* pSel = m_objects.FindSelected(); if(pSel) { CRect position = pSel->GetPosition(); position += delta; pSel->MoveTo(position, this); }
绘制图片集合也很容易:
GetDocument()->m_objects.Draw(pDC);
您可以从这里获取图片序列化的实现:
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(); } }
祝您好运!