Windows7のタスクバーに表示されるウィンドウのアイコンについて

はじめはバグではないかと思った挙動なのですが、色々試すうちに「こういうもの」なんだろうなと思い直しました。

しかし、分かりにくいので整理してみます(あんまり整理できてないかもですが)

前提

Windowsプログラムはexeファイル自体にアイコン画像が埋め込まれています。

エクスプローラ等ではexeファイルからこのアイコン画像を抽出して表示するわけです。

そして、プログラムを起動すると、タスクバーにも基本的にこのアイコンが表示されます。

Windows7のタスクバー

Windowsのタスクバーは、Windows7において大きく手が加えられました。

タスクバーの改良点は色々ありますが、ここで注目するのは以下の2点です。

  • プログラム(ウィンドウ)のアイコンとして「大きいアイコン」を使用するようになった。
  • MacOSXのDockのように、起動していないプログラムのアイコンをタスクバー上に固定してランチャーとして使用できるようになった(タスクバーにこのプログラムを表示する 設定)

ウィンドウのアイコン(WM_SETICON, WM_GETICON)

ここからの話はWindowsのバージョンによって異なります。以下はWindows7での動作となります。

タスクバーに表示されるプログラムのアイコンは、基本的にexeファイルに埋め込まれているアイコン画像が使用されるのですが、WindowsからWM_GETICON(wParam=ICON_BIG)というウィンドウメッセージが送信されたときに適当なアイコンを返してあげることにより、任意のアイコンをウィンドウのアイコンとして使用できるようになります。WM_GETICONが送信されるのは

  • プログラム起動時
  • ウィンドウのキャプションを変更する等したとき(おそらく再描画がかかるため)
  • WM_SETICON(wParam=ICON_SMALL)というウィンドウメッセージを送ったとき

WM_SETICON(wParam=ICON_SMALL)を送るとWM_GETICON(wParam=ICON_BIG)が送られてくるというのがイマイチ理解できませんが、とにかくプログラムからWM_SETICONを送ることで「任意のタイミングで」「任意のアイコンを」ウィンドウのアイコンに設定することができるわけです。

ちなみに、WM_SETICONで送信するアイコンハンドルは、適当な乱数でもよく、WM_GETICONに対して適切なアイコンハンドルを返すことが必要なようです。

ウィンドウの結合とアイコン

ここからが本題です。

Windows7のタスクバーには、同一プログラムのウィンドウが複数あるとき、それらを1プログラムのスペースに纏めて表示する(結合)という機能があります。

タスクバーのプロパティから「タスクバー」→「タスクバーのボタン」の値が「常に結合、ラベルを非表示」または「タスクバーがいっぱいの場合に結合」となっている場合、結合が行われます。

WM_SETICONやWM_GETICONでのアイコンの設定は、ウィンドウに対して行われるものですから、結合が行われると、1つの表示領域に対して複数のアイコンが存在してしまうことになります。

この問題に対して、Windowsはどうするのでしょうか?

答えはなぜか2つあります。

プログラムが「タスクバーにこのプログラムを表示する」に設定されている場合は、exeファイル埋め込みのアイコンが使用されます。

プログラムが「タスクバーにこのプログラムを表示する」に設定されていない場合は、先頭のウィンドウのアイコンが使用されます。

特に、タスクバーボタンの設定が「常に結合、ラベルを非表示」となっている場合、ウィンドウが1つしかなくても内部的には1つのウィンドウが「結合」されている状態らしく、「タスクバーにこのプログラムを表示する」に設定すると即アイコンがexeファイル埋め込みのものになってしまいます。

カテゴリー: Windows, Windows7   パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>