今回は、昔から使える、コーディングが必要な方法など。
GetDC(NULL)
GetDC() に NULL を渡すと画面全体を表すデバイスコンテキストが取れます。このデバイスコンテキストはマルチディスプレイ環境であってもすべてのディスプレイを連結したものとして扱えます。これを BitBlt() でコピーして保存すれば OK です。
PrintScreen キーを使った場合、デバイス座標系の原点が取得したスクリーンショットのどの座標に対応しているのかは頑張ってディスプレイの配置を取得しなければわかりませんが、GetDC() を使った方法なら対応は自明となります。もっとも、マルチディスプレイ環境であれば画面全体の範囲がどうなっているかは結局ディスプレイの配置を取得しなければわからないわけですが。
GetDC(hWnd)
GetDC() にウィンドウハンドルを渡すと、そのウィンドウのクライアント領域を表すデバイスコンテキストが取れます。
ここで、Windows XP などと違うのは、ウィンドウが画面からはみ出していたり他のウィンドウに隠れていたりしていてもクライアント領域全体を正しく表すということです。つまり、隠れている部分の画像も取得できます。なお、これはウィンドウコンポジションが有効な時(平たく言えば Aero Glass が有効な時)の話です。
GetWindowDC(hWnd)
GetWindowDC() にウィンドウハンドルを渡すと、そのウィンドウ全体を表すデバイスコンテキストが取れます。
ウィンドウが画面からはみ出していたり他のウィンドウに隠れていたりしていても無関係なのは GetDC() の場合と同じですが、GetWindowDC() の場合はさらに「ウィンドウ枠に相当する部分の画像は無意味なものが入っている」という点が XP と異なります。運が良ければ正しいウィンドウ枠が入っていますが。
まとめ
- 利点
- プログラムからの取り扱いが楽。
- 欠点
- ウィンドウ枠は取れない(GetWindowDC の場合)。
その3に続く…はず
Vista/7 でスクリーンショット(その3)
Windows 7 で使える undocumented API を使った方法。 Windows 7 の user32.dll には DwmGetDxSharedSurface() という undocumented な API があります。Vista には無いようです。 typedef BOOL WINAPI DwmGetSharedSurface(HWND hWnd, …