# 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();
```
- 第一章 介紹
- 1.1 為什么要使用wxWidgets?
- 1.2 wxWidgets的歷史
- 1.3 wxWidgets社區
- 1.4 wxWidgets和面向對象編程
- 1.5 wxWidgets的體系結構
- 1.6 許可協議
- 第一章小結
- 第二章 開始使用
- 2.1 一個小例子
- 2.2 應用程序類
- 2.3 Frame窗口類
- 2.4 事件處理函數
- 2.5 Frame窗口的構造函數
- 2.6 完整的例子
- 2.7 wxWidgets程序一般執行過程
- 2.8 編譯和運行程序
- 第二章小結
- 第三章 事件處理
- 3.1 事件驅動編程
- 3.2 事件表和事件處理過程
- 3.3 過濾某個事件
- 3.4 掛載事件表
- 3.5 動態事件處理方法
- 3.6 窗口標識符
- 3.7 自定義事件
- 第三章小結
- 第四章 窗口的基礎知識
- 4.1 窗口解析
- 4.2 窗口類概覽
- 4.3 基礎窗口類
- 4.4 頂層窗口
- 4.5 容器窗口
- 4.6 非靜態控件
- 4.7 靜態控件
- 4.8 菜單
- 4.9 控制條
- 第四章小結
- 第五章繪畫和打印
- 5.1 理解設備上下文
- 5.2 繪畫工具
- 5.3 設備上下文中的繪畫函數
- 5.4 使用打印框架
- 5.5 使用wxGLCanvas繪制三維圖形
- 第五章小節
- 第六章處理用戶輸入
- 6.1 鼠標輸入
- 6.2 處理鍵盤事件
- 6.3 處理游戲手柄事件
- 第六章小結
- 第七章使用布局控件進行窗口布局
- 7.1 窗口布局基礎
- 7.2 窗口布局控件
- 7.3 使用布局控件進行編程
- 7.4 更多關于布局的話題
- 第七章小結
- 第八章使用標準對話框
- 8.1信息對話框
- 8.2 文件和目錄對話框
- 8.3 選擇和選項對話框
- 8.4 輸入對話框
- 8.5 打印對話框
- 第八章小結
- 第九章創建定制的對話框
- 9.1 創建定制對話框的步驟
- 9.2 一個例子:PersonalRecordDialog
- 9.3 在小型設備上調整你的對話框
- 9.4 一些更深入的話題
- 9.5 使用wxWidgets資源文件
- 第九章小結
- 第十章使用圖像編程
- 10.1 wxWidgets中圖片相關的類
- 10.2 使用wxBitmap編程
- 10.3 使用wxIcon編程
- 10.4 使用wxCursor編程
- 10.5 使用wxImage編程
- 10.6 圖片列表和圖標集
- 10.7 自定義wxWidgets提供的小圖片
- 第十章小結
- 第十一章剪貼板和拖放操作
- 11.1 數據對象
- 11.2 使用剪貼板
- 11.3 實現拖放操作
- 第十一章小結
- 第十二章高級窗口控件
- 12.1 wxTreeCtrl
- 12.2 wxListCtrl
- 12.3 wxWizard
- 12.4 wxHtmlWindow
- 12.5 wxGrid
- 12.6 wxTaskBarIcon
- 12.7 編寫自定義的控件
- 第十二章小結
- 第十三章數據結構類
- 13.1 為什么沒有使用STL?
- 13.2 字符串類型
- 13.3 wxArray
- 13.4 wxList和wxNode
- 13.5 wxHashMap
- 13.6 存儲和使用日期和時間
- 13.7 其它常用的數據類型
- 第十三章小結
- 第十四章文件和流操作
- 14.1 文件類和函數
- 14.2 流操作相關類
- 第十四章小結
- 第十五章內存管理,調試和錯誤處理
- 15.1 內存管理基礎
- 15.2 檢測內存泄漏和其它錯誤
- 15.3 構建自防御的程序
- 15.4 錯誤報告
- 15.5 提供運行期類型信息
- 15.6 使用wxModule
- 15.7 加載動態鏈接庫
- 15.8 異常處理
- 15.9 調試提示
- 第十五章小結
- 第十六章編寫國際化程序
- 16.1 國際化介紹
- 16.2 從翻譯說起
- 16.3 字符編碼和Unicode
- 16.4 數字和日期
- 16.5 其它媒介
- 16.6 一個小例子
- 第十六章小結
- 第十七章編寫多線程程序
- 17.1 什么時候使用多線程,什么時候不要使用
- 17.2 使用wxThread
- 17.3 用于線程同步的對象
- 17.4 多線程的替代方案
- 第十七章小結
- 第十八章使用wxSocket編程
- 18.1 Socket類和功能概覽
- 18.2 Socket及其基本處理介紹
- 18.3 Socket標記
- 18.4 使用Socket流
- 18.5 替代wxSocket
- 第十八章小結
- 第十九章使用文檔/視圖框架
- 19.1 文檔/視圖基礎
- 19.2 文檔/視圖框架的其它能力
- 19.3 實現Undo/Redo的策略
- 第十九章小結
- 第二十章完善你的應用程序
- 20.1 單個實例和多個實例
- 20.2 更改事件處理機制
- 20.3 降低閃爍
- 20.4 實現聯機幫助
- 20.5 解析命令行參數
- 20.6 存儲應用程序資源
- 20.7 調用別的應用程序
- 20.8 管理應用程序設置
- 20.9 應用程序安裝
- 20.10 遵循用戶界面設計規范
- 20.11 全書小結