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, *.ico,etc...)
  • Scale images(Zoom In, Zoom Out)
  • Move images by cursor
  • Alignment
  • Save/Load images to/from compound document file.

Classes

class 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

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;
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 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:

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

Downloads

Download demo project - 150 Kb
Download source - 6.48 Kb


Comments

  • color blur when running in 65535 color mode + scrolling problem

    Posted by Legacy on 06/05/2002 12:00am

    Originally posted by: IonelB

    I have a SDK aplication very much like ADCSee.

    I am using IPicture to load images and I an having these problems

    Independent of the file format the colors of the pictures are blured and the picture is wrecked. (However this does not happen if the picture ids displayed in ACDSee or another picture viewer which perhaps uses other techniques)

    2. how do you scroll a picture realized with IPicture->render? I have tried it in the classical way (with WM_SIZE- SetScrollSize, WM_HSCROLL and WM_VSCROLL) but it seem that render only renders the portion of DC that is visible. When I scroll a blank portion of image or a blured mix of color is showed.


    Thenk you very much for any help,
    Ionel

    Reply
  • How crop the picture?

    Posted by Legacy on 05/10/2002 12:00am

    Originally posted by: BlackFox

    Thank you

    Reply
  • GDI+ Made easy

    Posted by Legacy on 11/04/2001 12:00am

    Originally posted by: Leandro Gustavo Biss Becker

    Hi

    Use gdi+ to manipulate pictures. See GDI+ codeguru session.

    Reply
  • woh! really great

    Posted by Legacy on 11/03/2001 12:00am

    Originally posted by: vikas saxena

    this type of article really provide the solution to the 
    
    problem which r not so easy to solve using text books
    like(teach yourself _ _ _ in _ _ days.
    vikas saxena

    Reply
  • Really nice, except...

    Posted by Legacy on 11/01/2001 12:00am

    Originally posted by: Jackson

    This is really nice except on the menu the Zoom in and Zoom out buttons do the opposite of what they should

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • VMware vCloud® Government Service provided by Carpathia® is an enterprise-class hybrid cloud service that delivers the tried and tested VMware capabilities widely used by government organizations today, with the added security and compliance assurance of FedRAMP authorization. The hybrid cloud is becoming more and more prevalent – in fact, nearly three-fourths of large enterprises expect to have hybrid deployments by 2015, according to a recent Gartner analyst report. Learn about the benefits of …

Most Popular Programming Stories

More for Developers

RSS Feeds