13.7 其它常用的数据类型

wxWidgets内部使用了一些其它的数据类型,也在一些公用API中作为参数和返回值,并且wxWidgets也鼓励程序员在它们的代码中使用这些类型.

wxObject

wxObject类是所有wxWidgets类的基类,它提供的功能包括运行期类型信息,引用技术,虚析构函数,可选的调试版本的new和delete函数等.某些wxObject对象的成员函数还使用了用于存储meta-data的wxClassInfo对象.

MyWindow* window = wxDynamicCast(FindWindow(ID_MYWINDOW), MyWindow);

IsKindOf函数判断对象是否是传入的wxClassInfo指向的类型.

bool tmp = obj->IsKindOf(CLASSINFO(wxFrame));

Ref函数的参数为const wxObject&类型, 它的作用是将当前对象的数据替换为参数对象的引用.当前对象的引用技术减一,如果需要则释放当前对象数据,参数对象的引用技术则加一.

UnRef则将对象内部数据的引用记数器减一,如果已经减到0则释放当前对象数据.

wxLongLong

wxLongLong类用来存储64位整数.如果本地系统支持64位长整数则使用本地系统提供的实现,否则将使用模拟的64位实现.这个类的使用和其它标准的数字类型没有区别.注意它是一个有符号数字,如果想使用它的无符号版本,可以使用wxULongLong类型,后者的API和前者几乎完全一样,除了个别的函数(比如求绝对值函数)可能返回不同的结果.除了一般的计算函数以外,另外的几个常用的函数包括:

  • Abs函数返回wxLongLong的绝对值,如果是作为常量引用调用的这个函数,则返回源对象的一个拷贝,否则将修改源对象的内部数值.
  • ToLong 函数将其转换成一个长整型,如果由于存在精度丢失,在调试版本中将引发一个断言错误.
  • ToString将内部存储的数据转换成一个wxString类型.

wxPoint和wxRealPoint

wxPoint在wxWidgets中使用比较普遍,常用来代表屏幕或者窗口上的一个确定的位置.正如它的名字的意思一样,它内部的数据用x和y两个整数代表一个座标值.其数据成员是以public方式定义的,可以直接被其它对象访问.wxPoint支持和另外一个wxPoint对象或者 wxSize对象进行加法和减法的运算.wxRealPoint对象和wxPoint对象类似,不过其内部成员是double类型,并且只支持和别的 wxRealPoint类型进行加减运算.

构造wxPoint实例的方法很直接:

wxPoint myPoint(50, 60);

wxRect

wxRect通常在绘画或者窗口类中使用(比如wxDC或者wxtreeCtrl),用来定义一个矩形区域.其内部的数据成员除了x和y 以外,还包括宽度和高度.所有的成员都是public类型,可以直接被其它的类访问.除了同类型之间的加减运算,wxRect还支持一些其它运算:

GetRight返回矩形最右边的X座标.

GetBottom返回底端的Y座标.

GetSize返回一个wxSize对象用来表征矩形区域的宽度和高度.

Inflate函数增加矩形区域的大小,如果只有一个参数,则长和宽增加一样的大小,如果是两个参数,则长和宽分别增加对应的大小.

Inside函数判断某个点是否位于矩形区域以内,点的格式可以是单独的XY座标,也可以是一个wxPoint类型.

Intersects判断某个矩形是否和另外一个矩形有重叠区域.

Offset将当前矩形偏移一段举例,偏移的位置既可以通过X和Y单独指定,也可以通过wxPoint来指定.

下面的代码演示了wxRect的三种构造函数:

wxRect myRect1(50, 60, 100, 200);
wxRect myRect2(wxPoint(50, 60), wxPoint(150, 260));
wxRect myRect3(wxPoint(50, 60), wxSize(100, 200));

wxRegion

wxRegion用来代表设备上下文或者窗口上的一个简单的或者复杂的区域.它使用了引用记数,因此拷贝和赋值操作是非常快速的.它的主要用途是用来定义或者查询某个需要裁剪或者更新的区域.

Contains函数在其参数指定的座标, wxPoint, 矩形或 wxRect被包含在区域内时返回True.

GetBox函数返回一个包含整个区域的wxRect对象.

Intersect函数在指定的矩形,wxRect或wxRegion参数和本区域有重叠的时候返回True.

Offset对区域进行指定x和y方向数量的平移.

Subtract, Union和Xor函数提供了一种灵活的机制来改变当前区域.这三个函数的变体函数(函数名相同,参数不同)超过10个.所有这些函数都可以支持wxRegion参数或者wxPoint参数.请参考wxWidgets的相关手册内容.

下面的代码演示了四种创建区域的方法,所有这些方法创建的结果都是一样的区域:

wxRegion myRegion1(50, 60, 100, 200);
wxRegion myRegion2(wxPoint(50, 60), wxPoint(150, 260));
wxRect myRect(50, 60, 100, 200);
wxRegion myRegion3(myRect);
wxRegion myRegion4(myRegion1);

你可以使用wxRegionIterator类来遍历某个区域中的矩形区域,比如要在窗口重绘函数中只绘制那些需要绘制的矩形区域,你可以使用下面的代码:

// 在窗口需要被重绘的时候调用
void MyWindow::OnPaint(wxPaintEvent& event)
{
    wxPaintDC dc(this);
    wxRegionIterator upd(GetUpdateRegion());
    while (upd)
    {
        wxRect rect(upd.GetRect());
        // 刷新这个矩形区域
        ...一些代码...
        upd ++ ;
    }
}

wxSize

wxSize类型在wxWidgets广泛用于指定窗口,控件,画布等等对象的大小.很多需要返回大小信息的函数也将返回这个对象类型.

GetHeight和GetWidth函数返回高度和宽度.

SetHeight和SetWidth函数设置整数的高度和宽度.

Set函数则使用两个整数参数来同时改变高度和宽度.

wxSize的创建也非常简单,如下所示:

wxSize mySize(100, 200);

wxVariant

wxVariant类用来表示那些可以是任意类型的数据.数据的类型甚至可以动态的改变.这种类型在解决某些特定的问题的时候很有用处,比如要编辑不同类型的数据的编辑器或者用于实现远程过程调用.

wxVariant类型可以存储的数据包括bool, char, double, long, wxString, wxArrayString, wxList, wxDateTime, void* 和可变类型变量列表.不过,你还是可以通过实现wxVariantData的派生类的发生扩展wxVariant可以支持的数据类型.在构造和赋值的时候,只需要将其当成wxVariantData使用就可以了.当然,不方便的地方在于如果你要访问自定义的数据类型,需要先将其转换成 wxVariantData对象,而不象内置支持的类型那样,有对应的类似于GetLong这样的函数支持.

另外,要记住不是所有的类型都可以互相转换,比如你不可能把一个bool型的数据转换成wxDateTime类型,也不可能把一个整数转换成wxArrayString,你需要按照一些常识来判断哪些数据类型是可以互相转换的,并且你总是可以通过GetType函数来得到当前数据最合适的类型.下面举一个使用wxVariant类的简单的例子:

wxVariant Var;
// 存储wxDateTime类型, 获取wxString类型
Var = wxDateTime::Now();
wxString DateAsString = Var.GetString();
// 存储一个wxString类型, 获取一个double类型
Var = wxT("10.25");
double StringAsDouble = Var.GetDouble();
// 当前的类型应该是"string"
wxString Type = Var.GetType();
// 下面演示一个无理取闹的转换
// 由于不能转换,所以转换的结果为0
char c = Var.GetChar();