wtl学习笔记(1),窗口类的注册
任何非对话框窗口都是来自CWindowImpl派生
对话框窗口都是来自CDialogImpl派生
定义一个窗口的实现
你的新窗口类需要包含三件事情:
一、一个窗口类的定义,如:
默认由父类CWindowImpl的DECLARE_WND_CLASS(NULL) 完成窗口WNDCLASS结构体的定义.
也可以自己通过DECLARE_WND_CLASS(_T( " My Window Class " )) 完成窗口WNDCLASS结构体的定义.
二、添加消息映射链
其中祖先类CWindowImplRoot继承自CMessageMap
三、窗口使用的默认窗口类型,称为称为window traits
预定义的window traits:
typedef CWinTraits < WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0 > CControlWinTraits;
typedef CWinTraits < WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE > CFrameWinTraits;
typedef CWinTraits < WS_OVERLAPPEDWINDOW | WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_MDICHILD > CMDIChildWinTraits;
typedef CWinTraits < 0 , 0 > CNullTraits;
类继承关系:
template < class T, class TBase /* = CWindow */ , class TWinTraits /* = CControlWinTraits */ >
class ATL_NO_VTABLE CWindowImpl : public CWindowImplBaseT < TBase, TWinTraits >
{
};
template < class TBase = CWindow, class TWinTraits = CControlWinTraits >
class ATL_NO_VTABLE CWindowImplBaseT : public CWindowImplRoot < TBase >
{
public :
WNDPROC m_pfnSuperWindowProc;
CWindowImplBaseT() : m_pfnSuperWindowProc(::DefWindowProc)
{}
};
template < class TBase /* = CWindow */ >
class ATL_NO_VTABLE CWindowImplRoot : public TBase, public CMessageMap
{
};
// 窗口类的注册,宏:DECLARE_WND_CLASS
#define DECLARE_WND_CLASS(WndClassName) \
static ATL::CWndClassInfo & GetWndClassInfo() \
{ \
static ATL::CWndClassInfo wc = \
{ \
{ sizeof (WNDCLASSEX), CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, StartWindowProc, \
0 , 0 , NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1 ), NULL, WndClassName, NULL }, \
NULL, NULL, IDC_ARROW, TRUE, 0 , _T( "" ) \
}; \
return wc; \
}
全局变量:_AtlWinModule,_AtlBaseModule
extern CAtlWinModule _AtlWinModule;
extern CAtlBaseModule _AtlBaseModule;
// 窗口类WNDCLASS结构体的填充
struct _ATL_WNDCLASSINFOA
{
WNDCLASSEXA m_wc;
LPCSTR m_lpszOrigName;
WNDPROC pWndProc;
LPCSTR m_lpszCursorID;
BOOL m_bSystemCursor;
ATOM m_atom;
CHAR m_szAutoName[ 5 + sizeof ( void * ) * CHAR_BIT];
ATOM Register(WNDPROC * p)
{
return AtlWinModuleRegisterWndClassInfoA( & _AtlWinModule, & _AtlBaseModule, this , p);
}
};
typedef _ATL_WNDCLASSINFOA CWndClassInfoA;
窗口注册过程
CMainFrame wndMain;
CFrameWindowImpl::Create()
ATOM atom = T::GetWndClassInfo().Register( & m_pfnSuperWindowProc);
// 模板展开后
// ATOM atom = CMainFrame::GetWndClassInfo().Register(&m_pfnSuperWindowProc);
// 这里的T就是类 CMainFrame
// 然后通过如下代码,返回一个静态变量 static WTL::CFrameWndClassInfo wc;
CFrameWndClassInfo::Register( & m_pfnSuperWindowProc);
// CWindowImplBaseT::m_pfnSuperWindowProc
// CWindowImplBaseT() : m_pfnSuperWindowProc(::DefWindowProc){}
对话框窗口都是来自CDialogImpl派生
定义一个窗口的实现
你的新窗口类需要包含三件事情:
一、一个窗口类的定义,如:
默认由父类CWindowImpl的DECLARE_WND_CLASS(NULL) 完成窗口WNDCLASS结构体的定义.
也可以自己通过DECLARE_WND_CLASS(_T( " My Window Class " )) 完成窗口WNDCLASS结构体的定义.
二、添加消息映射链
其中祖先类CWindowImplRoot继承自CMessageMap
三、窗口使用的默认窗口类型,称为称为window traits
预定义的window traits:
typedef CWinTraits < WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0 > CControlWinTraits;
typedef CWinTraits < WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE > CFrameWinTraits;
typedef CWinTraits < WS_OVERLAPPEDWINDOW | WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_MDICHILD > CMDIChildWinTraits;
typedef CWinTraits < 0 , 0 > CNullTraits;
类继承关系:
template < class T, class TBase /* = CWindow */ , class TWinTraits /* = CControlWinTraits */ >
class ATL_NO_VTABLE CWindowImpl : public CWindowImplBaseT < TBase, TWinTraits >
{
};
template < class TBase = CWindow, class TWinTraits = CControlWinTraits >
class ATL_NO_VTABLE CWindowImplBaseT : public CWindowImplRoot < TBase >
{
public :
WNDPROC m_pfnSuperWindowProc;
CWindowImplBaseT() : m_pfnSuperWindowProc(::DefWindowProc)
{}
};
template < class TBase /* = CWindow */ >
class ATL_NO_VTABLE CWindowImplRoot : public TBase, public CMessageMap
{
};
// 窗口类的注册,宏:DECLARE_WND_CLASS
#define DECLARE_WND_CLASS(WndClassName) \
static ATL::CWndClassInfo & GetWndClassInfo() \
{ \
static ATL::CWndClassInfo wc = \
{ \
{ sizeof (WNDCLASSEX), CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, StartWindowProc, \
0 , 0 , NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1 ), NULL, WndClassName, NULL }, \
NULL, NULL, IDC_ARROW, TRUE, 0 , _T( "" ) \
}; \
return wc; \
}
全局变量:_AtlWinModule,_AtlBaseModule
extern CAtlWinModule _AtlWinModule;
extern CAtlBaseModule _AtlBaseModule;
// 窗口类WNDCLASS结构体的填充
struct _ATL_WNDCLASSINFOA
{
WNDCLASSEXA m_wc;
LPCSTR m_lpszOrigName;
WNDPROC pWndProc;
LPCSTR m_lpszCursorID;
BOOL m_bSystemCursor;
ATOM m_atom;
CHAR m_szAutoName[ 5 + sizeof ( void * ) * CHAR_BIT];
ATOM Register(WNDPROC * p)
{
return AtlWinModuleRegisterWndClassInfoA( & _AtlWinModule, & _AtlBaseModule, this , p);
}
};
typedef _ATL_WNDCLASSINFOA CWndClassInfoA;
窗口注册过程
CMainFrame wndMain;
CFrameWindowImpl::Create()
ATOM atom = T::GetWndClassInfo().Register( & m_pfnSuperWindowProc);
// 模板展开后
// ATOM atom = CMainFrame::GetWndClassInfo().Register(&m_pfnSuperWindowProc);
// 这里的T就是类 CMainFrame
// 然后通过如下代码,返回一个静态变量 static WTL::CFrameWndClassInfo wc;
CFrameWndClassInfo::Register( & m_pfnSuperWindowProc);
// CWindowImplBaseT::m_pfnSuperWindowProc
// CWindowImplBaseT() : m_pfnSuperWindowProc(::DefWindowProc){}
#include
<
atlbase.h
>
#include < atlwin.h >
// 可选的消息处理类
template < typename T >
class CPaintBkgnd : public CMessageMap
{
public :
BEGIN_MSG_MAP(CPaintBkgnd)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
END_MSG_MAP()
LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
{
T * pT = static_cast < T *> ( this );
HDC dc = (HDC)wParam;
RECT rcClient;
pT -> GetClientRect ( & rcClient );
::FillRect(dc, & rcClient, CreateSolidBrush(RGB( 0xff , 0x66 , 0x99 )) );
return 1 ;
}
};
class CMyWindow :
public CWindowImpl < CMyWindow, CWindow,CFrameWinTraits > ,
public CPaintBkgnd < CMyWindow >
{
public :
// DECLARE_WND_CLASS(_T("abc"))
BEGIN_MSG_MAP(CMyWindow)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_CLOSE, OnClose)
// CHAIN_MSG_MAP(CPaintBkgnd)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
END_MSG_MAP()
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
{
ATLTRACE( " WM_CREATE==0x0001,MSG ID:0x%u\n " ,uMsg);
return 0 ;
}
LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
{
DestroyWindow();
PostQuitMessage( 0 );
return 0 ;
}
LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
{
HDC dc = (HDC) wParam;
RECT rcClient;
this -> GetClientRect ( & rcClient );
::FillRect(dc, & rcClient, CreateSolidBrush(RGB( 0xff , 0x66 , 0x00 )) );
return 1 ;
}
};
int _tWinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */ , LPTSTR lpstrCmdLine, int nCmdShow)
{
CMyWindow wndMain;
HWND hWnd = wndMain.Create(NULL,NULL, " good luck Aaron " );
if (hWnd == NULL)
{
::MessageBox(NULL, " 创建窗口失败 " , " 提示 " ,MB_OK);
}
wndMain.ShowWindow(nCmdShow);
wndMain.UpdateWindow();
MSG msg;
while ( GetMessage ( & msg, NULL, 0 , 0 ) > 0 )
{
TranslateMessage ( & msg );
DispatchMessage ( & msg );
}
return 0 ;
}
#include < atlwin.h >
// 可选的消息处理类
template < typename T >
class CPaintBkgnd : public CMessageMap
{
public :
BEGIN_MSG_MAP(CPaintBkgnd)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
END_MSG_MAP()
LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
{
T * pT = static_cast < T *> ( this );
HDC dc = (HDC)wParam;
RECT rcClient;
pT -> GetClientRect ( & rcClient );
::FillRect(dc, & rcClient, CreateSolidBrush(RGB( 0xff , 0x66 , 0x99 )) );
return 1 ;
}
};
class CMyWindow :
public CWindowImpl < CMyWindow, CWindow,CFrameWinTraits > ,
public CPaintBkgnd < CMyWindow >
{
public :
// DECLARE_WND_CLASS(_T("abc"))
BEGIN_MSG_MAP(CMyWindow)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_CLOSE, OnClose)
// CHAIN_MSG_MAP(CPaintBkgnd)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
END_MSG_MAP()
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
{
ATLTRACE( " WM_CREATE==0x0001,MSG ID:0x%u\n " ,uMsg);
return 0 ;
}
LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
{
DestroyWindow();
PostQuitMessage( 0 );
return 0 ;
}
LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
{
HDC dc = (HDC) wParam;
RECT rcClient;
this -> GetClientRect ( & rcClient );
::FillRect(dc, & rcClient, CreateSolidBrush(RGB( 0xff , 0x66 , 0x00 )) );
return 1 ;
}
};
int _tWinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */ , LPTSTR lpstrCmdLine, int nCmdShow)
{
CMyWindow wndMain;
HWND hWnd = wndMain.Create(NULL,NULL, " good luck Aaron " );
if (hWnd == NULL)
{
::MessageBox(NULL, " 创建窗口失败 " , " 提示 " ,MB_OK);
}
wndMain.ShowWindow(nCmdShow);
wndMain.UpdateWindow();
MSG msg;
while ( GetMessage ( & msg, NULL, 0 , 0 ) > 0 )
{
TranslateMessage ( & msg );
DispatchMessage ( & msg );
}
return 0 ;
}