Welcome

首页 / 软件开发 / C++ / ATL布幔之下的秘密(5)

ATL布幔之下的秘密(5)2010-11-22李马介绍

很多人认为ATL只是用来编写COM组件的,其实你也可以使用ATL 中的窗口类来创建基于窗口的应用程序。虽然你可以将基于MFC的程序转换为ATL ,但是ATL中对于UI(译注:用户界面)组件的支持太少了。所以,这就要求你 需要自己编写很多代码。例如,在ATL中没有文档/视图,所以在你想使用它的时 候就需要自己实现了。在本篇中,我们将要探究一些关于窗口类的秘密,以及 ATL技术实现的秘密。WTL(Window Template Library,窗口模板库),虽然到 现在(译注:本文于2002年10月27日发表在CodeProject)还不为Microsoft所支 持,但是它在制作图形应用程序方面跨出了一大步。WTL就是基于ATL的窗口类的 。

在开始讨论基于ATL的程序之前,让我们从一个经典的Hello world程序开始吧。这个程序完全用SDK编写,并且我们中几乎所有人都已经熟悉它了。

程序66.

#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
char szAppName[] = "Hello world";
HWND hWnd;
MSG msg;
WNDCLASS wnd;

wnd.cbClsExtra = NULL;
wnd.cbWndExtra = NULL;
wnd.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
wnd.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wnd.hInstance = hInstance;
wnd.lpfnWndProc = WndProc;
wnd.lpszClassName = szAppName;
wnd.lpszMenuName = NULL;
wnd.style = CS_HREDRAW | CS_VREDRAW;

if (!RegisterClass (&wnd))
{
MessageBox(NULL, "Can not register window class", "Error",
MB_OK | MB_ICONINFORMATION);
return -1;
}

hWnd = CreateWindow(szAppName, "Hello world", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

while (GetMessage(&msg, NULL, 0, 0))
{
DispatchMessage(&msg);
}

return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
RECT rect;
switch (uMsg)
{
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
DrawText(hDC, "Hello world", -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
}

return DefWindowProc(hWnd, uMsg, wParam, lParam);
}