miranda的专栏

从网络中学习,归还到网络!

GDI+在ActiveX Controls中的启用和停止

  
在ActiveX中使用GDI+和在其它应用程序中使用基本上是相同的,但是有一个非常重要的不同就是启动和停止GDI+的问题。在一个window应用程序中,我们一般在程序开始时启用GDI+,在程序退出时停止它。这样的方法在ActiveX中并不适用,会出现多次加载的情况。在我的测试中,如果GDI+在继承了COleControl类的构造函数中调用,在析构函数中停止,那么每次都是好用的。
下面的程序直接写了一个类来完成GDI+的启用和停止,它确保在每个进程中只调用一次Gdiplus::GdiplusStartup。
class InitGDIPlus {
private:
    HANDLE                       m_hMap;
    bool                         m_bInited, m_bInitCtorDtor;
    ULONG_PTR                    m_gdiplusToken;
    Gdiplus::GdiplusStartupInput m_gdiplusStartupInput;
    long                         m_initcount;
 
public:
    // Constructor offers the ability to initialize on construction, or delay until needed.
    InitGDIPlus(bool bInitCtorDtor = false) : m_bInitCtorDtor(bInitCtorDtor),
                m_bInited(false), m_hMap(NULL), m_gdiplusToken(NULL),
                m_gdiplusStartupInput(NULL), m_initcount(0) 
    {
        if (m_bInitCtorDtor) {
            Initialize();
        }
    }
 
    // If GDI+ has not been explicitly Deinitialized, do it in the destructor
    virtual ~InitGDIPlus() {
        if (m_bInitCtorDtor) {
            Deinitialize();
        }
    }
 
   
//这个函数基于当前的进程创建一个文件映射,如果映射已经存在我们就知道这个类已经启用
//GDI+了,不过不存在,则启用它
    void Initialize() {
        if (!m_bInited) {
            char buffer[1024];
            sprintf(buffer, "GDIPlusInitID=%x", GetCurrentProcessId());
            m_hMap = CreateFileMapping((HANDLE) INVALID_HANDLE_VALUE, NULL,
                PAGE_READWRITE | SEC_COMMIT, 0, sizeof(long), buffer);
               
            if (m_hMap != NULL) {
                // We might have a winner
                if (GetLastError() == ERROR_ALREADY_EXISTS) {
                    CloseHandle(m_hMap);
                } else {
                    // Yes, we have a winner
                    m_bInited = true;
                    Gdiplus::GdiplusStartup(&m_gdiplusToken,
                        &m_gdiplusStartupInput, NULL);
                    TRACE("Inited GDIPlus/n");
                }
            }
        }
        m_initcount++;
    }
//这个函数没有任何窍门,如果类已经启用的GDI+,那么在初始化次数达到0时才能被关闭
    void Deinitialize()
    {
        m_initcount--;
        if (m_bInited && m_initcount == 0) {
            TRACE("GDIPlus shutdown/n");
            Gdiplus::GdiplusShutdown(m_gdiplusToken);
            CloseHandle(m_hMap);
            m_bInited = false;
        }
    }
};
 
static InitGDIPlus GDI_Plus_Controler;
CGDIPlusControlCtrl::CGDIPlusControlCtrl() : m_isClicked(false), m_center(50, 50)
{
    InitializeIIDs(&IID_DGDIPlusControl, &IID_DGDIPlusControlEvents);
 
    GDI_Plus_Controler.Initialize(); //GDI_Plus_Controler 为静态全局变量
}
 
 
/////////////////////////////////////////////////////////////////////////////
// CGDIPlusControlCtrl::~CGDIPlusControlCtrl - Destructor
 
CGDIPlusControlCtrl::~CGDIPlusControlCtrl()
{
    GDI_Plus_Controler.Deinitialize(); //GDI_Plus_Controler为静态全局变量
}
阅读更多
个人分类: 图形处理
上一篇GLM中文使用说明
下一篇Vc调用ado访问数据库
想对作者说点什么? 我来说一句

使用GDI+技术写ActiveX控件

2008年11月24日 25KB 下载

没有更多推荐了,返回首页

关闭
关闭