返回首页

简介
这里是一个非常简单的原子类型的包装器,它支持最简单的原子API的。类的接口非常简单,不需要任何说明。类的源代码是非常小的,所以我张贴在这里:

///////////////////////////////////////////////////////////////////////////////

// CAtomT - ATOM type wrapper



template[bool t_bGlobal]

class CAtomT

{

public:

    ATOM m_Atom;



public:

    enum AtomType

    {

        ATOM_INTEGER = 0,

        ATOM_STRING

    };



public:

    CAtomT(ATOM Atom = 0) : m_Atom(Atom)

    { }



    CAtomT& operator=(const CAtomT& Atom)

    {

        if (this != &Atom)

            m_Atom = Atom;



        return (*this);

    }



    operator ATOM() const

    {

        return m_Atom;

    }



    bool IsValid() const

    {

        return (m_Atom != 0);

    }



    AtomType GetType() const

    {

        ATLASSERT(IsValid());

        return (m_Atom < MAXINTATOM) ? ATOM_INTEGER : ATOM_STRING;

    }



    bool GetName(LPTSTR lpNameBuffer, int nBufferSize) const

    {

        ATLASSERT(IsValid());

        ATLASSERT(lpNameBuffer != NULL);

        if (t_bGlobal)

            return (::GlobalGetAtomName(m_Atom, lpNameBuffer, nBufferSize) != 0);

        else

            return (::GetAtomName(m_Atom, lpNameBuffer, nBufferSize) != 0);

    }



#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)

    bool GetName(_CSTRING_NS::CString& strName) const

    {

        ATLASSERT(IsValid());

        const size_t MAX_ATOM_NAME_SIZE = 255;

        LPTSTR lpNameBuffer = strName.GetBufferSetLength(MAX_ATOM_NAME_SIZE);

        if (lpNameBuffer != NULL)

        {

            bool bRes = GetName(lpNameBuffer, MAX_ATOM_NAME_SIZE);

            strName.ReleaseBuffer();

            return bRes;

        }

        else

            return false;

    }

#endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)



    bool Delete()

    {

        ATLASSERT(IsValid());

        if (t_bGlobal)

            m_Atom = ::GlobalDeleteAtom(m_Atom);

        else

            m_Atom = ::DeleteAtom(m_Atom);

        return (!IsValid());

    }



public:

    static CAtomT Add(ATL::_U_STRINGorID AtomName)

    {

        if (t_bGlobal)

            return CAtomT(::GlobalAddAtom(AtomName.m_lpstr));

        else

            return CAtomT(::AddAtom(AtomName.m_lpstr));

    }



    static CAtomT Find(ATL::_U_STRINGorID AtomName)

    {

        if (t_bGlobal)

            return CAtomT(::GlobalFindAtom(AtomName.m_lpstr));

        else

            return CAtomT(::FindAtom(AtomName.m_lpstr));

    }

};



#ifndef _WIN32_WCE

typedef CAtomT<false> CAtom;

#endif // _WIN32_WCE

typedef CAtomT<true> CGlobalAtom;

回答

评论会员:雷蒙 时间:2011/12/07
所有第一,我不使用,因为我停止了原子​​的DDE(DDEML)协议
。可用于其他地方吗?

现在你的代码:
1。由于每个局部和全局原子的API有相同的原型,CAtomT模板可以使用静态方法添加一个类模板,查找,...
,而不是一个BOOL的值始终检查!
全球政策:
/ / ================================================ ==================={ BR}/ /所有的静态方法来处理全局原子。全局原子 / /所有的应用程序。GlobalPolicy
{
枚举TableType {IsLocal = 0,IsGlobal = 1}

静态原子添加(LPCTSTR lpString)
{
返回(::GlobalAddAtom(lpString))
}

静态的ATOM查找(LPCTSTR lpString)
{
返回(::GlobalFindAtom(lpString))
}

静态布尔删除(一个原子一个原子)
{
::SetLastError(ERROR_SUCCESS)
VERIFY(:GlobalDeleteAtom(原子)==(ATOM)0);
返回(::GetLastError函数()== ERROR_SUCCESS)
}

静态的UINT的GetName(一个原子一个原子,LPTSTR lpNameBuffer,nBufferSize INT)
{
ASSERT(lpNameBuffer = NULL)
返回(::GlobalGetAtomName(原子,lpNameBuffer,nBufferSize))
}
}
本地策略:

LocalPolicy
{
枚举TableType {IsGlobal = 0,IsLocal = 1}

静态原子添加(LPCTSTR lpString)
{
返回(::AddAtom(lpString))
}

静态的ATOM查找(LPCTSTR lpString)
{
返回(::FindAtom(lpString))
}

静态布尔删除(一个原子一个原子)
{
返回(::DeleteAtom(原子)==(原子)0);
}

静态的UINT的GetName(一个原子一个原子,LPTSTR lpNameBuffer,nBufferSize INT)
{
ASSERT(lpNameBuffer = NULL)
返回(::GetAtomName(原子,lpNameBuffer,nBufferSize))
}
}

CAtomT模板:

模板类CAtomT {
...
BOOL删除()
{
ASSERT(IsValid的());{ BR}& #160; (M:删除(m_Atom))m_Atom = 0;
  ; 返回(!的IsValid ());{ BR} }

市民:
静态CAtomT地址(LPCTSTR AtomName)
{
返回(CAtomT(M:添加(AtomName )));{ BR} }
...
最后,在typedef:
的typedef CAtomT CAtom;
的typedef CAtomT CGlobalAtom;

评论会员:雷蒙 时间:2011/12/07
2。每次添加模板不处理,原子必须删除

微软说:"每个AddAtom调用应该有一个相应的调用,以DeleteAtom不要叫DeleteAtom更多的时间比你调用AddAtom,而其他客户端使用它,你可能会删除原子。"

事实上,CAtomT应该有一个析构函数调用Delete成员只有当嵌入原子是由添加成员创建的。

但在这种情况下,复制操作?复制原子获得查找的成员很简单,因为没有破坏应该发生。但是,大约一个原子获得通过添加成员?第一反应是再次调用添加成员。但是,让我们来看看。

另一方面,由于模板CTOR是从一个原子和默认的(唯一的)转换运算符是原子,可以很容易地混合本地及全球的原子。

混合局部/全局原子:

CAtom ATM1(CGlobalAtom:(TEXT("URP混合局部/全局原子!!")))

复搅局部/全局原子内存泄漏:

ATM1 = CAtom(CGlobalAtom:添加(TEXT("!!URP重新混合局部/全局原子加内存泄漏")))

更多的递增原子的引用计数递减可能会删除其他客户端的ATOM:

CAtom ATM2;
ATM2 = ATM1;
atm2.Delete()
atm1.Delete()

由于这些原因,我认为应该隐藏模板类型的原子(没有CTOR作为paramater原子),并使用一个引用计数的对象持有的原子和"自动删除"布尔值,这将解决复制的问题一次,而无需调用添加成员。

类似的东西... ...

模板LT,M级= LocalPolicy>
TImpl类:公共IFACE
{
市民:
TImpl()
{
}

TImpl(常量名Ato​​mName,BOOL bLookupOnly = FALSE)
{
(bLookupOnly)查找(AtomName)
其他新增(AtomName);
}

虚拟〜TImpl()
{
(m_bAutoDelete)删除();}

BOOL添加(常量名Ato​​mName)
{
(m_bAutoDelete)
VERIFY(删除())
m_Atom = M:添加(AtomName)
返回(m_bAutoDelete = m_Atom.IsValid())
}

BOOL查找(常量名Ato​​mName)
{
(m_bAutoDelete)
VERIFY(删除())
m_Atom = M:查找(AtomName)
返回(m_Atom.IsValid())
}

BOOL删除()
{
IFNDEF NDEBUG#
(M:IsGlobal m_Atom.IsInteger())
TRACE(TEXT("GlobalDeleteAtom整数原子\ N "));{ BR没有影响}#ENDIF
(m_bAutoDelete)
{
ASSERT(m_Atom.IsValid())
(男::删除(m_Atom))
(假);
} m_Atom =(凌动)0;
m_bAutoDelete = FALSE;
(TRUE);
}


评论会员:armentage 时间:2011/12/07
原子这是一个包装吗?
评论会员:isemenov 时间:2011/12/07
这是一个Win32的原子类型(全局和局部的原子)的包装。
评论会员:肖恩Poulson 时间:2011/12/07
你能使用这个吗?如何解决一些问题的例子?

---
肖恩Poulson
spoulson@explodingcoder.com
评论会员:isemenov 时间:2011/12/07
我就例如工作。我将它张贴在这里很快。