事件管理器:Vista 小工具






4.35/5 (26投票s)
2007年2月2日
6分钟阅读

93147

2675
Windows Vista 的事件管理器小工具。

引言
Mac OS 用户自 Mac OS X 10.4 (Tiger) 起就可以使用小部件。小部件是浮动在用户桌面上的小型应用程序,用于执行特定任务。最知名的小部件包括时钟、日历、天气、货币转换器等……
而 Windows Vista 则拥有被称为“小工具”的小部件。小工具非常简单易创建:您只需熟悉 Html/JavaScript 即可开发自己的小工具。在本文中,我将与您分享我的小工具以及它是如何工作的详细信息。
理想情况下,小工具要想成功,必须有用。这就是为什么我选择创建一个事件管理器,该管理器可以在事件日期之前向用户发送电子邮件来通知他们即将发生的事件。
事件管理器
处理事件管理的主要代码位于 EventManager.js
和 AddEvent.js
中。管理器负责添加、删除和显示事件。为了更好地理解它的工作原理,了解我的小工具使用的事件结构很重要。
事件结构
在 C# 中,事件结构应如下所示
struct Event
{
int Id;
string Name;
string Description;
DateTime EventDate;
int notifyBefore;
bool SendEmail;
bool EmailSent;
}
添加事件
要添加事件,用户单击“添加事件”。此链接调用 ShowAddEventFlyout
函数,该函数会显示一个弹出窗口 (AddEvent.htm)
Document.js
System.Gadget.Flyout.file = "AddEvent.htm";
System.Gadget.Flyout.show = true;
// MainScript is used to call functions of this window from flyout
System.Gadget.Flyout.document.MainScript = this;
System.Gadget.Flyout.document.EventId = CurrentEventId;
System.Gadget.Flyout.document.EditEvent = false;
一旦用户填写完事件的所有字段,字段内容就会由 ValidateData
进行验证。如果数据有效,AddEvent
会使用 System.Gadget.Settings.write
以特殊格式保存事件数据:"Event" + eventId + Property (参见事件结构)
AddEvent.js
var radical = "Event" + eventId;
// save data using System.Gadget.Settings.write
System.Gadget.Settings.write(radical+"Id", eventId);
System.Gadget.Settings.write(radical+"Name", name);
System.Gadget.Settings.write(radical+"EventDate", date + " " + time);
System.Gadget.Settings.write(radical+"Description", description);
System.Gadget.Settings.write(radical+"NotifyBefore", parseInt(notifyBefore));
System.Gadget.Settings.write(radical+"SendEmail", SendEmail);
System.Gadget.Settings.write(radical+"EmailSent", false);
删除事件
使用小工具 API,没有官方方法可以删除使用 System.Gadget.Settings.write
或 System.Gadget.Settings.writeString
编写的条目。但有一个技巧。在事件管理器中,RemoveEvent
是“删除”事件的函数
EventManager.js
function RemoveEvent(eventId)
{
EventsNumber--;
System.Gadget.Settings.write("Event"+eventId+"Id", -1);
HideEventInfo();
SaveSettings();
LoadEvents();
UpdateSliderInput();
SetSlider();
}
正如您所见,我们并没有真正删除事件,只是禁用了它。Id
属性设置为 -1。通常,Id
等于 eventId
。
显示事件
LoadEvents
负责显示所有事件。此函数经常被调用以刷新事件,从而考虑任何最近的修改。
EventManager.js
function LoadEvents()
{
ClearEventsList();
for(i = 0, j=0; j<EventsNumber; i++)
{
if(System.Gadget.Settings.read("Event"+i+"Id")==i)
{
j++;
AddLineToEventsList(i);
}
}
}
条件 if(System.Gadget.Settings.read("Event"+i+"Id")==i)
避免了 for
循环显示已删除的事件。另一方面,AddLineToEventsList
函数使用 DOM 将事件添加到主 html 文档 (Document.htm)。
设置
在开发我的小工具时,我希望它是可自定义的。侧边栏允许小工具指定一个 html 文件用于设置。对于我的小工具,Settings.htm
页面和 Settings.js
脚本负责处理小工具的设置。事件管理器在 Init
函数(第一个调用的函数)中设置配置文件。
Document.js
function Init()
{
...
// Set the settings html page
System.Gadget.settingsUI = "Settings.htm";
...
}
使用我的小工具,您可以设置几个参数
- 您的电子邮件
- 每页事件数
- 启用声音
- 删除 x 天前的旧事件
- 用于发送电子邮件的服务器端脚本
GetDefaultSettings
当您第一次运行我的小工具时,事件管理器有许多默认值。这些值硬编码在 Settings.js
文件中,并且可以通过 GetDefaultSetting
函数访问
Settings.js
function GetDefaultSetting(settingName)
{
switch(settingName)
{
case "EventsPerPage":
return 5;
case "CurrentEventId":
return 0;
case "EventsNumber":
return 0;
case "RefreshInterval":
return 5;
case "DeleteOldEvents":
return true;
case "OldEventDeletionDelay":
return 5;
case "YourEmail":
return "";
case "ServerSideScript":
return "http://membres.lycos.fr/mailrelay/mail.php";
case "EnableSound":
return true;
}
}
SetSettings
GetDefaultSetting
函数由 SetSettings
用于初始化全局变量。SetSettings
检查每个参数是否用户已指定自定义值。如果是,则使用用户的值而不是默认值。否则,使用默认值。
Settings.js
function SetSettings()
{
...
// EventsNumber
if(System.Gadget.Settings.read("EventsNumber")=="")
EventsNumber = GetDefaultSetting("EventsNumber");
Else
EventsNumber = System.Gadget.Settings.read("EventsNumber");
...
}
搜索引擎
事件管理器允许用户通过在搜索框中输入关键字来搜索事件。Search
函数用于搜索。与 LoadEvents
一样,Search
遍历所有事件并使用 indexOf
检查是否有事件名称包含关键字
SearchEngine.cs
function Search(keyword)
{
...
// check if the event's name contain the keyword
var offset = eventName.indexOf(keyword);
// if yes :
if(offset != -1)
{
// add the event to event's list and highlight the keyword
AddLineToEventsList(i, true, offset, offset + keyword.length);
}
...
}
设计
外观
小工具界有一个不成文的规定,即小工具必须具有视觉吸引力。问题在于开发者很少是优秀的设计师。为了实现良好的设计,我选择使用联系人小工具的设计作为我小工具设计的基础。
停靠/取消停靠
使用小工具 API,我们可以注册一些重要事件,使我们的痉挛更具交互性。既然我们谈论设计,有两个事件值得我们关注
- System.Gadget.onDock
- System.Gadget.onUndock
我们通过这种方式注册事件
Document.js
function Init()
{
...
System.Gadget.onUndock = DockUndock;
System.Gadget.onDock = DockUndock;
...
}
DockUndock
在小工具停靠在侧边栏或从侧边栏取消停靠时更新小工具的大小。System.Gadget.docked
用于确定小工具是否已停靠
Document.js
// Update the gadget size
function DockUndock()
{
if (System.Gadget.docked)
{
HideEventInfo();
document.getElementById("Body").style.width = "134px";
}
else
{
document.getElementById("Body").style.width = "268px";
document.getElementById("LeftPage").style.visibility = "visible";
}
}
如何发送电子邮件?
小工具 API 中没有发送电子邮件的函数。但是,我们可以使用 ActiveX 对象 Microsoft.XMLHTTP
向服务器端脚本发送 HTTP 请求。脚本将处理其余工作。
让我们看看负责发送电子邮件的函数
Notification.js
function SendMail(eventId)
{
var radical = "Event" + eventId;
var result = true;
// create an XmlHttpRequest obj
var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
// ServerSideScript : script used to send mail
// method : POST
// async : false
xmlHttp.Open("POST",System.Gadget.Settings.read("ServerSideScript"),
false);
xmlHttp.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
// Email data
var email = System.Gadget.Settings.read("YourEmail");
var name = System.Gadget.Settings.read(radical + "Name");
var description = System.Gadget.Settings.read(radical + "Description");
var date = System.Gadget.Settings.read(radical + "EventDate");
var message = "You have an upcoming event : " + name + ".\nDate : " +
date + "\nDescription :\n" + description +
"\n\nSent by Event Manager Gadget.";
// if user specified an email adress
if(email != "")
{
// send the request
xmlHttp.send("address="+email+"&subject=notification : "+
name+"&message="+message);
if(xmlHttp.status != 200)
{
// if request failed
result = false;
}
}
else
{
result = false;
}
return result;
}
服务器端脚本的 URL 通过 System.Gadget.Settings.read("ServerSideScript")
检索。脚本应接受 POST 模式下的三个参数:address (收件人)
、subject (主题)
和 message (消息)
。例如,这是与我的小工具兼容的一个小 PHP 脚本的代码
mail.php
<html>
<head>
<title>Mail Relay</title>
</head>
<body>
<?php
$adresse = $_POST['address'];
$sujet = $_POST['subject'];
$message = $_POST['message'];
$message = wordwrap($message, 70);
mail($adresse, $sujet, $message);
?>
</body>
</html>
调试
调试小工具非常容易。实际上,它就像调试 Internet Explorer 中的脚本一样容易。首先,运行 IE,然后在菜单中:工具 -> Internet 选项 -> 高级 -> 取消选中禁用脚本调试 (Internet Explorer) 和禁用脚本调试 (其他)。
现在,如果发生错误,您可以使用 Visual Studio(或其他脚本调试器)进行调试。
通常,您会看到一个看起来像这样的窗口
部署小工具
要部署您的小工具,请按照以下步骤操作
- 压缩您小工具文件夹中的所有文件(zip 或 cab)
- 将 .zip 或 .cab 扩展名更改为 .gadget
- 双击您的 .gadget 文件以安装您的小工具
这很容易,但当您经常部署小工具时,这些步骤可能会花费 considerable 时间。因此,为了使部署更容易,我开发了一个名为部署小工具的小应用程序
有关部署的更多信息,请此处。
全球化
借助全球化支持,小工具可以多语言。您只需为每种文化创建一个特定文件夹,并使用该文化的代号。不必复制所有文件,只需复制用户界面的文件。事件管理器支持两种语言:法语和英语。这是我的小工具的文件夹树
有关全球化的更多详情,请此处。
补充和参考
声音和音乐
在小工具 API 中,有两个函数可以播放声音和音乐
System.Sound.beep()
System.Sound.playSound(strPlaySoundInit)
第一个函数生成一个简单的哔声。第二个函数播放声音文件。事件管理器使用 playSound 来通知用户即将发生的事件
EventManager.js
function AddLineToEventsList(eventId)
{
...
// play sound only if EnableSound == true
if(EnableSound) System.Sound.playSound("../sound/toutoune.wav");
...
}
滚动条
当事件数量超过每页事件数量时,我的小工具会显示一个滚动条,以便用户可以看到列表中的所有事件
我使用 Tigara 的免费控件。您可以在此处下载。
日历
日历非常有用,可以方便地选择日期
您可以从 Matt Kruse 的网站下载此漂亮的控件。同位作者的,我还使用了他的日期管理库。
清单文件
每个小工具都有一个清单。这个 xml 文件包含有关您小工具的信息,例如作者姓名、版权、小工具名称……您清单文件中的数据由侧边栏用于正确加载和显示您的小工具。清单文件命名为“gadget.xml”(名称不是可选的)。
典型的清单文件如下所示
<gadget>
<name>Name of the gadget</name>
<namespace>Example.You</namespace>
<version>1.0</version>
<author name=" Author name ">
<info url="http://www.example.com" />
<logo src="logo.png"/>
</author>
<copyright> Copyright </copyright>
<description> Gadget description </description>
<icons>
<icon height="48" width="48" src="icon.png" />
</icons>
<hosts>
<host name="sidebar">
<base type="HTML" src="YourMainPage.html" />
<permissions>full</permissions>
<platform minPlatformVersion="1.0" />
<defaultImage src="drag.png" />
</host>
</hosts>
</gadget>
您可以在此处找到所有字段的列表以及每个字段的完整描述