通知と通知領域
通知領域とはタスク バーの一部であり、通知と状態の一時的なソースを提供する場所です。 また、バッテリ レベル、音量制御、ネットワーク ステータスなど、デスクトップ上に存在しないシステム機能やプログラム機能のアイコンを表示するためにも使用できます。 従来、通知領域はシステム トレイまたはステータス領域と呼ばれていました。
このトピックは、次のセクションで構成されています。
通知と通知領域のガイドライン
通知と通知領域の使用に関するベスト プラクティスについては、Windows ユーザー エクスペリエンス操作ガイドラインの「通知」セクションおよび「通知領域」セクションを参照してください。 目標は、操作の妨害や目障りになることなく、通知を適切に使用してユーザーに有益な情報を提供することです。
通知領域は、直ちに対処を要する重要な情報が対象ではありません。 また、プログラムやコマンドへの迅速なアクセスを目的としたものでもありません。 Windows 7 の時点では、機能の多くについては、アプリケーションのタスク バー ボタンを通じて実行する方法が最も効果的です。
Windows 7 では、ユーザーの選択によってはアプリケーションからのすべての通知を抑制できるため、アプリケーションで引き続き通知が表示されるようにユーザーに働きかけるには、通知を慎重に設計して使用する必要があります。 通知とは中断であるため、それだけの価値がある内容にすることが重要です。
Windows 7 では、"通知オフ時間" という概念が導入されています。 通知オフ時間は、新しいユーザーが初めて自分のアカウントにログインした後、またはオペレーティング システムのアップグレードやクリーン インストール後に初めてログインした後の最初の 1 時間として定義されます。 この時間は、ユーザーが通知に妨害されることなく、ユーザーが新しい環境を探索して慣れることができるようにするために設けられています。 この間、ほとんどの通知は送信も表示もされません。 ただし、USB デバイスを接続したり、ドキュメントを印刷したりする場合などに、ユーザーのアクションに応じて表示されるユーザーに必要なフィードバックなどは例外です。 通知オフ時間に関する API の詳細については、このトピックの後半で説明します。
通知の作成と表示
このトピックの残りのセクションでは、アプリケーションからユーザーへの通知を表示するための基本的な手順について説明します。
通知アイコンを追加する
通知を表示するには、通知領域にアイコンを配置する必要があります。 Microsoft Communicator やバッテリー レベルなどの特定のケースでは、対応するアイコンが既に表示されています。 他の多くのケースでは、通知を表示するために必要な期間のみ、通知領域にアイコンを追加します。 どちらの場合も、これは Shell_NotifyIcon 関数を使用して行います。 Shell_NotifyIcon を使用すると、通知領域のアイコンを追加、変更、または削除できます。
Windows 7 の通知領域にアイコンを追加すると、既定では通知領域のオーバーフロー セクションに追加されます。 この領域には、アクティブではあるが通知領域には表示されない通知領域アイコンが配置されます。 アイコンをオーバーフロー領域から通知領域に昇格できるのはユーザーのみですが、状況によっては、アイコンを短いプレビュー (1 分未満) として一時的に通知領域に昇格させることができます。
Note
通知領域にどのアイコンを表示するかについては、ユーザーが最終決定権を持つ必要があります。 通知領域に一時的でないアイコンをインストールする場合は、あらかじめユーザーにアクセス許可を求める必要があります。 また、ユーザーには、通知領域からアイコンを削除するオプション (通常はショートカット メニューを使用) も提供される必要があります。
Shell_NotifyIcon の呼び出しで送信される NOTIFYICONDATA 構造体には、通知領域アイコンと通知自体の両方を指定する情報が含まれます。 以下は、NOTIFYICONDATA を通じて設定できる、通知領域アイコンに固有の項目です。
- アイコンの取得元のリソース。
- アイコンの一意の識別子。
- アイコンのツールヒントのスタイル。
- 通知領域のアイコンの状態 (非表示、共有、またはその両方)。
- アイコンに関連付けられているアプリケーション ウィンドウのハンドル。
- アイコンを囲む四角形内とバルーン通知内で発生するイベントを、関連付けられたアプリケーション ウィンドウでアイコンが通信できるようにするコールバック メッセージ識別子。 アイコンを囲む四角形は、Shell_NotifyIconGetRect を使用して取得できます。
通知領域の各アイコンは、次の 2 つの方法で識別できます。
- レジストリでアイコンを宣言するために使用されている GUID。 これは Windows 7 以降で推奨される方法です。
- 通知領域アイコンに関連付けられたウィンドウのハンドルと、アプリケーション定義のアイコン識別子。 この方法は、Windows Vista 以前で使用されていました。
通知領域のアイコンには、ツールヒントを含めることができます。 ツールヒントには、標準のツールチップ (推奨) またはアプリケーションによって描画されるポップアップ UI のいずれかを使用できます。 ツールヒントの使用は必須ではありませんが、推奨されています。
通知領域のアイコンは、高 DPI に対応している必要があります。 アプリケーションでは、リソース ファイルに 16 x 16 ピクセルのアイコンと 32 x 32 ピクセルのアイコンの両方を提供し、LoadIconMetric を使用して正しいアイコンが読み込まれ、適切に拡大縮小されるようにする必要があります。
通知領域にアイコンを表示するアプリケーションは、そのアイコンに対するマウス クリックを処理する必要があります。 ユーザーがアイコンを右クリックすると、通常のショートカット メニューが表示されます。 ただし、マウスの左ボタンによる 1 回のクリックの結果は、アイコンの機能によって異なります。 ユーザーが必要とするものを、そのコンテンツに最適な形式 (ポップアップ ウィンドウ、ダイアログ ボックス、またはプログラム ウィンドウ自体) で表示する必要があります。 たとえば、状態アイコンに対して状態テキスト、ボリューム コントロールに対してスライダーを表示できます。
クリックの結果として表示されるポップアップ ウィンドウやダイアログ ボックスは、通知領域内でクリックされた座標付近に配置する必要があります。 その位置を判断するには、CalculatePopupWindowPosition を使用します。
次に示すように、NOTIFYICONDATA (上記で説明) のアイコン固有のメンバーのみを定義し、Shell_NotifyIcon を呼び出すことで、通知を表示せずに通知領域にアイコンを追加できます。
NOTIFYICONDATA nid = {};
// Do NOT set the NIF_INFO flag.
...
Shell_NotifyIcon(NIM_ADD, &nid);
Shell_NotifyIcon を 1 回呼び出すだけで、通知領域にアイコンを追加し、通知を表示する処理を行うこともできます。 これを行うには、このトピックの以下の手順に従ってください。
NOTIFYICONDATA バージョンを定義する
Windows の進化とともに、NOTIFYICONDATA 構造体が拡張され、より多くの機能を定義するためにより多くのメンバーが含まれるようになりました。 下位互換性を確保するために、通知領域アイコンで使用する NOTIFYICONDATA のバージョンを宣言するには、定数を使用します。 特別な理由がない限り、Windows Vista で導入された NOTIFYICON_VERSION_4 バージョンを使用することを強くお勧めします。 このバージョンでは、登録された GUID を使用して通知領域アイコンを識別する優先機能、優れたコールバック メカニズム、より優れたアクセシビリティなど、利用可能なすべての機能が提供されます。
バージョンを設定するには、以下の呼び出しを使用します。
NOTIFYICONDATA nid = {};
...
nid.uVersion = NOTIFYICON_VERSION_4;
// Add the icon
Shell_NotifyIcon(NIM_ADD, &nid);
// Set the version
Shell_NotifyIcon(NIM_SETVERSION, &nid);
この形での Shell_NotifyIcon の呼び出しでは、通知が表示されないことに注意してください。
通知の外観と内容を定義する
通知は、特殊な型のバルーン ツールヒント コントロールです。 タイトル、本文、アイコンが含まれています。 ウィンドウと同様、右上隅に [閉じる] ボタンがあります。 また、コントロール パネルの [通知領域アイコン] 項目を開く [オプション] ボタンも含まれています。ユーザーはこれを使用してアイコンを表示または非表示にしたり、アイコンなしで通知のみを表示したりできます。
Shell_NotifyIcon の呼び出しで送信される NOTIFYICONDATA 構造体には、通知領域アイコンと通知バルーン自体の両方を指定する情報が含まれます。 以下は、NOTIFYICONDATA を通じて設定できる通知に固有の項目です。
- 通知バルーン内に表示されるアイコン。通知の種類によって指定されます。 カスタム アイコンと同様に、アイコンのサイズを指定できます。
- 通知のタイトル。 このタイトルは、英語で最大 48 文字にする必要があります (ローカライズに対応するため)。 タイトルは通知の最初の行であり、フォントのサイズ、色、太さによって区別されます。
- 通知の本文で使用するテキスト。 このテキストは、英語で最大 200 文字にする必要があります (ローカライズに対応するため)。
- 通知をすぐに表示できない場合に破棄するかどうかの情報。
- 通知のタイムアウト。 Windows Vista 以降のシステムではこの設定が無視され、システム全体のアクセシビリティ タイムアウト設定が優先されます。
- 通知に通知オフ時間を反映させるかどうかは、NIIF_RESPECT_QUIET_TIME フラグで設定されます。
Note
IUserNotification インターフェイスおよび IUserNotification2 インターフェイスは、Shell_NotifyIcon のコンポーネント オブジェクト モデル (COM) ラッパーです。 ただし、現時点では、GUID を使用して通知領域アイコンを識別するなど、Shell_NotifyIcon を介して直接利用できる完全な NOTIFYICON_VERSION_4 機能は提供されていません。
ユーザーの状態を確認する
システムは、SHQueryUserNotificationState 関数を使用して、ユーザーとコンピューターの状態として、通知オフ時間中、ユーザーが離席中、プレゼンテーション モードなど割り込むことができない状態にある、などを確認します。 システムが通知を表示するかどうかは、この状態によって決定されます。
Note
アプリケーションで Shell_NotifyIcon、IUserNotification、または IUserNotification2 を使用しないカスタム通知メソッドを使用している場合は、その時点で通知 UI を表示するかどうかを判断するために、常に SHQueryUserNotificationState を明示的に呼び出す必要があります。
ユーザーの離席中に送信された通知は表示用のキューに入れられますが、ユーザーがいつ戻ってくるか、その時点で通知が有効になるかどうかはわからないため、後で通知を再送することを検討してください。
通知オフ時間中に送信された通知は、表示されることなく破棄されます。 設計ガイドラインでは、すべての通知を無視できるようにすることが求められています。 通知では、ユーザーによる即時のアクションを要求しないようにします。 つまり、通知オフ時間より優先するほど重要な通知を設定すべきではないということです。
通知を表示する
NOTIFYICONDATA バージョンを設定し、 NOTIFYICONDATA 構造体で通知を定義したら、Shell_NotifyIcon を呼び出してアイコンを表示します。
通知領域アイコンが存在しない場合は、Shell_NotifyIcon を呼び出してアイコンを追加します。 これは、一時的なアイコンと一時的でないアイコンの両方に対して行います。
NOTIFYICONDATA nid = {}; ... Shell_NotifyIcon(NIM_ADD, &nid);
通知領域アイコンが既に存在する場合は、Shell_NotifyIcon を呼び出してアイコンを変更します。
NOTIFYICONDATA nid = {}; ... Shell_NotifyIcon(NIM_MODIFY, &nid);
次のコードは、NOTIFYICONDATA データを設定し、 Shell_NotifyIcon 経由で送信する例を示しています。 この例では、GUID を使用して通知アイコンを識別しています (Windows 7 で推奨)。
// Declare NOTIFYICONDATA details.
// Error handling is omitted here for brevity. Do not omit it in your code.
NOTIFYICONDATA nid = {};
nid.cbSize = sizeof(nid);
nid.hWnd = hWnd;
nid.uFlags = NIF_ICON | NIF_TIP | NIF_GUID;
// Note: This is an example GUID only and should not be used.
// Normally, you should use a GUID-generating tool to provide the value to
// assign to guidItem.
static const GUID myGUID =
{0x23977b55, 0x10e0, 0x4041, {0xb8, 0x62, 0xb1, 0x95, 0x41, 0x96, 0x36, 0x69}};
nid.guidItem = myGUID;
// This text will be shown as the icon's tooltip.
StringCchCopy(nid.szTip, ARRAYSIZE(nid.szTip), L"Test application");
// Load the icon for high DPI.
LoadIconMetric(hInst, MAKEINTRESOURCE(IDI_SMALL), LIM_SMALL, &(nid.hIcon));
// Show the notification.
Shell_NotifyIcon(NIM_ADD, &nid) ? S_OK : E_FAIL;
アイコンを削除する
アイコンを削除するには (通知をブロードキャストするためにアイコンを一時的に追加した場合など)、次のように Shell_NotifyIcon を呼び出します。 この呼び出しで必要になるのは、アイコンを識別する最小限の NOTIFYICONDATA 構造体のみです。
NOTIFYICONDATA nid = {};
...
Shell_NotifyIcon(NIM_DELETE, &nid);
Note
アプリケーションをアンインストールしても、対応する通知領域アイコンは、最大 7 日間、コントロール パネルの [通知領域アイコン] ページのオプションとしてユーザーに表示されます。 ただし、そこで変更を加えても効力はありません。
SDK のサンプル
Shell_NotifyIcon の完全な使用例については、Windows ソフトウェア開発キット (SDK) の NotificationIcon サンプルを参照してください。
関連トピック