1.5 wxWidgets的体系结构

下表展示的wxWidgets的四层体系结构: wxWidgets公用API层,各个平台发行版,用于各个平台的API和操作系统层。

wxWidgets API                  
wxWidgets Port wxMSW wxGTK wxX11 wxMotif wxMac wxCocoa wxOS2 wxPalmOS wxMGL
Platform API Win32 GTK+ Xlib Motif/Lesstif Carbon Cocoa PM Palm OS Protein APIs MGL
Operating System Windows/Windows CE Unix/Linux     Mac OS 9/ Mac OS X Mac OS X OS/2 Palm OS Unix/DOS

下面依次说明目前已有的各个平台发行版本:

wxMSW

这个版本编译和运行在各个版本的微软的Windows操作系统上,包括:Windows95,Windows98,WinMe,Windows NT,Windows 2000,Windows Xp以及Windows 2003.在linux平台上,这个版本也可以使用Wine的库进行编译,并且可以被配置成在WinCE上运行。除了使用本地原生窗口控件,这个版本也可以配置成使用wxWidgets自己的窗口控件。

wxGTK

wxWidgets的GTK+版本可以使用GTK的1.x或者2.x版本,支持所有可以运行X11和GTK的类Unix平台 (比如: Linux, Solaris, HP-UX, IRIX, FreeBSD, OpenBSD, AIX等). 它也可以运行在那些有足够资源的嵌入式平台,比如GPE Palmtop环境 (如下图所示). wxWidgets的GTK版本是类Unix系统的推荐版本.

wxX11

wxWidgets的X11版本使用了wxUniversal的窗口控件集,直接运行在Xlib上。这使得它很适合嵌入式系统,当然它也可以运行在那些不喜欢GTK+的桌面系统上。它支持所有可以运行X11的Unix系统,当然wxX11并不像wxGTK那样完善。下图演示了Life程序使用wxX11版本编译运行在一个iPAQ PDA的类似Linux/TinyX环境下的样子。

wxMotif

这个版本的wxWidgets可以在大多数拥有 Motif, OpenMotif, 或者Lesstif的Unix系统上. 既然连Sun自己都正准备把它的窗口控件集转向GNOME和GTK+,对于大多数开发者来说,Motif并不是一个很可靠的选择.

wxMac

wxMac是为Mac OS 9 (9.1以后的版本)和Mac OS X (10.2.8以后的版本)准备的. 如果在Mac OS 9上编译,你需要 Metrowerks CodeWarrior的工具包, 如果在Mac OS X上编译, 你可以选择Metrowerks CodeWarrior工具包或者苹果公司的工具包. 如果使用苹果公司的工具包,你应该使用Xcode 1.5或者更高的版本,或者你可以考虑直接使用命令行工具toolsGCC 3.3或者其后续的版本.

wxCocoa

这是一个正在进行中的版本, 它使用Mac OS X的Cocoa API. 虽然Carbon和Cocoa的功能很相似,但是这个版本有可能会支持除Mac以外的其它支持GNUStep的操作系统。

wxWinCE

Windows CE版本的wxWidgets封装了WindowsCE平台上的各种不同的开发包,包括Pocket PC和Smartphone等. 这个版本包含在wxMSW的Win32版本中。下面第一副图演示了Life程序在Pocket PC 2003模拟器上运行的样子。第二副图则演示了wxWidgets中的对话框例子运行在一个拥有四个屏幕,分辨率为176x220的 SmartPhone2003上的样子。wxWidgets作了大量的用户界面适配方面的工作,比如因为Smartphone只支持两个菜单按钮,所以在通常显示菜单的地方wxWidgets构建了可以折叠的菜单。尽管如此,一些地方仍然需要依靠编程者使用不同的代码,比如应该使用SetLeftMenu 和SetRightMenu函数来代替直接在对话框上增加两个确定和取消按钮。

wxPalmOS

这个版本是为Palm OS 6准备的。到作者写这本书的时候为止,这个版本还处在很初级的阶段,但是已经可以在Palm OS 6的模拟器中运行一个很简单的小程序了。参见下图:

wxOS2

wxOS2是一个由别人维护的用于OS/2或者eComStation的版本(is a Presentation Manager port for OS/2 or eComStation).

wxMGL

这个版本使用了SciTech公司的底层图形库,窗口控件使用的是wxUniversal中的版本。

内部组织

在内部,wxWidgets的代码大致分为6层:

  1. 通用代码被所有的版本使用,包括类的数据结构,运行期类型信息,和一些公共基类比如wxWindowBase等,这些基类的代码将被所有它的子类所继承。
  2. 一般代码用来实现独立于各个平台的高级窗口控件,在某个平台不具有某种控件的时候将使用这部分代码,比如wxWizard和wxCalendarCtrl。
  3. 通用组件基本的窗口控件集,这套控件可以在某个平台(比如X11或者MGL)不具有它自己的窗口控件的时候使用。
  4. 平台相关代码调用特定平台的API来实现某个类的代码。比如在wxMSW中的wxTextCtrl控件的实现是封装了Win32的edit控件。
  5. 外来代码存放在一个单独的contrib目录中,提供一些非必要但是很有用的类实现。比如wxStyledTextCtrl
  6. 第三方代码不是由wxWidgets开发维护但是被wxWidgets使用以提供一些很重要的特性的代码,比如JPEG, Zlib, PNG和Expat库。

每一个平台版本所需要作的事情就是提取它需要的那些层的代码,然后用它那个平台的底层的API来实现wxWidgets的API。

当你编译你的代码的时候,wxWidgets怎么知道要编译哪一个平台的类呢?当你包含一个wxWidgets的头文件(比如 wx/textctrl.h)的时候,由于使用的不同的宏定义,实际上你包含的是一个特定平台的头文件(wx/msw/textctrl.h)。然后,当你链接wxWidgets的库文件的时候,当然这个库文件也需要是用同样的宏定义编译的。你可以同时拥有多套宏定义,例如你可以有调试版本和发布版本两套宏定义。通过这些宏定义的不同,你可以控制编译器链接wxWidgets的动态或者是静态版本,也可以禁止编译某个特定组件,或者是决定你要编译的是 Unicode版本还是ANSI版本。为了达到这个目的,你需要修改setup.h或者增加不同的编译选项,这取决于你的编译器。有关这些问题更详细的描述,请参见附录A,???安装wxWidgets???

另外一点提示是:虽然wxWidgets封装了本地的平台相关的API,并不意味着在你的wxWidgets程序中不可以使用这些API。只是,在绝大多数情况下,你用不着使用这些API。