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()
来识别事件代码并获取相应的事件数据,从而进行处理。先表给出了不同的事件代码对应的事件数据和窗体句柄:
|
|
|
EEventNull |
n/a |
n/a |
EEventKey |
TKeyEvent |
RWindowGroup |
EEventKeyUp |
TKeyEvent |
RWindowGroup |
EEventKeyDown |
TKeyEvent |
RWindowGroup |
EEventModifiersChanged |
TModifiersChangedEvent |
The client handle of the RWindowTreeNode on which RWindowTreeNode::EnableModifierChangedEvents() was called |
EEventPointer |
TPointerEvent |
RWindow client handle |
EEventPointerEnter |
TPointerEvent |
RWindow client handle |
EEventPointerExit |
TPointerEvent |
RWindow client handle |
EEventPointerBufferReady |
None-call RWindowBase::RetrievePointerMoveBuffer() RWindow client handle |
RWindow client handle |
EEventDragDrop |
TPointerEvent |
RWindow client handle |
EEventFocusLost |
None |
RWindowGroup client handle |
EEventFocusGained |
None |
RWindowGroup client handle |
EEventSwitchOn |
None |
The client handle of the RWindowTreeNode on which RWindowTreeNode::EnableOnEvents() was called |
EEventPassword |
None |
The client handle of the RWindowGroup of the window on which RWindowBase::PasswordWindow() was called |
EEventWindowGroupsChanged |
None |
The client handle of the RWindowTreeNode on which RWindowTreeNode::EnableGroupChangeEvents() was called |
EEventErrorMessage |
TWsErrorMessage |
The client handle of the RWindowTreeNode on which RWindowTreeNode::EnableErrorMessages() was called |
EEventMessageReady |
None |
RWindowGroup client handle |
EEventMarkInvalid |
n/a |
n/a |
EEventSwitchOff |
None |
The client handle of the RWindowTreeNode passed into RWsSession::RequestOffEvents() |
EEventKeySwitchOff |
None |
The client handle of the RWindowTreeNode passed into RWsSession::RequestOffEvents() |
EEventScreenDeviceChanged |
None |
The client handle of the object on which RWindowGroup::EnableScreenChangeEvents() was called |
EEventFocusGroupChanged |
None |
The client handle of the RWindowTreeNode on which RWindowTreeNode::EnableFocusChangeEvents() was called |
EEventCaseOpened |
None |
The client handle of the RWindowTreeNode on which RWindowTreeNode::EnableOnEvents() was called |
EEventCaseClosed |
None |
The client handle of the RWindowTreeNode passed into RWsSession::RequestOffEvents() |
EEventWindowGroupListChanged |
None |
The client handle of the RWindowTreeNode on which RWindowTreeNode::EnableGroupListChangeEvents() was called |
EEventKeyRepeat |
n/a (only sent to the key click plug-in interface) |
n/a |
EEventUser |
n/a |
n/a |
表(
1
)
重画事件
重画事件对应的类是
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
{
public
:
//
继承自
CActive
void
RunL
();
void
DoCancel
();
//
向
Window Server
请求事件
void
IssueRequest();
private
:
// Access to Window Server session
RWsSession
&
iWs
;
// Access to screen device
CWsScreenDevice
&
iScreen
;
//
用来保存收到的事件
TWsEvent
iWsEvent
;
};
一旦活动对象被创建,就可以发送请求。我们可以调用
IssueRequest()
来发送一个异步请求,这个请求前面提到过,使用
RWsSession
的
EventReady()
方法,其中参数
TRequestStatus
是活动对象的成员变量
iStatus
,如下代码段所示:
/*
向
Window Server
请求事件
*/
void
CClientEventExample
::IssueRequest
()
{
//
请求事件
iWs.EventReady(&iStatus);
//
设置活动对象为
active
,即当这个异步请求返回时,
Active scheduler
会调用
RunL
SetActive
();
}
当客户端程序事件请求返回后,活动对象的
RunL()
函数会被调用。前面提到过,在
RunL()
获取事件对象,并根据不同事件代码和事件数据进行不同的处理。如下代码所示:
/*
当有事件发生时,
Active scheduler
调用
RunL */
void
CClientEventExample
::RunL
()
{
//
用
Window Server session iWs
来获取事件
iWs
.
GetEvent
(
iWsEvent
);
//
获取事件代码,事件代码在
TEventCode
中定义
TInt
eventType=
iWsEvent
.
Type
();
//
处理事件
switch
(eventType)
{
/*
根据不同的事件代码来处理不同的事件
-->
- 该日志由 serchong 于10年前发表在综合分类下,最后更新于 2013年12月04日.
- 转载请注明: Symbian OS应用编程图形篇之事件(Event) | 学步园 +复制链接