首先还是让我们来看看WTL是怎样封装应用程序线程的。
和ATL类似,WTL使用一个_Module全局变量来保存全局数据,并通过它来引用应用程序级的代码。在WTL中,该变量是CAppModule或CServerAppModule的实例。后者通常作为COM服务器的应用程序。
每个应用程序都有一个或多个界面线程组成。首先剖析一下WTL是怎样管理只有一个界面线程的(除了Mutli-SDI应用程序)。
单个界面线程的封装
先看应用程序的入口函数。
在上面的代码中,_Module是一个全局变量,这里是CAppModule的一个实例。而CAppModule类是对应用程序的封装。它封装了诸如初始化模块等功能。一个_Module还维持一个消息循环Map。
入口函数名为_tWinMain()。当使用UNICODE时,编译器会将它替换为wWinMain(),否则,为WinMain()。入口函数其实就是主线程(_Module)的起始点。
在该函数中,最关键的逻辑是调用了全局函数Run(),它是核心程序逻辑所在。
下面来看一下这个函数。
和ATL类似,WTL使用一个_Module全局变量来保存全局数据,并通过它来引用应用程序级的代码。在WTL中,该变量是CAppModule或CServerAppModule的实例。后者通常作为COM服务器的应用程序。
每个应用程序都有一个或多个界面线程组成。首先剖析一下WTL是怎样管理只有一个界面线程的(除了Mutli-SDI应用程序)。
先看应用程序的入口函数。
CAppModule _Module;
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));
//程序逻辑,调用全局函数Run()
int nRet = Run(lpstrCmdLine, nCmdShow);
//终止模块
_Module.Term();
::CoUninitialize();
return nRet;
} |
在上面的代码中,_Module是一个全局变量,这里是CAppModule的一个实例。而CAppModule类是对应用程序的封装。它封装了诸如初始化模块等功能。一个_Module还维持一个消息循环Map。
入口函数名为_tWinMain()。当使用UNICODE时,编译器会将它替换为wWinMain(),否则,为WinMain()。入口函数其实就是主线程(_Module)的起始点。
在该函数中,最关键的逻辑是调用了全局函数Run(),它是核心程序逻辑所在。
下面来看一下这个函数。

本文深入探讨了如何使用WTL库来封装Windows界面程序,涵盖了从单个界面线程到多个界面线程的封装技术,揭示了在Windows API和Microsoft对象模型中的应用策略。
最低0.47元/天 解锁文章
2525

被折叠的 条评论
为什么被折叠?



