您的位置:首页 > 其它

nsIIdleService 的实现与应用

2010-02-23 09:19 363 查看
在 Mozilla 中有一个服务可以实现对系统消息的侦听,就是 nsIIdleService

接口。

该接口主要实现的功能是:设置一个时间段,当你在这个时间段内没有对计算机进行操作(键盘触发和鼠标操作)时,它会侦听到一个
idle 的消息,而你可以对这个消息做处理,做你想要实现的效果。

其实,就是在 QQ 中实现的“离开”的自动设置的功能。

分析源码,涉及到 nsITimer 及其相关内容,对这部分还不是很懂,继续研究中。

经过一番分析,终于找到它是如何侦听系统消息的了。
图一中所示代码是在windows下实现的接口中的 idleTime 的获取过程。其中,通过GetLastInputInfo获取最后的 input
event 的时间。

正是在这个函数中,实现在对 windows 系统消息的捕获,nsIIdleService
在实现接口的时候利用该属性与设定的侦听的延迟时间做比较,从而进行触发,如此想来,就很是简单了。图二中所示代码是 nsIIdleService
中实现的 checkAwayState 方法。

图一:在 windows 中实现的 GetIdleTime 方法

NS_IMETHODIMP

nsIdleServiceWin:

:

GetIdleTime(

PRUint32 *

aTimeDiff)

{

LASTINPUTINFO inputInfo;

inputInfo.

cbSize =

sizeof

(

inputInfo)

;

if

(

!

:

:

GetLastInputInfo(

&

inputInfo)

)

return

NS_ERROR_FAILURE;

*

aTimeDiff =

GetTickCount(

)

-

inputInfo.

dwTime;

return

NS_OK;

}



于windows 对消息事件的处理,可参阅 Keyboard Input

图二: 在 nsIdleService.cpp 中实现的修改 away state 的方法


void

nsIdleService:

:

CheckAwayState(

)

{

// Get the idle time.

PRUint32 idleTime;

if

(

NS_FAILED(

GetIdleTime(

&

idleTime)

)

)

return

;

nsAutoString timeStr;

timeStr.

AppendInt(

idleTime)

;

// Change state first, and
save observers that need notification, so

// removing things will
always work without upsetting notifications.

nsCOMArray<

nsIObserver>

idleListeners;

nsCOMArray<

nsIObserver>

hereListeners;

for

(

PRUint32 i =

0;

i <

mArrayListeners.

Length(

)

;

i+

+

)

{

IdleListener&

curListener =

mArrayListeners.

ElementAt(

i)

;

if

(

(

curListener.

reqIdleTime
*

1000 <

=

idleTime)

&

&

!

curListener.

isIdle)

{

curListener.

isIdle
=

PR_TRUE;

idleListeners.

AppendObject(

curListener.

observer)

;

}

else

if

(

(

curListener.

reqIdleTime *

1000 >

idleTime)

&

&

curListener.

isIdle)

{

curListener.

isIdle
=

PR_FALSE;

hereListeners.

AppendObject(

curListener.

observer)

;

}

}

// Notify listeners gone
idle:

for

(

PRInt32 i =

0;

i <

idleListeners.

Count

(

)

;

i+

+

)

{

idleListeners[

i]

-

>

Observe(

this

,

OBSERVER_TOPIC_IDLE,

timeStr.

get(

)

)

;

}

// Notify listeners that came
back:

for

(

PRInt32 i =

0;

i <

hereListeners.

Count

(

)

;

i+

+

)

{

hereListeners[

i]

-

>

Observe(

this

,

OBSERVER_TOPIC_BACK,

timeStr.

get(

)

)

;

}

}



这段源代码的分析中,可以看到 mozilla 在实现一个接口的思想。它的跨平台的实现,也显现了出来。而对服务的实现,也是利用 observer
机制很简单就实现了。真是佩服。

我要好好消化下。

在应用方面,mozilla 官网上的实例很不错。如图三所示:

var

idleService =

Components.

classes

[

"@mozilla.org/widget/idleservice;1"

]

.

getService(

Components.

interfaces.

nsIIdleService)

var

idleObserver =

{

observe:

function

(

subject,

topic,

data

)

{

alert

(

"topic:
"

+

topic +

"/ndata: "

+

data

)

;

}

}

;

idleService.

addIdleObserver(

idleObserver,

60)

;

// one minute

// ...

// Don't forget to remove the
observer using removeIdleObserver!

idleService.

removeIdleObserver(

idleObserver,

60)

;


第一次这样研究 mozilla 里的 xpcom
,我想这仅仅是一个开始,我将坚持下去,深入的理解这个庞大强悍的 Gecko 内核。

加油!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: