wtl学习笔记(1),窗口类的注册

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){}





 

#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 ;
}

 

你可能感兴趣的:(wtl学习笔记(1),窗口类的注册)