作者:姜江
QQ:457283
E-mail:jznsmail@163.net
ATLAPP.H包含了消息循环类、接口类、和产生应用程序所必需的一些基础类定义。
类定义如下:
CmessageFilter类---用于消息过滤的
CidleHandler 类---用于空闲消息处理的
CmessageLoop类---用于消息循环的
CappModule 类---应用程序基础类
CserverAppModule类---用于Com服务构架的应用程序类
另外还有3个全局函数:
AtlGetDefaultGuiFont()获得默认的显示字体
AtlCreateBoldFont() 产生一个粗体字体
AtlInitCommonControls()初始化一些控件所需共同的DLL
WTL程序的结构
一个窗口程序的创建到销毁过程主要经过如下几个阶段
1. 注册窗口类
2. 创建窗口
3. 进入消息循环
如果用C写过Win32窗口程序的人一定会记得如下的结构:
//窗口过程处理函数
LRESULT CALLBACK WndProc(HWND hwnd,UINT Message,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR szCmdLine,int iCmdShow)
{
HWND hwnd = NULL;
MSG msg;
…
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
…
//注册窗口
if(!RegisterClass(&wndclass))
{
MessageBox(NULL,TEXT("Porgram requires Windows NT!"),szAppName,MB_ICONERROR);
return 0;
}
//创建窗口
hwnd = CreateWindow(szAppName,TEXT("My Application"),
WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,iCmdShow);
UpdateWindow(hwnd);
//进入消息循环
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
那么你可能会问WTL的WinMain函数再哪里?如果你通过WTL/ATL导向生成一个应用程序,那么你会在跟工程名字同名的.cpp文件中发现如下的代码:
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
HRESULT hRes = ::CoInitialize(NULL);
// If you are running on NT 4.0 or higher you can use the following call instead to
// make the EXE free threaded. This means that calls come in on a random RPC thread.
// HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
ATLASSERT(SUCCEEDED(hRes));
// this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used
::DefWindowProc(NULL, 0, 0, 0L);
AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES); // add flags to support other controls
hRes = _Module.Init(NULL, hInstance); //等下分析它的实现 ATLASSERT(SUCCEEDED(hRes));
int nRet = Run(lpstrCmdLine, nCmdShow);//程序的关键分
_Module.Term();
::CoUninitialize();
return nRet;