ATL是微软继MFC之后提供的一套C++模板类库,小巧、精妙、效率极高。它的主要作用是为我们编写COM/DOM/COM+程序提供了丰富的支持。但是ATL只能写COM么?我以前只是MFC程序员的时候,一直有此误解。但其实ATL提供了很多类用来帮助编写WIN32窗口程序,可能没有MFC使用的广泛和方便(当然啦,因为ATL本来难度就较一般的C++类库大)。用ATL编写WIN32窗口程序有什么好处?小巧、效率这些好处之外,还有一个我认为非常大的好处,写一个EXE形式的COM服务程序,该程序拥有自己的窗口可以和用户交互。你想象一下,一个友好的窗口程序,同时暴露了一些COM接口使得可以和其他程序跨进程通信,是不是非常的便利呢?
使用ATL编写WIN32窗口应用程序你具备以下基础知识,包括WIN32SDK编程能力、C++模板技术、COM编程的能力。要求很高啊,正因为这样,才萌发了写这篇文章的念头。
第一章 HWND和CWindow类
HWND是WINDOWS窗口的灵魂,每个窗口都对应一个HWND变量,称为窗口句柄。
我们可以通过HWND向窗口发送消息,让窗口做一些我们想要的动作或者获取窗口的某些信息(比如设置/窗口标题)。
CWindow类保存了窗口句柄,并且包装了一些常用的基于窗口句柄的对窗口的操作。CWindow类定义在atlwin.h文件中。CWindow类提供了很多成员变量和函数,有几个比较重要的:
HWND m_hWnd;//保存了窗口句柄
static RECT rcDefault;//静态变量,保存了默认的窗口的初始位置和大小
_declspec
(selectany) RECT CWindow::rcDefault = { CW_USEDEFAULT, CW_USEDEFAULT, 0, 0 };
Create成员函数:
HWND Create(LPCTSTR lpstrWndClass, HWND hWndParent, _U_RECT rect = NULL, LPCTSTR szWindowName = NULL,DWORD dwStyle = 0, DWORD dwExStyle = 0,
_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
throw()
{
ATLASSERT(m_hWnd == NULL);
if(rect.m_lpRect == NULL)
rect.m_lpRect = &rcDefault;
m_hWnd = ::CreateWindowEx(dwExStyle, lpstrWndClass, szWindowName,
dwStyle, rect.m_lpRect->left, rect.m_lpRect->top, rect.m_lpRect->right - rect.m_lpRect->left,
rect.m_lpRect->bottom - rect.m_lpRect->top, hWndParent, MenuOrID.m_hMenu,
_AtlBaseModule.GetModuleInstance(), lpCreateParam);
return m_hWnd;
}
Creat函数第一步,检测窗口是否已经拥有句柄,然后判断;第二步,检测 rect参数的变量m_plpRect是否为NULL,rect类型为
class
_U_RECT
{
public
:
_U_RECT(LPRECT lpRect) : m_lpRect(lpRect)