Windows 秘話消えるカーソルの話

Raymond Chen

PrtSc キーを押してスクリーン ショットをキャプチャする際に、カーソルが少しの間点滅することにお気付きの方がいらっしゃるかもしれません。信じられないかもしれませんが、この現象は Windows XP をシャットダウンするときのフェードアウト画面で半透明のウィンドウが表示されないのと同じ理由で起こっている現象です。

通常、BitBlt 関数で画面からピクセル データを読み取るときには、このような半透明のウィンドウ (通称、レイヤード ウィンドウ) は含まれません。このウィンドウをキャプチャするには、CAPTUREBLT フラグを渡す必要があります。このフラグを渡すと、マウスのカーソルも点滅するようになります。では、この理由をご説明しましょう。

その昔、画面上にあるオブジェクトの上を動くオブジェクトはマウス カーソルだけでした。また、当初、システムでサポートされていたのは、モノクロのマウス カーソルだけでした。カーソルはソフトウェアでサポートされていましたが、高性能なビデオ カードが搭載されている場合は、ハードウェアでもサポートされていました。

ビデオ カードでサポートされているカーソルを使用すると、グラフィック デバイス インターフェイス (GDI) では、ビデオ カードにビットマップ情報とマスクを渡し「さあ、これがマウス カーソルです。私が指定する画面上の座標にそれを重ね合わせなさい」という指示を出します。ユーザーがマウスを動かすと、GDI からビデオ カードには随時最新の座標情報が渡され、ビデオ カードによって画面上のピクセル データを移動するという重労働が行われます。

一方、ソフトウェアでサポートされているカーソルを使用する場合は、GDI 側で、ピクセル データをフレーム バッファに出力する前に保存する必要があります。この処理は、どのように行われるかというと、ユーザーがマウスを動かすと、GDI では、その都度、直前のピクセル データを復元し、カーソルの移動先の下にあるすべてのピクセル データを保存してから、カーソルを新たな位置に移動します。

ハードウェアでサポートされているカーソルを使用している場合、ハードウェア自体が移動処理を行うため、フレーム バッファにマウス カーソルのピクセル データは実際には存在しません。そのため、BitBlt 関数では、単にフレーム バッファからピクセル データをコピーすることができます。というのも、そもそもフレーム バッファには、マウス カーソルのピクセル データは存在していないので、誤ってマウス カーソルのデータをコピーする心配はありません。

これに対して、ソフトウェアでサポートされているカーソルを使用している場合、コピーする範囲にカーソルが含まれているときには、BitBlt 関数を実行する前に、GDI がカーソルを取り除く必要があります。

アニメーション ポインタが使用されている場合、ハードウェアでサポートされているカーソルではうまく動作しません。というのも、ハードウェアでサポートされているカーソルはアニメーションには対応していないからです。そのため、アニメーション ポインタは、ソフトウェアで実装されています。

まあ、道理ですね。でも、それが CAPTUREBLT フラグと何の関係があるのか、ですって。今からご説明しますから、少しお待ちください。

Windows 2000 では、ソフトウェアでサポートされているカーソルの構成メカニズムが汎用化され、アプリケーションが、このメカニズムの利点を享受できるようになりました。この擬似カーソルが、後に、レイヤード ウィンドウとして普及しました。レイヤード ウィンドウは、ソフトウェアでサポートされているカーソルと同様、実際には存在しないので、BitBlt 関数で画面のデータをキャプチャする際には、レイヤード ウィンドウは表示されません。カーソルとレイヤード ウィンドウのピクセル データは、最終的には画面上で統合されます。

BitBlt 関数を使用して、レイヤード ウインドウのピクセル データをキャプチャする必要がある場合はどうしたら良いかというと、新しく導入された CAPTUREBLT フラグの出番です。このフラグを使用すると、構成エンジンによる処理が完了した後にピクセル データをキャプチャできます。Windows XP をシャットダウンするときのフェードアウト画面を生成するコードでは CAPTUREBLT フラグが渡されないので、レイヤード ウィンドウは表示されません。

これだけでは、カーソルが点滅する理由の説明になっていないと思われる方がいらっしゃるかもしれません。ですが、実は、それが説明になっているのです。マウスのカーソルも単なる構成オブジェクトなので、CAPTUREBLT フラグでキャプチャされます。スクリーン ショットをキャプチャする際にマウス カーソルがキャプチャされることを防ぐため、構成エンジンでは、カーソルを非表示にし、CAPTUREBLT フラグを渡してから、カーソルを再表示しています。

Windows 2000 の構成エンジンをアプリケーションに公開することによって、カーソルは特別な地位を失ったというわけです。これで、ちょうど話が振り出しに戻ったようです。つまり、フレーム バッファとソフトウェアでサポートされているカーソルしかなかった古き良き時代と同じ状態になりました。

Raymond Chen は、自分の Web サイト「The Old New Thing」(古くて新しいもの) および同じタイトルの著書 (Addison-Wesley、2007 年発行) で、Windows の歴史、Win32 プログラミング、そして新聞の見出しの読み間違いについて触れています。