2.2 应用程序类

每一个wxWidgets程序都需要定义一个wxApp类的子类,并且需要并且只能构造一个这个类的实例,这个实例控制着整个程序的执行。你的这个继承自 wxApp的子类至少需要定义一个OnInit函数,当wxWidgets准备好运行你写的代码的时候,它将会调用这个函数(和一个典型的Win32程序中的main函数或者WinMain函数类似)。

你定义这个子类的代码可能和下面的代码类似:

class MyApp : public wxApp
{
  public:
      virtual bool OnInit();
};

在这个OnInit函数中,你通常应该创建至少一个窗口,对传入的命令行参数进行解析,为应用程序进行数据设置和其它的一些初始化的操作.如果这个函数返回真,wxWidgets将开始事件循环用来处理用户输入并且在必要的情况下处理这些输入。如果OnInit函数返回假, wxWidgets将会释放它内部已经分配的资源,然后结束整个程序的运行。

接下来我们看一个最简单的OnInit函数的实现:

bool MyApp::OnInit()
{
   MyFrame *frame = new MyFrame(wxT("Minimal wxWidgets App"));
   frame->Show(true);
   return true;
}

你可能还会注意到上面例子中的wxT这个宏,在接下来的例子中,这个宏还会被频繁用到。它的作用是让你的代码兼容Unicode模式。这个宏和另外一个T宏的作用是完全一样的。使用这个宏也不会带来运行期的性能损失。(你可能还会遇到另外一个类似的"()"标记,这个标记是用来告诉 wxWidgets将其中的字符串翻译成其它语言的版本,参见第16章“编写国际化程序”)。

那么创建MyApp的实例的代码在哪里呢?实际上,这是在wxWidgets内部实现的,不过你仍然需要告诉wxWidgets需要创建哪一个App类的实例,所以你还需要增加下面的一个宏:

IMPLEMENT_APP(MyApp)

如果没有实现这个类,wxWidgets就不知道怎样创建一个新的应用程序对象。这个宏除了上述的功能以外,还会检查编译应用程序使用的库文件是否和当前的库文件的版本相匹配,如果没有这种检查,由此而产生的一些运行期的错误可能很难被查出原因。

当wxWidgets创建这个MyApp类的实例的时候,会将创建的结果赋值给一个全局变量wxTheApp.你当然可以在你的程序中使用这个变量,但是你可能不得不一遍又一遍的进行从wxApp到MyApp的类型强制转换。增加下面的这一行声明以后,你就可以调用wxGetApp()函数,这个函数会返回一个到这个MyApp实例的引用,这样用起来就方便多了。

DECLARE_APP(MyApp)

一点提示:

即使没有声明DECLARE_APP,你仍然可以不用进行类型强制转化就直接对wxTheApp变量调用wxApp的方法.这可以避免在所有的头文件中包含MyApp的头文件,对于那些库文件而不是应用程序的代码来说也更有意义,而且还可以缩短编译的时间。