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

翻译 2007年09月13日 13:04:00
  
在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为静态全局变量
}

相关文章推荐

WTL for MFC Programmers, Part VI - Hosting ActiveX Controls

介绍 在第六章,我将介绍ATL对在对话框中使用ActiveX控件的支持,由于ActiveX控件就是ATL的专业,所以WTL没有添加其他的辅助类。不过,在ATL中使用ActiveX控件与在MFC中有很...
  • zcxin
  • zcxin
  • 2013-10-30 01:34
  • 762

二:在VC6.0中用GDI+调用png图片实现半透明渐变的特效窗口

在VC6.0中用GDI+调用png图片实现半透明渐变的特效窗口作者:邵凯锋下载源代码一、概述  GDI+的应用使得平面图形图象编程变的更加容易,本文以一个基于对话框的时钟程序为例,在VC6.0中调用*...

Resizing a Photographic image with GDI+ for .NET

http://www.codeproject.com/KB/GDI-plus/imageresize.aspx This article describes the various techni...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)