Windows 7 タスク バーの動的なオーバーレイ アイコンと進行状況バー

みなさん、こんにちは。Windows 開発統括部の古内です。

今週はまた Windows 7 タスク バーの特集に戻りたいと思います。今日お届けするのは、2009 年 7 月 28 日に Developing for Windows Blog に 投稿された 「Windows 7 Taskbar Dynamic Overlay Icons and Progress Bars」 の翻訳です。


Windows 7 タスク バーの動的なオーバーレイ アイコンと進行状況バー

これまでの記事では、Windows 7 タスク バーの基本事項 (「Windows 7 タスク バー関連の開発 – Application ID」) と、アプリケーション用のジャンプ リストの作成方法 (「Windows 7 タスク バー関連の開発 – ジャンプ リストの活用 (その 1)」、「その 2」、「その 3」 ) について説明してきました。今回はこの Windows 7 タスク バーの優れた機能の中から、動的なオーバーレイ アイコンと、複数の状態を表示する進行状況バーの活用方法についてご紹介します。

Windows 7 の理念の核とも言えるのが、「ユーザーが主導権を握る (User Is in Control)」 ということです。つまり、デスクトップの外観や機能を、ユーザー自身がコントロールできるようにすることです。たとえば些細なことですが、タスク バー アイコンの配置を調整したり、タスク バーに表示するアイコンの数を制御したりすることができます。Windows 7 では、システム トレイ アイコン領域が非常にシンプルになり、デフォルトではほぼすべてのトレイ アイコンが非表示となっています。このため、通知メッセージのほとんどは表示されず、ユーザーが通知を目にする機会が減少していることが十分に考えられます。通知領域の更新情報についてさらに詳しく知りたい方は、こちらのブログ記事を参照してください。このあまり表示されなくなった通知を補う手段として、Windows 7 のタスク バーにはオーバーレイ アイコンと進行状況バーが提供されています。これらの機能を活用すれば、システム トレイ アイコン領域がなくても、さらにはアプリケーションのウィンドウが表示されていない状態であっても、アプリケーションの状況を適切に示すステータス情報をユーザーに提供することができます。ユーザーはアプリケーションのサムネイルやライブ プレビューを表示する必要もありません。重要なステータス更新があれば、タスク バー ボタンそのものに表示されます。この機能は、ユーザーが余分なクリック操作なしで簡単にアプリケーションの状態を確認できるようにする、ということを目指したマイクロソフトの取り組みの 1 つの成果です。

オーバーレイ アイコン

ネイティブのオーバーレイ機能は、ITaskbarList4 インターフェイス、具体的にはその SetOverlayIcon 関数で提供されています。 次のコード スニペットに示すとおり、この関数は、ウィンドウ ハンドル、アイコン ハンドル、およびオプションの説明テキストを使用します。

 HICON hIcon = NULL; // IDM_OVERLAY_CLEAR の場合
hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_OVERLAY1));
// ウィンドウのオーバーレイ アイコン (NULL 値が可能) を設定する
g_pTaskbarList->SetOverlayIcon(hWnd, hIcon, NULL);
if (hIcon) {
// アイコンが不要になったので、クリーンアップする
DestroyIcon(hIcon);
}

以前と同様に、ITaskbarList3 *g_pTaskbarList = NULL; を取得し、CoCreate を使用します。

 CoCreateInstance(
    CLSID_TaskbarList, 
    NULL, 
    CLSCTX_INPROC_SERVER, 
    IID_PPV_ARGS(&g_pTaskbarList));

上記のコードを適切な場所で実行すると (アプリケーションをダウンロードできます)、次の画像のような状態が表示されます。左の画像ではアプリケーションにオーバーレイ アイコンはありませんが、右の画像では赤色のアイコン オーバーレイが表示されています。

画像この機能のマネージ ラッパーは、Windows API Code Pack for the .NET Framework に含まれる Taskbar クラスにあります。この場合は、OverlayImage プロパティ (Taskbar.OverlayImage) を使用するだけです。単純に、次のように呼び出します。

 Taskbar.OverlayImage = 
        new OverlayImage(TaskbarDemo.Properties.Resources.Red, "Red");

これで、タスク バー ボタンにオーバーレイ イメージを指定することができます。この TaskbarDemo プロジェクトは WinForms のデモであり、上記のコードは TaskbarDemoMainForm.cs にあります。

また、同様の処理を WPF Window に対して実行する拡張メソッドも簡単に提供できます。適切なアイコンを入手する必要がありますが、.NET リソースを使用すればこれも簡単です。

進行状況バー

アプリケーションの最上位ウィンドウで標準の進行状況バーを使っている場合は、DMW がそれを特定し、既定でその進行状況がアプリケーション アイコン上にオーバーレイとして表示されます。ただし、アプリケーションのアイコン上に表示されるこの進行状況バーの動作はプログラムで制御することが可能です。

先ほどと同様、ネイティブのこの機能は ITaskbarList3 インターフェイスにありますが、今回は SetProgressState 関数と SetProgressValue 関数を使用します。これらの関数の機能はその名前から予想されるとおりです。SetProgressState は進行状況バーの状態 (たとえば、不確定、エラーなど) を設定します。SetProgressValue は進行状況の値を設定します。次のコード スニペットは、これらの関数の使用方法を示しています。

 case WM_TIMER:
    g_nProgress++;
    if (g_nProgress == 1)
    {
        // 最初は、進行状況の状態を不確定に設定する
        // この状態は、必要な処理の量を明らかにするための 
        // バックグラウンド計算が実行されていることを表す
        g_pTaskbarList->SetProgressState(hWnd, TBPF_INDETERMINATE);
    }
    else if (g_nProgress == MAX_PROGRESS_IND)
    {
        // 進行状況の状態を設定し、
        // 通常の進行状況として表示する処理があることを示す
        g_pTaskbarList->SetProgressValue(hWnd, 0, MAX_PROGRESS_NORMAL);
        g_pTaskbarList->SetProgressState(hWnd, TBPF_NORMAL);
    }
    else if (g_nProgress > MAX_PROGRESS_IND)
    {
        if (g_nProgress - MAX_PROGRESS_IND <= MAX_PROGRESS_NORMAL)
        {
            // バックグラウンドの処理の実行を表す、
            // 通常の進行状況を表示する
            g_pTaskbarList->SetProgressValue(
                                hWnd, 
                                g_nProgress - MAX_PROGRESS_IND, 
                                MAX_PROGRESS_NORMAL);
        }
        else
        {
            // 処理が完了したら、タイマーを停止し、進行状況の状態を 
            // リセットする
            KillTimer(hWnd, g_nTimerId);
            g_nTimerId = 0;
            g_pTaskbarList->SetProgressState(hWnd, TBPF_NOPROGRESS);
            MessageBox(hWnd, L"Done!", L"Progress Complete", MB_OK);
        }
    }
    break;

上記では、最初のタイマー チックで進行状況バーを TBPF_INDETERMINATE に設定し、その後で TBPF_NORMAL に設定しています。TBPF_NORMAL は、処理が完了するまでの推定残り時間に比例して進行状況インジケーターが左から右へ伸びていく通常の状態です。

マネージ コードの場合は Windows Code Pack API を使用します。ネイティブの進行状況バーと同様、マネージ コード Taskbar クラスにも進行状況バーのプロパティ (自身のクラス内) があります。これにより、現在の値、最大値、および進行状況バーの状態を設定することができます。この進行状況バーの状態 (TaskbarButtonProgressState クラスに含まれる) は、次のとおりです。

  • NoProgress – ネイティブの TBPF_NOPROGRESS 状態と同等
  • Indeterminate – ネイティブの TBPF_INDETERMINATE 状態と同等
  • Normal – ネイティブの TBPF_NORMAL 状態と同等
  • Error – ネイティブの TBPF_ERROR 状態と同等
  • Paused – ネイティブの TBPF_PAUSED 状態と同等

WinForms のデモについては、TaskbarDemo プロジェクトおよび TaskbarDemoMainForm.cs を参照してください。この中には、進行状況バーの更新のためにタイマーから呼び出される UpdateProgressBar 関数もあります。

 Taskbar.ProgressBar.State = 
    (TaskbarButtonProgressState)Enum.Parse(
            typeof(TaskbarButtonProgressState), 
            (string)comboBoxProgressBarStates.SelectedItem);

if (Taskbar.ProgressBar.State != TaskbarButtonProgressState.Indeterminate)
    Taskbar.ProgressBar.CurrentValue = progressBar1.Value;

ここまで見てきたとおり、コードによって進行状況バーの状態を選択することが可能です。エラー状態に変更すると、タスク バー アイコンに表示される進行状況バーの色が赤に変わります。

ファイル処理に標準の進行状況ダイアログを使用している場合は、何もしなくてもタスク バー アイコンにこの優れた進行状況バーを表示することができます (このシリーズ記事を通じて、Windows プログラミングの標準ガイドラインに従えば、多くの機能を無料で利用できることがおわかりいただけると思います)。たとえば、ファイル処理を SHFileOperation API または IFileOperation インターフェイスを使って実行すると、その処理の進行状況の情報 (エラーを含む) を示す進行状況バーがタスク バー ボタン上に自動的に表示されます。この機能は Windows エクスプローラーでも採用されて大成功を収めています。