視窗事件 Window Server Events

2021-05-25 00:55:12 字數 3214 閱讀 4465

window server中的events(事件)被應用程式獲取並處理。類似於微軟windows作業系統中的訊息,事件通常源於使用者的輸入,由wserv生成傳送給客戶端程式,如請求窗體重畫。客戶端程式通過wserv 會話來傳送請求並獲取事件。大部分事件(如鍵盤和滑鼠事件)都封裝為twsevent類。重畫事件告訴應用程式螢幕的哪個區域需要重畫,這類事件被封裝在twsredrawevent類中。

事件型別

symbian os 中的window server有三種事件型別,通用事件、重畫事件及優先鍵事件,它們分別封裝在twsevent、twsredrawevent、twsprioritykeyevent類中。如下圖所示:

圖 (1)

這三種事件分別通過rwssession的getevent()、getredraw()、getprioritykey()來獲取。

其中通用事件又可以通過twsevent的type()方法來獲取事件碼以區分不同的事件,如keyup、keydown事件等;通過twsevent的pointer()方法來獲取指標事件(tpointerevent),twsevent的key()方法來獲取按鍵事件(tkeyevent)。

需要指出的是,這裡的pointer(指標)是泛指指向螢幕的裝置,如滑鼠,輸入筆,手指等。

下面對著三種型別的事件分別作一簡單的介紹。

通用事件

通用事件對應的類是twsevent,代表了使用者輸入事件如指標和按鍵事件,這類事件用活動物件以標準優先順序來處理。除重畫和優先鍵事件外的通用事件由window server生成twsevent並傳送給客戶端,客戶端通過非同步方法rwssession::eventready()來請求事件,此執行方法結束後,會觸發cactive::runl(),在runl函式裡,使用rwssession::getevent()來獲取twsevent所代表的事件。然後通過twsevent::type()和twsevent::eventdata()來識別事件**並獲取相應的事件資料,從而進行處理。先表給出了不同的事件**對應的事件資料和窗體控制代碼:

twsevent::type() 對應w32std.h中的enum teventcode

重畫事件

重畫事件對應的類是twsredrawevent,這類事件用活動物件以較低優先順序來處理。twsredrawevent通過rwssession::redrawready()來請求,請求返回後,重畫事件可以通過rwssession::getredraw()來獲得事件。重畫事件資料中包括了要重畫的窗體的控制代碼及重畫區域。

優先鍵事件

優先鍵事件對應的類是twsprioritykeyevent,這類事件用活動物件以較高優先順序來處理。在使用優先鍵事件機制前需要先用rwindowgroup::addprioritykey()來配置優先鍵。優先鍵通常是為應用程式提供「放棄(abort)」或「退出(escape)」鍵,即應用程式遇到這種事件要優先響應。

所有的優先鍵事件由window server生成並以twsprioritykeyevent傳送給客戶端,客戶端通過rwssession::getprioritykey()來獲取事件。

事件的處理(handling events)

所有的window server應用程式都處理標準事件,也幾乎都處理重畫事件,然而,卻很少處理優先鍵事件。很少有程式不處理重畫事件,除非程式所有窗體都是backed-up 窗體。事件總是伴隨著窗體的,如按鍵事件伴隨window group;指標事件伴隨可畫窗體(drawable window)。這些事件都包含乙個控制代碼,用來識別窗體,這個控制代碼就是窗體在建立時的控制代碼。在處理事件時,symbian推薦不同的時間在不同的活動物件(active object)中處理,這樣可以保證事件在不同優先順序下分別被處理。

window server在服務端為應用程式維護乙個事件佇列緩衝區,每個應用程式有自己的事件佇列區(這僅僅是對於通用事件來說,重畫和優先鍵事件是另一種不同的處理機制)。應用程式必須適當地處理好事件。應用程式在處理時,首先通過rwsseeeion::getevent()來獲取事件,然後在分析處理事件。事件必須被快速處理以相應使用者的輸入,如果事件的處理比較複雜費時,應該將處理分成多個小的處理塊,沒個處理塊在不同的活動物件中,且執行優先順序低於getevent()。下面分類介紹事件的具體處理方法。

在處理事件時我們要先定義乙個活動物件類,從cactive派生,自己實現runl()。下面的**段宣告了乙個處理事件的活動物件類cclienteventexample:

/* 活動物件類中包含乙個 window server session. */

class cclienteventexample : public cactive    ;

一旦活動物件被建立,就可以傳送請求。我們可以呼叫issuerequest()來傳送乙個非同步請求,這個請求前面提到過,使用rwssession的eventready()方法,其中引數trequeststatus是活動物件的成員變數istatus,如下**段所示:

/* 向 window server請求事件 */

void cclienteventexample::issuerequest()

當客戶端程式事件請求返回後,活動物件的runl()函式會被呼叫。前面提到過,在runl()獲取事件物件,並根據不同事件**和事件資料進行不同的處理。如下**所示:

/*  當有事件發生時,active scheduler呼叫runl */

void cclienteventexample::runl()

/* 如控制或換檔鍵事件(e.g. shift) */

case eeventmodifierschanged:

// 處理使用者自定義的事件

case eeventuser:

... }

} 無論是窗體、窗體組還是系統事件,都在如上所示的runl中處理。具體如何獲取事件資料和窗體控制代碼,查w32std.h中的enum teventcode即可。

另外需要說明的是,還有類事件即trawevent,它是最原始的系統事件,來自硬體裝置如鍵盤,滑鼠或手寫筆等。這類事件從硬體產生,送到系統核心的事件佇列中,由核心處理後再生成前面講的應用層的事件。

視窗事件onresize

在做自適應布局的時候,我們常常需要根據視窗不同的解析度給出不同布局和樣式,今天說的onresize便能幫我們實現這一效果。onresize事件在視窗或者框架的大小發生改變的時候會被呼叫,下面我們用乙個例子來演示。在這個例子中,我們想要實現的效果是 當螢幕寬度小於500時,頁面的背景色為灰色 當螢幕寬...

視窗關閉觸發事件

net平台上開發應用程式時,在視窗關閉時觸發乙個提示對話方塊,在彈出的對話方塊中如果確定關閉則關閉窗體。如果取消則返回。那麼這裡有二種作法。第一種方法重寫系統提供 onclosing事件函式。實現 如下 重寫關閉視窗事件 protected override void onclosing cance...

QT 視窗重繪事件 paintEvent事件

1 qwidget qscrollview viewport const 返回滾動檢視中的視口視窗部件,這個視窗部件包含內容視窗部件或者要畫的區域。2 void qwidget paintevent qpaintevent 虛 保護 只要視窗部件需要被重繪就被呼叫。每個要顯示輸出的視窗部件必須實現它...