// GDIPlusHelper.h: interface for the CGDIPlusHelper class.   
//   
//////////////////////////////////////////////////////////////////////   
  
#if !defined(AFX_GDIPLUSHELPER_H__BD5F6266_5686_43E2_B146_5EA1217A56FE__INCLUDED_)   
#define AFX_GDIPLUSHELPER_H__BD5F6266_5686_43E2_B146_5EA1217A56FE__INCLUDED_   
  
#if _MSC_VER > 1000   
#pragma once   
#endif // _MSC_VER > 1000   
  
#include <windows.h>   
  
//注意：此类当创建的图像对象是多帧动画时，没有考虑线程同步问题，不能在其他地方使用，   
//比如所有的Graphics操作函数，以及从基类继承过来的接口函数，你只能使用ImageEx类的public接口函数；   
//而当创建的是单帧图像时，线程同步性等价于基类Image的同步性，   
//则你可以像以前使用Image类那样使用该类，包括所有的Graphics操作函数，以及从基类继承过来的接口函数。  
//其实你会发现下面的public成员函数操作的成员变量都是新增的成员变量。   
  
class ImageEx : public Image   
{   
public:   
//以长度为nSize的内存pBuff中的内容构造图像   
    ImageEx(const void* pBuff, size_t nSize, BOOL useEmbeddedColorManagement = FALSE);   
//以类型为sResourceType，名称为sResource的资源构造图像   
    ImageEx(LPCTSTR sResourceType, LPCTSTR sResource, BOOL useEmbeddedColorManagement = FALSE);   
//以文件构造图像   
    ImageEx(LPCTSTR filename, BOOL useEmbeddedColorManagement = FALSE);   
//调用Destroy成员函数   
    ~ImageEx();   
public:   
//如果已经构造的对象是动画，则创建动画线程，并返回true，   
//如果为静态图像或已经创建过动画线程，则也返回false   
// 图像将绘制在m_hWnd客户区的rect区域，会拉伸，支持镜像   
    bool InitAnimation(HWND hWnd, RECT rect);   
//判断是否为动画   
    bool IsAnimatedGIF() { return m_nFrameCount > 1; }   
//设置动画暂停与否   
    void SetPause(bool bPause);   
//判断动画是否处于暂停状态   
    bool IsPaused() { return m_bPause; }   
//关闭动画，事实上基类Image中还有的两个成员变量没有关闭，因为析构函数会调用基类析构函数进行关闭的   
    void Destroy();   
  
protected:   
//测试图像是否为动画，是的话成员变量m_pPropertyItem将会malloc分配内存   
    bool TestForAnimatedGIF();   
//给所有成员变量初始化，构造函数中调用   
    void Initialize();   
//在客户区画出当前帧，返回值表示是否要退出线程函数   
    bool DrawFrameGIF();   
//把长度为nSize的内存pBuff中的内容创建为IStream流保存在类的m_pStream成员变量中，   
//返回成功与否，不检查参数的非法性   
    bool LoadFromBuffer(const void* pBuff, size_t nSize);   
//装载名称为lpName，类型为lpType的资源到pResource中，返回装载成功与否。   
//nBufSize表示pResource缓存的长度。pResource为NULL时，nBufSize返回所需内存大小，   
//不为NULL时，返回实际资源大小，长度不够时，相当于pResource为NULL时的作用，只是返回值为false。   
    bool GetResource(LPCTSTR lpName, LPCTSTR lpType, void* pResource, size_t& nBufSize);   
//装载类型为sResourceType，名称为sResource的资源到流对象成员变量m_pStream中，返回装载成功与否，   
//m_pStream在该函数中装载成功与否保存在成员变量m_bIsInitialized中，   
//同时，如果该类的对象是以文件构造的，则m_bIsInitialized表示构造成功与否   
    bool Load(LPCTSTR sResourceType, LPCTSTR sResource); //类型，名字   
//实际的线程函数   
    void ThreadAnimation();   
//代理线程函数，实际调用ThreadAnimation成员函数   
    static UINT WINAPI _ThreadAnimationProc(LPVOID pParam);   
  
protected:   
    IStream*        m_pStream; //记得Release   
    HANDLE          m_hThread; //线程创建时是挂起的，须调用ResumeThread   
    HANDLE          m_hPause; //手工重置，初始有信号   
    HANDLE          m_hExitEvent; //手工重置，初始无信号   
    HINSTANCE       m_hInst;   
    HWND            m_hWnd;   
    UINT            m_nFrameCount;   
    UINT            m_nFramePosition;   
    bool            m_bIsInitialized; //表示对象构造成功与否，不管是以资源还是文件的形式   
    bool            m_bPause;   
    PropertyItem*   m_pPropertyItem; //如果为动画，会malloc内存，记得free   
    HDC             m_hdcMem; //双缓存用，只在是多帧动画且创建了播放线程时才创建   
    HBITMAP         m_hbmpBack; //双缓存用，只在是多帧动画且创建了播放线程时才创建   
    RECT            m_rect; // 图像在m_hWnd客户区绘制的区域，会拉伸，支持镜像   
    //另外，基类Image中还有两个成员变量：nativeImage(GpImage*类型)和lastResult(Status类型)   
};   
  
  
#endif // !defined(AFX_GDIPLUSHELPER_H__BD5F6266_5686_43E2_B146_5EA1217A56FE__INCLUDED_)  
  