Windows 7 侧边栏小工具 - CodeProject 声望观察者
Windows 7 小工具,可抓取您的声望积分和图表,并跟踪更新之间的变化

引言
继我之前编写的 CodeProject Chrome 扩展 之后,我想探索一下将其移植到 Windows 桌面小工具需要付出什么。本文将探讨如何构建一个桌面小工具,并讨论一些遇到的问题以及如何克服它们。该小工具会轮询 CodeProject 来获取成员的个人资料,并利用 jQuery 来抓取声望积分,显示成员当前的声望积分以及上次轮询以来的变化。该小工具还可以获取成员的声望图表,并在“弹出窗口”中显示给用户。
背景
构建此扩展所需的信息可以在 Microsoft MSDN Windows 侧边栏开发 页面 上找到。有关 jQuery 的信息,请参见 此处。
侧边栏小工具
侧边栏小工具是在 Windows Vista 中引入的,小工具会停靠在侧边栏区域内。在 Windows 7 中,移除了侧边栏内的停靠功能,小工具可以自由地漂浮在用户放置的任何位置。我只在 Windows 7 中进行了测试,因为我再也不想和 Vista 有任何瓜葛了,任何有理智的人都会完全理解这一点!
小工具可以是嵌入在 HTML 文件中的 ActiveX 控件,或者只是简单的 HTML 和相关的 JavaScript/图像等。由于我是在移植之前提到的 Chrome 扩展,本文将只关注简单的 HTML/JavaScript 实现。
这个小工具实际上是一系列包含完全嵌入式 JavaScript 和 CSS 的 HTML 文件,或者可以链接到其他 JavaScript、CSS 和图像文件。该小工具只是一个重命名的 zip 文件(扩展名为 .gadget),其中包含所有必需的组件和元素。我们将在文章后面介绍打包。为了让 Windows 知道如何处理包中的所有这些文件并如何将其呈现给用户,项目根目录中的一个清单文件定义了各种元素。清单文件必须命名为 gadget.xml。
现在让我们来看看为这个小工具制作的清单文件
<?xml version="1.0" encoding="utf-8" ?>
- <gadget>
<name>CodeProject Gadget</name>
<version>1.2.0.0</version>
- <author name="Dave Auld">
<info url="http://www.dave-auld.net" />
<logo src="images\bob.png" />
</author>
<copyright>©2011 Dave Auld.</copyright>
<description>CodeProject Windows Desktop Gadget</description>
- <icons>
<icon height="48" width="48" src="images\bob48.png" />
</icons>
- <hosts>
- <host name="sidebar">
<base type="HTML" apiVersion="1.0.0" src="cpgadget.html" />
<permissions>Full</permissions>
<platform minPlatformVersion="1.0" />
<defaultImage src="images\bob128.png" />
</host>
</hosts>
</gadget>
有一些基本属性,如 name
、version
和 description
,它们不言而喻。icons
和 defaultimage
元素定义了可供 Windows 使用的图像;这些图像出现在安装时的小工具选择页面上,以及将小工具拖到桌面上时。base
元素包含一个 src
参数,该参数定义了要打开的作为主要小工具元素的 HTML 文件。其他一些元素是强制性的值,必须使用,并且在 MSDN 文档中已定义。其中一些元素也用于小工具选择屏幕,为用户提供信息,如下所示

小工具初始化、配置和设置
当小工具启动时,代码会配置小工具中的一些功能,即用于设置对话框的 HTML 文件,以及用于弹出窗口功能的 HTML 文件。弹出窗口功能是我们用于声望图表显示的。还会初始化一个事件处理程序,用于在设置对话框关闭时执行更新,如果成员 ID 或刷新间隔已更改。首次运行小工具时,成员 ID 默认为作者的,刷新间隔设置为 300 秒。
设置使用 System.Gadget.Settings
命名空间中的函数进行存储和读取。在版本 1.1 中,进行了一些额外的检查,以在设置默认值之前检查小工具实例的设置是否已存在。添加此功能是因为如果计算机重启,默认设置会被重新应用。执行初始化的代码如下所示
var memberID = "557325"; // Member ID Number (1st load is Authors ID)
var refreshInt = "300"; // 300 Second default
//Check if the instance has settings stored already before
//applying new defaults
if (System.Gadget.Settings.read("MemberID") === "")
{
//Write the default settings
System.Gadget.Settings.writeString("MemberID", memberID);
System.Gadget.Settings.writeString("RefreshInterval", refreshInt);
}
else
{
//Read the saved settings
memberID = System.Gadget.Settings.readString("MemberID");
refreshInt = System.Gadget.Settings.readString("RefreshInterval");
}
System.Gadget.onSettingsClosed = SettingsClosed;
// --------------------------------------------------------------------
// Initialize the gadget. called from the onload event of primary file
// --------------------------------------------------------------------
function init() {
// Enable Settings dialog for the gadget.
System.Gadget.settingsUI = "cpsettings.html";
// Specify the Flyout root.
System.Gadget.Flyout.file = "cprepgraph.html";
System.Gadget.Flyout.show = false;
//Hide the Play image, as will start in Autoupdate
$("#playImage").hide();
reload_Page();
//kickoff the auto update timer
setTimeout(function () { updateTick(); }, 1000);
}
设置对话框用于设置成员 ID 和刷新间隔。通过点击小工具上的扳手图标可以访问它,这会打开设置 HTML 文件并向用户显示对话框。

添加和使用 jQuery,为什么使用它?抓取内容?
由于这个小工具是 Chrome 扩展的移植版,添加和使用 jQuery 的方法以及我们为什么要使用它的原因完全相同,所以我们不再赘述,请参考 此处 的 Chrome 扩展文章。该小工具只使用 jQuery,不使用 jQueryUI,因此只需要引用与 jQuery 库相关的部分,即
<script type="text/javascript" src="jquery/jquery-1.4.2.min.js"></script>
内容抓取方式与 Chrome 扩展完全相同,只是代码稍作修改以适应小工具的布局。
注意:Windows 侧边栏使用 Internet Explorer 引擎来托管小工具,因此,我发现 Internet Explorer 缓存开始干扰声望积分的更新,并且这些积分没有正确刷新。为了阻止 Internet Explorer 缓存干扰,可以将 jQuery 配置为不使用缓存。这是通过在 JavaScript 文件开头添加以下代码来实现的,为 jQuery 进行的所有调用禁用缓存
// Disable caching of AJAX responses - Stop IE reusing
// cache data for the same URL requests
$.ajaxSetup({
cache: false
});
实现自动刷新
Chrome 扩展和 Windows 小工具之间的一个主要区别是数据刷新。每次从 Chrome 工具栏激活扩展时,它都会加载新数据。然而,小工具一直处于打开状态,因此需要一种刷新数据的方法。这是通过实现一个自生成的计时器滴答事件和一个计数器来实现的。当小工具首次加载时,它会启动一个计时器,其中一个回调函数是“滴答”;滴答会维护一个计数器,记录它滴答的次数,如果次数超过刷新周期,它就会执行一次数据刷新。在每次滴答结束时,它会启动另一个超时,并回调自身。小工具还可以通过使用一个播放/暂停布尔标志来停止和重新启动自动刷新。一旦我弄清楚我要做什么,它就变成了一种相对简单有效的机制。计时器例程的代码如下所示
// 300 Second default, this is a string as it comes from the Settings Dialog
var refreshInt = "300";
var tickCount = 0; // How many ticks have elapsed
var autoupdate = true; // Is autoupdate on/off
//This code is actually held within the gadget start up routine
//kickoff the auto update timer
setTimeout(function () { updateTick(); }, 1000);
// --------------------------------------------------------------------
// Auto-Refresh codes
// --------------------------------------------------------------------
function updateTick() {
tickCount++;
if (autoupdate) {
if (tickCount >= parseInt(refreshInt)) {
//refresh
tickCount = 0;
reload_Page();
}
setTimeout(function () { updateTick(); }, 1000);
}
}
function playpauseUpdates() {
autoupdate = !autoupdate;
if (autoupdate) {
$("#playImage").hide();
$("#pauseImage").show();
}
else {
$("#playImage").show();
$("#pauseImage").hide();
}
//clear the tickCounter
tickCount = 0;
if (autoupdate) {
updateTick();
}
}
小工具界面元素概述
- 显示/隐藏声望图表
- 手动刷新数据
- 导航到 CodeProject
- 数据刷新时显示的动画图像
- 播放/暂停自动刷新控件
- 鼠标悬停显示基本作者信息和版本号
- 关闭小工具
- 显示设置对话框
- 抓取控制柄以移动小工具
- 鼠标悬停在每个类别单元格上可查看会员级别工具提示,每个类别单元格的颜色会相应改变
- 刷新之间积分变化区域,例如 +5
- 类别声望积分
- 上次刷新日期/时间
测试代码
测试小工具确实有点烦人。通常,对于 JavaScript 测试,很容易在那里添加一些 alert
语句来查看发生了什么;但是,alert()
在小工具中已被禁用。然而,事实证明 window.prompt()
仍然可用并且可以使用。您可以将调试器附加到侧边栏进程,但对于简单的快速检查,这有点大材小用。
最终最简单的方法是进行更改,然后打包并安装小工具并使用它。根据需要重复此过程,随着时间的推移添加和删除 window.prompt()
。哦,感谢 GadgetPacker……稍后会详细介绍!
打包和部署/托管
正如文章开头所述,小工具只是一个重命名的 zip 文件,其中包含所有必要的文件,都包含在里面。您只需使用 Explorer 的“发送到”->“压缩(zipped)文件夹”功能,然后手动将输出文件重命名为您想要的任何小工具名称。
您可以想象,一遍又一遍地重复这个过程会变得非常乏味;最终,我写了一个小工具(称为 GadgetPacker)来执行此过程以及启动安装过程。您可以在 此处 阅读有关 GadgetPacker 的更多信息并获取副本。
小工具可以通过电子邮件分发,通过 Web 服务器提供,或者在网络上传输,当用户想要安装时,只需双击文件即可启动安装过程。
那么我如何使用这个扩展呢?
下载小工具文件,然后双击进行安装。首次安装小工具时,它将默认成员 ID 为作者的,刷新周期为 5 分钟。进入设置并输入您的成员 ID,可以在 CodeProject 上的个人资料页面找到。
扩展移除
可以通过从侧边栏控制面板卸载来移除小工具。
已知问题
由于小工具托管在 Internet Explorer 进程中,如果您使用“导航到 CodeProject”按钮,即使 Internet Explorer 不是您的默认浏览器,它也会被打开,因为使用了 window.open()
。
参考文献
历史
(版本号与代码更改相关,而不是文章修订版。)
- V1.2 - 2011 年 3 月 21 日:计算机重启后保留设置
- V1.1 - 2011 年 1 月 19 日:计算机重启后保留设置
- V1.0 - 2010 年 12 月 11 日:文章和代码发布的第一版