深入剖析WTL——Win32模型

转载 2007年10月08日 12:35:00
 
WTL 是Windows Template Library的缩写。最初,WTL是由微软的ATL(Active Template Library)小组成员开发的一个SDK例子。主要是基于ATL的对Win32 API的封装。从2.0后,功能逐步完善,成为了一个完整的支持窗口的框架(windows framework)。

与MFC相比较,功能并没有MFC完善。比如MFC支持doc/view架构,而WTL并不支持。同时,WTL也没有Microsoft的官方支持。但是,WTL是基于模版(template)的,其应用程序最小只有24KB,同时不象MFC,依赖DLL(MFC需要MFC42.DLL)。

WTL系列文章对WTL进行了深入剖析,希望能方便您对WTL有一个深入的理解,从而能得心应手的开发出高质量的Windows应用程序。



Win32的线程模型


为了便于以后的探讨,首先看一下Win32的线程模型。

一个Win32应用程序(或进程)是由一个或多个并发的线程组成的,其中第一个启动的线程称为主线程。

Win32定义了两种类型的线程,界面线程和工作线程。Win32的每个进程可以有一个或多个界面线程和/或多个工作线程。界面线程拥有一个或多个窗口,拥有一个消息队列和其它属于界面线程的元素。工作线程就是一般的线程,它没有窗口,没有消息队列。

界面线程通常有一个或几个窗口。当某一个窗口有消息时,界面线程会调用相应的窗口函数(Windows Process)来处理该事件。由于某消息循环由它界面线程处理,同时不必在乎是哪个线程发送消息的,因此,Windows会保证线程间的同步问题。

对于工作线程,线程间的同步必须由程序员来实现。尽可能避免死锁和竞争出现。

Win32应用程序模型


Win32应用程序可以分成两大类:控制台程序(console application)和窗口界面程序(windows GUI application)。控制台程序的入口函数是main(),窗口界面程序的入口函数是WinMain()。

入口函数就是程序的主线程的运行起点。

这里讨论的开发框架(Framework)是针对窗口界面程序的。

窗口界面程序通常分成以下几类:SDI, MDI, multi-SDI, 和Dialog应用程序。

SDI(Single Document Interface)应用程序通常只有一个主窗口(通常是一个框架窗口,Frame Window)。框架窗口包含菜单、工具栏、状态栏和称为视(View)的客户工作区。

multi-SDI(Multiple Threads SDI)应用程序有框架个主窗口。比如IE浏览器,使用"文件/新建/窗口"命令后,会出现另一个IE窗口。

MDI(Multiple Document Interface)应用程序有一个主框架窗口,但有多个子框架窗口。每个子窗口都有自己的视(View)。

Dialog应用程序是基于对话框的。

通常一个简单的SDI应用程序由两个函数组成。一个是应用程序入口函数WinMain(),另一个是该应用程序窗口的窗口函数。

程序(主线程)从入口函数开始运行。在该函数中,首先是注册并创建一个主窗口。然后,启动消息循环。消息循环中,根据不同的消息,将消息发送到窗口函数中处理。当消息是退出消息时,该入口函数会退出消息循环,然后结束程序。

下面是一个最简单的Windows界面应用程序。

//应用程序入口函数int APIENTRY WinMain(HINSTANCE hInstance,      HINSTANCE hPrevInstance,      LPSTR lpCmdLine,      int nCmdShow){   MSG msg;   //1. 注册窗口类   WNDCLASSEX wcex;   wcex.cbSize = sizeof(WNDCLASSEX);    wcex.style = CS_HREDRAW | CS_VREDRAW;   wcex.lpfnWndProc = (WNDPROC)WndProc;    //指定窗口函数   wcex.cbClsExtra = 0;   wcex.cbWndExtra = 0;   wcex.hInstance = hInstance;   wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_HELLOWORLD);   wcex.hCursor = LoadCursor(NULL, IDC_ARROW);   wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);   wcex.lpszMenuName = (LPCSTR)IDC_HELLOWORLD;   wcex.lpszClassName = szWindowClass;wcex.hIconSm = LoadIcon(wcex.hInstance,(LPCTSTR)IDI_SMALL);   RegisterClassEx(&wcex);   //2. 创建一个该类型的窗口   HWND hWnd;   hWnd = CreateWindow(szWindowClass,szTitle,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);   if (!hWnd) return FALSE;   //3. 按nCmdShow所指定的方式显示窗口   ShowWindow(hWnd, nCmdShow);UpdateWindow(hWnd);   //4. 启动消息循环,将消息发送给相应的窗口函数   while (GetMessage(&msg, NULL, 0, 0))    {      TranslateMessage(&msg);      DispatchMessage(&msg);   }   return msg.wParam;}//窗口函数LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,         LPARAM lParam){   PAINTSTRUCT ps;   HDC hdc;   char* szHello = "Hello, world!";   switch (message)    {     case WM_PAINT:      hdc = BeginPaint(hWnd, &ps);      RECT rt;      GetClientRect(hWnd, &rt);      DrawText(hdc, szHello, strlen(szHello),&rt,DT_CENTER);      EndPaint(hWnd, &ps);      break;     case WM_DESTROY:      PostQuitMessage(0);  //退出应用程序      break;     default:      return DefWindowProc(hWnd, message, wParam, lParam);     }    return 0;  }


上面程序的执行过程如下:

1、注册窗口类

在使用CreateWindwo()或CreateWindowEx()创建窗口时,必须提供一个标识窗口类的字符串。该窗口类定义了一些窗口的基本属性。其中一个重要的工作是向操作系统提供窗口函数。该函数是回调函数,用于处理发送给该窗口的消息。

在上面程序中,仅仅简单的处理了两个消息。一个是向窗口区域画出"Hello world."字符串。另一个是当窗口撤消时,向应用程序发送"退出应用程序"消息。

2、创建窗口

3、显示窗口

4、启动消息循环,分发并处理消息。

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


在上述消息循环代码中,调用GetMessage()从线程的消息队列中取出一条消息。如果消息为0(由窗口函数处理"WM_DESTROY"消息时发送的"PostQuitMessage(0)"),会退出消息循环。

然后调用TranslateMessage()翻译消息。

翻译后,再调用DispatchMessage()将该消息分发至相应的窗口函数进行处理。 (实际上DispatchMessage()将该消息作为参数调用对应的窗口的窗口函数,这就是分发的实质)。

深入剖析WTL——Win32模型

WTL 是Windows Template Library的缩写。最初,WTL是由微软的ATL(Active Template Library)小组成员开发的一个SDK例子。主要是基于ATL的对Win...
  • zcxin
  • zcxin
  • 2013年10月23日 00:28
  • 1138

深入剖析WTL—WTL框架窗口分析

WTL的基础是ATL。WTL的框架窗口是ATL窗口类的继承。因此,先介绍一下ATL对Windows窗口的封装。 由第一部分介绍的Windows应用程序可以知道创建窗口和窗口工作的逻辑是: ...
  • zcxin
  • zcxin
  • 2013年10月23日 01:42
  • 1454

STL源码剖析 读书总结

> 侯捷著 很早就买了这本书, 一直没看, 现在在实验室师兄代码的时候发现里面使用了大量泛型编程的内容, 让我有了先看看这本书的想法.  看之前我对于泛型编程了解甚少, STL倒使用的比较...
  • xuzhezhaozhao
  • xuzhezhaozhao
  • 2014年10月21日 15:29
  • 1411

深入剖析WTL——Win32模型

WTL 是Windows Template Library的缩写。最初,WTL是由微软的ATL(Active Template Library)小组成员开发的一个SDK例子。主要是基于ATL的对Win...
  • zcxin
  • zcxin
  • 2013年10月23日 00:28
  • 1138

Visual Studio 9.0(2008) Mini版的整理。 (支持WTL/ATL/MFC/Win32)

软件名称:Visual Studio 9.0(2008) Mini版 功能:可以脱离 VS2008来编译 WTL/ATL/MFC/Win32 工程 PS:不支持 C#、VB以及其它语言的编译。 ...
  • yuyuyezi
  • yuyuyezi
  • 2012年11月24日 11:06
  • 396

Win32平台各种主流开发框架(MFC、ATL、WTL、VCL等)

Win32平台各种主流开发框架(MFC、ATL、WTL、VCL等) 博客分类: C/C++/D MFC框架C#CC++  C++ 书籍推荐 http://community...
  • yeahhook
  • yeahhook
  • 2012年06月06日 14:20
  • 635

[ATL/WTL]_[初级]_[Win32窗口自定义消息处理过程]

场景 有时候我们需要单独对某个窗口消息进行拦截,比如CEdit响应回车, 这时候就需要拦截窗口处理过程了. 当然MFC的界面可以重载: BOOL CXXXDlg::PreTranslateMessag...
  • infoworld
  • infoworld
  • 2016年06月28日 16:50
  • 2789

使用Win32::OLE操作Excel——Excel对象模型

使用Win32::OLE模块操作Excel
  • will2ni
  • will2ni
  • 2011年01月21日 11:38
  • 5466

win32、MFC、WTL比较

  • 2009年05月18日 16:29
  • 5.23MB
  • 下载

【WIN32】CMake的学习总结 4——深入动态库

上回讲述了CMake使用动态库与使用静态库之间并没有太大的区别,并讲述了学习期间碰到的问题:无法正确生成动态库DLL,导致使用动态库的test测试项目无法正确编译;【 学习时遇到的疑问 】 既然已...
  • BlueKingFirst
  • BlueKingFirst
  • 2015年05月17日 00:27
  • 871
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章: 深入剖析WTL——Win32模型
举报原因:
原因补充:

(最多只允许输入30个字)