65.9K
CodeProject 正在变化。 阅读更多。
Home

Windows 7 侧边栏小工具 - CodeProject 声望观察者

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.94/5 (49投票s)

2010年12月11日

CPOL

8分钟阅读

viewsIcon

142655

downloadIcon

5110

Windows 7 小工具,可抓取您的声望积分和图表,并跟踪更新之间的变化

gadget_main.png

引言

继我之前编写的 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>

有一些基本属性,如 nameversiondescription,它们不言而喻。iconsdefaultimage 元素定义了可供 Windows 使用的图像;这些图像出现在安装时的小工具选择页面上,以及将小工具拖到桌面上时。base 元素包含一个 src 参数,该参数定义了要打开的作为主要小工具元素的 HTML 文件。其他一些元素是强制性的值,必须使用,并且在 MSDN 文档中已定义。其中一些元素也用于小工具选择屏幕,为用户提供信息,如下所示

gadget_select.png

小工具初始化、配置和设置

当小工具启动时,代码会配置小工具中的一些功能,即用于设置对话框的 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 文件并向用户显示对话框。

gadget_settings.png

添加和使用 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();
    }
}

小工具界面元素概述

gadget_parts.png

  1. 显示/隐藏声望图表
  2. 手动刷新数据
  3. 导航到 CodeProject
  4. 数据刷新时显示的动画图像
  5. 播放/暂停自动刷新控件
  6. 鼠标悬停显示基本作者信息和版本号
  7. 关闭小工具
  8. 显示设置对话框
  9. 抓取控制柄以移动小工具
  10. 鼠标悬停在每个类别单元格上可查看会员级别工具提示,每个类别单元格的颜色会相应改变
  11. 刷新之间积分变化区域,例如 +5
  12. 类别声望积分
  13. 上次刷新日期/时间

测试代码

测试小工具确实有点烦人。通常,对于 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 日:文章和代码发布的第一版
© . All rights reserved.