文檔中心

8.窗口系統

01.窗口系統架構

窗口系統的整體結構圖:

上圖中只有屏幕(framebuffer)是真正占用內存空間的,如屏幕分辨率為 1280*720,32bit顏色,那么這個屏幕對應的 framebuffer所占用的內存大小為 1280*720*4=3.6MB。window(包括 root window,top window) 都只是表示屏幕上的一個矩形區域,沒有分配顏色空間內存。

window是有層次關系的,這種層次結構可以以樹狀圖表示。在樹狀圖的最上層是根窗口(root window),這個根窗口由系統自動創建,大小和對應的framebuffer一樣。其他窗口則由開發人員創建,相同父控件的窗口稱為兄弟窗口。 窗口樹的深度、兄弟窗口的個數沒有任何限制。

每個窗口都有一個位置(x,y)和大?。╳,h),位置是相對于父窗口左上角的坐標(y軸向下為正),當一個窗口移動時,那么它所有的子孫窗口在屏幕上也都會移動。除了根窗口,其他窗口的位置沒有限制,可以為負數。窗口的大小只要大于 0,沒有其他限制。

頂層窗口(top window)特指父窗口是根窗口的窗口。

02.窗口剪裁

一個窗口的顯示區域由窗口剪裁來確定,窗口剪裁的原則如下

A、父子窗口剪裁:子窗口的顯示區域不能超出父窗口;

B、兄弟窗口剪裁:兄弟窗口的顯示區域有重疊時,上層窗口遮住下層窗口;

03.窗口的層次

一般情況下,一個 top窗口及其子孫窗口都是由一個客戶進程創建的,一個進程也可以創建多個 top window。

不同的 top window可能屬于不同的進程,并且進程看不到其他進程的窗口,所以由系統來統一管理 top window的層次。為了方便管理,系統設計了 top window的幾種類型:

層次

類型

屬性

說明

1

TW_WINDOW_DOCK

ABOVE

Dock類型,用于 top欄,系統提示框等

2

NORMAL

3

TW_WINDOW_NORMAL

TW_WINDOW_SPLASH

ABOVE

普通窗口

4

NORMAL

5

BELOW

6

TW_WINDOW_DESKTOP

 

桌面窗口,專用于桌面

窗口的類型是創建時確定的,不能修改。窗口的屬性 above、normal和below是可以運行時動態調整的。由窗口的類型和屬性決定了窗口的層次。上 層的窗口總是在下層窗口上面,無論誰先創建或先顯示出來。即 DOCK類型的top window總是在 NORMAL類型的上面,NORMAL類型的總是在 DESKTOP 類型的上面。

屬于相同層次的多個窗口之間,后創建的窗口在上面,也可以之后通過 API 來調整在同層次窗口的上下關系。

04.窗口的互斥
只針對 NORMAL類型(包括 SPLASH類型)的 top window,當一個 app顯示它的第一個 NORMAL類型窗口時,會自動隱藏其他 app的 NORMAL類型窗口。即系統當前總是只能顯示一個 app的 NORMAL類型窗口。 其他類型的窗口不受互斥規則影響。
05.彈出框管理規范

彈出框是指在任意 app的 NORMAL類型窗口界面或桌面上,可以隨時出現的一種由后臺服務程序彈出的界面窗口。彈出框不受普通窗口的互斥限制,也不 會互斥普通窗口。彈出框應該顯示一段時間之后自動消失。
彈出框對應的窗口類型為 DOCK類型。根據系統的 UI設計需求,
彈出框規范如下:

彈出框分類

top窗口類型/屬性

 

1 警示信息

TW_WINDOW_DOCK

ABOVE

警示信息和語音識別信

息在屏幕上彈窗的位置不重疊

2 語音識別信息

3 導航

TW_WINDOW_DOCK

NORMAL

 

4 電話

5 其他彈出信息

注:因為 1,2,3,4等彈出框內部顯示的復雜性,所以有各自的后臺服務程序自己負責彈出。其他彈出信息中,如果彈出內容比較簡單(只有一個文本串),可以交給桌面代為彈出(通過遠程方法把文本串發給桌面)。

06.前臺進程和后臺進程

前臺顯示 NORMAL(包括 SPLASH)類型的頂層窗口的 app是前臺進程,因為普通窗口的互斥關系,所以前臺進程只有一個,后臺進程可以有多個。

當一個進程被創建時,它的第一個普通窗口顯示出來時,該進程變為前臺進 程,并且擠掉前一個前臺進程,前臺進程可以調用 TwShow()或 TwHide()來顯 示或隱藏它的普通窗口。

后臺進程調用 TwShow()顯示普通窗口是無效的,不能顯示出來。因為后臺進程不能干擾前臺進程的顯示,只有通過下面的消息把自己變為前臺進程才行。

(系統會記錄后臺進程的 TwShow()和 TwHide()操作,當它變成前臺進程時才生效)

前臺進程退出或它的所有普通窗口都隱藏時,自動把上一個前臺進程變為當前的前臺進程。

void msg_show_hide_client(void *msg, Tint pid, Tbool show)
{
    TTable temp=TTableCreate();
    TTableAddInt(temp, TStringID("process"), pid);
    TTableAddInt(temp, TStringID("show"), show); TMessageRemoteMethod(msg,"tdWM",
    TStringID("SHOW_HIDE_CLIENT"), temp, NULL, NULL);
    TTableDestroy(temp);
    return;
}

例如一個后臺的進程,想把自己提到前臺來,調用:

msg_show_hide_client(msg, getpid(), TRUE); //msg是自己的消息對象
07.回到桌面

回到桌面的操作導致當前的前臺進程也到后臺,即所有的進程都是后臺進程,這樣才露出桌面。

/*參數 msg是自己的消息對象*/
void msg_return_desktop(void *msg, Tint pid, Tbool show)
{
    TMessageRemoteMethod(msg,"PmServer",
    TStringID("PM_RET_HOME"), NULL, NULL, NULL);
    return;
}
怎么在一天内赚钱 贵州快3开奖结果走势图一定牛 基金申购认购 福建体育11选5 福建11选五5前3走势图 股票补仓成本计算器 股票分析师如何评估一只股票 大乐透中奖规则及奖金 同花顺模拟炒股官网 安徽十一选五精准推荐 河北快三开奖结果直播