文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>采用模板的手法服用CWnd类

采用模板的手法服用CWnd类

时间:2010-11-14  来源:方外之士

    .h文件:

      代码

template<typename T>
class CAuxWindowT : public CWnd
{
    DECLARE_DYNAMIC(CAuxWindowT)
public:
    CAuxWindowT();   // 标准构造函数
    virtual ~CAuxWindowT();

public:
    BOOL CreateWnd(DWORD dwExStyle, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, LPVOID lpParam = NULL);

protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

    DECLARE_MESSAGE_MAP()
    int  OnCreate(LPCREATESTRUCT lpCreateStruct);
    void OnPaint();
    BOOL OnEraseBkgnd(CDC* pDC);
};

#include "AuxWindow.inl"

 

 文件AuxWindow.inl的代码如下:

代码 #define DECLARE_TEMPLATE_THIS_POINTER(type, var)      \
    type* var = static_cast<type*>(this);    \
    ATLASSERT(var != NULL);

//IMPLEMENT_DYNAMIC_T(CAuxWindowT, T, CWnd)

template<typename T>
CAuxWindowT<T>::CAuxWindowT()
{

}

template<typename T>
CAuxWindowT<T>::~CAuxWindowT()
{
}

template<typename T>
BOOL CAuxWindowT<T>::CreateWnd(DWORD dwExStyle, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, LPVOID lpParam)
{
    DECLARE_TEMPLATE_THIS_POINTER(T, pThis);

    CAuxInitWinStruct<WNDCLASSEX>  wndClass;
    wndClass.lpfnWndProc    = ::DefWindowProc;
    wndClass.hInstance        = AfxGetInstanceHandle();
    wndClass.lpszClassName    = pThis->GetRegisterClassName();
    AUX_ASSERT_FAILED_RETURN_VALUE(AuxRegisterWindowClass(&wndClass), FALSE);
    AUX_ASSERT_FAILED_RETURN_VALUE(this->CreateEx(dwExStyle, pThis->GetRegisterClassName(), lpszWindowName, dwStyle, rect, pParentWnd, nID, lpParam), FALSE);

    return TRUE;
}

template<typename T>
void CAuxWindowT<T>::DoDataExchange(CDataExchange* pDX)
{
    CWnd::DoDataExchange(pDX);
}

BEGIN_TEMPLATE_MESSAGE_MAP(CAuxWindowT, T, CWnd)
    ON_WM_CREATE()
    ON_WM_PAINT()
    ON_WM_ERASEBKGND()
END_MESSAGE_MAP()

template<typename T>
int  CAuxWindowT<T>::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    int nRet = 1;

    __if_exists(T::InsideCreate)
    {
        DECLARE_TEMPLATE_THIS_POINTER(T, pThis);
        nRet = pThis->InsideCreate(lpCreateStruct);
    }
    return nRet;
}

template<typename T>
void CAuxWindowT<T>::OnPaint()
{
    __if_exists(T::InsidePaint)
    {
        DECLARE_TEMPLATE_THIS_POINTER(T, pThis);
        pThis->InsidePaint();
    }

    __if_not_exists(T::InsidePaint)
    {
        CPaintDC dc(this);
    }
}

template<typename T>
BOOL CAuxWindowT<T>::OnEraseBkgnd(CDC* pDC)
{
    __if_not_exists(T::InsideEraseBkgnd)
    {
        return CWnd::OnEraseBkgnd(pDC);
    }

    DECLARE_TEMPLATE_THIS_POINTER(T, pThis);
    return pThis->InsideEraseBkgnd(pDC);
}

 

 这种封装很大的问题在于CWnd的消息映射宏只能映射到自己类中的某个方法,故而我只有在封装中加了一层转发接口,在这里调用派生类的相应的方法(如果有的话).如果完全定制BEGIN_MESSAGE_MAP/ END_MESSAGE_MAP宏使其保存指向派生类的方法,可以实现,但改动实在较大(不亚于自己重头开始写一个窗口类了),而且代码复用的优点也削弱了不少。

派生类的定义:代码

class CFadeWindow : public CAuxWindowT<CFadeWindow>
{
    DECLARE_DYNAMIC(CFadeWindow)

public:
    CFadeWindow();   // 标准构造函数
    virtual ~CFadeWindow();

public:
    LPCTSTR GetRegisterClassName()
    {
         return _T("SinaShowFadeWindow");
    }

    int  InsideCreate(LPCREATESTRUCT lpCreateStruct);

    void InsidePaint();

    BOOL InsideEraseBkgnd(CDC* pDC);
}; 

// .cpp

IMPLEMENT_DYNAMIC(CFadeWindow, CAuxWindowT<CFadeWindow>)  


 代码注解:__if_exists和__if_not_exists用于判断某个标识符是否存在,其不能与else共用,所以提供2个相反的关键字。

             CAuxInitWinStruct:用于初始化Windows结构体的封装

             定义如下:

             代码

    //
    // 封装Windows常用的结构体
    // 自动进行清零操作和设置Windows结构体的cbSize字段
    //
    template<typename TBase>
    class  CAuxInitWinStruct : public TBase
    {
    public:
        CAuxInitWinStruct()
        {
            ::ZeroMemory(this, sizeof(TBase));
            this->cbSize   =  sizeof(TBase);
        }

        CAuxInitWinStruct(const TBase& var)
        {
            memcpy(this, &var, sizeof(TBase));
        }
    };

 

     AuxRegisterWindowClass:窗口类注册实现, 代码如下:

         代码

// 注册窗口类
    inline BOOL  AuxRegisterWindowClass(const WNDCLASSEX* pWndClass)
    {
        ATLASSERT(pWndClass != NULL);

        BOOL  bSuccess  =  TRUE;

        // 先检测窗口是否注册过
        WNDCLASSEX wndClassDummy;
        BOOL bRegistered = ::GetClassInfoEx(pWndClass->hInstance, pWndClass->lpszClassName, &wndClassDummy);

        if (!bRegistered || (wndClassDummy.lpfnWndProc != pWndClass->lpfnWndProc))
        { 
            // 如果未注册或者注册的窗口过程不是本地的函数地址, 则重新注册
            if (bRegistered)
            {
                // 如果已注册 则先取消注册
                ::UnregisterClass(wndClassDummy.lpszClassName, pWndClass->hInstance);
            }

            // 注册窗口
            bSuccess = (::RegisterClassEx(pWndClass) != 0) ? TRUE : FALSE;
        }

        return bSuccess;
    }

 

 

 

 

相关阅读 更多 +
排行榜 更多 +
边境检察最后区域手机版下载

边境检察最后区域手机版下载

角色扮演 下载
酋长你别跑手游下载

酋长你别跑手游下载

休闲益智 下载
心动漫画app下载官方版

心动漫画app下载官方版

浏览阅读 下载