Defining a Window Implementation
定义一个窗体实现
Any non-dialog window you create will derive from CWindowImpl. Your new class needs to contain three things:
你所产生的任何非对话框的窗体都将从CWindowImpl派生,你需要为你的新类做下面的3件事:
1. A window class definition
2. A message map
3. The default styles to use for the window, called the window traits
1. 一个窗体类的定义
2. 一个消息映射
3. 调用窗体特征为窗体使用缺省的风格。
The window class definition is done using the DECLARE_WND_CLASS or DECLARE_WND_CLASS_EX macro. Both of these define an ATL struct CWndClassInfo that wraps the WNDCLASSEX struct. DECLARE_WND_CLASS lets you specify the new window class name and uses default values for the other members, while DECLARE_WND_CLASS_EX lets you also specify a class style and window background color. You can also use NULL for the class name, and ATL will generate a name for you.
窗体类的定义需要使用DECLARE_WND_CLASS或DECLARE_WND_CLASS_EX宏。这两个宏都将定义一个封装了WNDCLASSEX结构的ATL结构CWndClassInfo。DECLARE_WND_CLASS允许你提供一个新的窗体名并对其他的窗体参数赋缺省值,DECLARE_WND_CLASS_EX允许你提供一个类的风格和窗体的背景色。你可以将类名赋空值,ATL将自动为你生成一个类名。
Let's start out a new class definition, and I'll keep adding to it as we go through this section.
让我们开始一个新的类定义,我将在本章中不断地为它加入新的内容。
class CMyWindow : public CWindowImpl<CMyWindow>
{
public:
DECLARE_WND_CLASS(_T("My Window Class"))
};
Next comes the message map. ATL message maps are much simpler than MFC maps. An ATL map expands into a big switch statement; the switch looks for the right handler and calls the corresponding function. The macros for the message map are BEGIN_MSG_MAP and END_MSG_MAP. Let's add an empty map to our window.
下面开始消息映射。ATL的消息映射比MFC简单的多。它就像一个大的switch语句,通过switch找到正确的句柄并执行相应的函数。消息映射宏是BEGIN_MSG_MAP和END_MSG_MAP。下面让我们添加一个空的消息映射到我们的窗体。
class CMyWindow : public CWindowImpl<CMyWindow>
{
public:
DECLARE_WND_CLASS(_T("My Window Class"))
BEGIN_MSG_MAP(CMyWindow)
END_MSG_MAP()
};
I'll cover how to add handlers to the map in the next section. Finally, we need to define the window traits for our class. Window traits are a combination of window styles and extended window styles that are used when creating the window. The styles are specified as template parameters so the caller doesn't have to be bothered with getting the styles right when it creates our window. Here's a sample traits definition using the ATL class CWinTraits:
我将在下一节讲述如何添加一个句柄到映射中。最后,我们需要为我们的类定义窗体特征。窗体特征是产生窗体时使用的窗体风格和扩展窗体风格的合并。它像模板参数一样提供,使得调用程序不必再为产生窗体时如何取到正确的风格而烦恼。下面是一个使用ATL类CWinTraits定义特征的简单例子:
typedef CWinTraits<WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
WS_EX_APPWINDOW> CMyWindowTraits;
class CMyWindow : public CWindowImpl<CMyWindow, CWindow, CMyWindowTraits>
{
public:
DECLARE_WND_CLASS(_T("My Window Class"))
BEGIN_MSG_MAP(CMyWindow)
END_MSG_MAP()
};
The caller can override the styles in the CMyWindowTraits definition, but generally this is not necessary. ATL also has a few predefined CWinTraits specializations, one of which is perfect for top-level windows like ours, CFrameWinTraits:
调用程序能够在CMyWindowTraits定义时重载风格,但这并不是很必要的。ATL也提供一些预定义的CWinTraits的特殊形式,如为顶级窗体使用的CFrameWinTraits:
typedef CWinTraits<WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN |
WS_CLIPSIBLINGS,
WS_EX_APPWINDOW | WS_EX_WINDOWEDGE>
CFrameWinTraits;