次へウィンドウキャプチャ以前にやったデスクトップ画面全体のキャプチャに続き、今回は任意のウィンドウのキャプチャを行ってみましょう。最前面でアクティブになっているウィンドウ(フォアグラウンドウィンドウ)のキャプチャを行ってみることにします。ウィンドウキャプチャは、次のような手順で行います。対象となるウィンドウのハンドルを取得するウィンドウのサイズを取得するウィンドウのデバイスコンテキストを取得する画像をHSPの画面にコピーするデバイスコンテキストを解放するそこで、まずは対象となるウィンドウのハンドルを取得する方法から説明していきましょう。ウィンドウハンドルを取得するフォアグラウンドウィンドウデスクトップ上の最前面でアクティブになっているウィンドウのことをフォアグラウンドウィンドウと呼びます。フォアグラウンドウィンドウのハンドルを取得するには、user32.dllが提供するGetForegroundWindow関数を呼び出します。GetForegroundWindow(VOID);この関数は引数を持ちません。関数の戻り値として、現在のフォアグラウンドウィンドウのハンドルが返ります。デスクトップウィンドウフォアグラウンドウィンドウの代わりに、デスクトップウィンドウのハンドルを取得することもできます。デスクトップウィンドウはデスクトップ画面全体を覆っているウィンドウのことで、このデスクトップウィンドウのキャプチャを行うことで、以前にも説明したスクリーンキャプチャを行うことができます。こちらは、以前のものとは別の手続きでスクリーンキャプチャを行うものです。デスクトップウィンドウのハンドルを取得するにはGetDesktopWindow関数を使います。この関数はuser32.dllにより提供されており、次のように定義されています。GetDesktopWindow(VOID);この関数もまた引数を持ちません。関数の戻り値として、デスクトップウィンドウのハンドルが返ります。指定することによってデスクトップ画面に対するデバイスコンテキストを取得することができるので、画面のサイズをウィンドウハンドルからではなくHSP標準関数ginfoから取得するのであれば、あえてデスクトップウィンドウのハンドルを取得する必要はないのですが。ウィンドウのサイズを取得する対象ウィンドウのハンドルを取得できたら、次にそのウィンドウのサイズを取得してしまうことにします。今回のウィンドウキャプチャでは、クライアント領域(アプリケーションの描画領域)だけの画像の取得と、非クライアント領域(タイトルバーやメニューなど)を含めたウィンドウ全体の画像の取得をそれぞれ行います。ウィンドウのサイズはそれぞれ異なるので、それらのサイズを取得する手続きも異なります。クライアント領域のみのサイズ対象ウィンドウのクライアント領域(アプリケーションによる描画領域)のみのサイズを取得したい場合には、user32.dllより提供されているGetClientRect関数を使います。rectangle);最初のhWndパラメータには、対象ウィンドウのハンドルを指定します。次のpRectパラメータには、RECT構造体のアドレスを指定します。以前にも記述しましたが、RECT構造体は以下のように定義されています。*LPRECT;GetClientRect関数にRECT構造体のアドレスを渡すと、この構造体にウィンドウのクライアント領域の座標が格納されます。クライアント座標は常にクライアント領域の左上の点を基準としているので、leftメンバとtopメンバは常に0になります。rightメンバとbottomメンバがそれぞれ右下の点のクライアント座標(x座標とy座標)であり、これらがそのままクライアント領域の幅と高さを表しています。非クライアント領域を含めたサイズウィンドウのクライアント領域だけでなく、タイトルバー、メニューバー、スクロールバーといった非クライアント領域も含めた対象ウィンドウ全体のサイズを取得するには、GetWindowRect関数を使います。この関数はuser32.dllによって提供されており、以下のように定義されています。rectangle);2つの引数hWndパラメータとpRectパラメータについては、上記のGetClientRect関数と同じです。GetWindowRect関数の場合には、クライアント領域の座標ではなく、ウィンドウ全体の座標がRECT構造体に格納されます。GetWindowRect関数で取得される座標はスクリーン座標で表されています。これは、スクリーンの左上の点を基準(座標ゼロ)とするものです。そのため、実際のウィンドウの幅はrightメンバからleftメンバを引いた値に、高さはbottomメンバからtopメンバを引いた値になります。ウィンドウのデバイスコンテキストを取得する次に、対象ウィンドウの描画を行っているデバイスコンテキストのハンドルを取得しなければいけません。これについても、クライアント領域(アプリケーションの描画領域)だけのデバイスコンテキストの場合と、非クライアント領域(タイトルバーやメニューなど)を含めたウィンドウ全体のデバイスコンテキストの場合とで、手続きが異なります。クライアント領域のみのデバイスコンテキストウィンドウのクライアント領域のみを取得したい場合には、クライアント領域のみに割り当てられているデバイスコンテキストのハンドルを取得します。これには、user32.dllより提供されているGetDC関数を使います。handle);hWndパラメータにはウィンドウハンドルを指定します。ここで指定されたウィンドウのクライアント領域に対するデバイスコンテキストのハンドルが戻り値として取得されます。指定することもできます。この場合には、デスクトップ画面に対するデバイスコンテキストのハンドルが取得されます。非クライアント領域を含めたデバイスコンテキスト非クライアント領域も含めたウィンドウ全体に対するデバイスコンテキストのハンドルを取得するには、GetWindowDC関数を使います。この関数はuser32.dllによって提供されており、以下のように定義されています。handle);hWndパラメータにはウィンドウハンドルを指定します。ここで指定されたウィンドウの全領域に対するデバイスコンテキストのハンドルが戻り値として取得されます。指定することによって、デスクトップ画面に対するデバイスコンテキストのハンドルを取得することができます。対象ウィンドウのサイズとデバイスコンテキストのハンドルを取得できたら、2つのデバイスコンテキスト間での画像コピーを行います。スクリーンキャプチャの際にも説明したように、画像のコピーにはgdi32.dllが提供するBitBlt関数を使います。code);コピー元として取得したデバイスコンテキストのハンドルを指定し、コピー先のデバイスコンテキストのハンドルとしてはシステム変数hwndの値を指定します。組み合わせを指定します。画像のコピーが終了したら、取得したデバイスコンテキストを解放しなければいけません。これには、user32.dllのReleaseDC関数を呼び出します。handle);最初のhWndパラメータには対象ウィンドウのハンドルを、次のhDCパラメータにはGetDC関数やGetWindowDC関数で取得されたデバイスコンテキストのハンドルを指定します。1つ注意しておくべきことは、以前のスクリーンキャプチャではCreateDC関数を使って取得したデスクトップ画面のデバイスコンテキストをDeleteDCで解放していましたが、今回のウィンドウキャプチャではGetDC関数またはGetWindowDC関数で取得したデバイスコンテキストをReleaseDC関数で解放しているということです。これらの関数の対応を間違えてはいけません。サンプルスクリプト今回のスクリプトでは、モジュール機能を使用しています。モジュール内で新たに定義されている命令は、指定されたウィンドウの画像をHSPのバッファウィンドウにコピーするCaptureWindow命令、アクティブなウィンドウの画像をコピーするCaptureActiveWindow命令、デスクトップ画面の画像をコピーするCaptureDesktopScreen命令の3つです。CaptureActiveWindow命令とCaptureDesktopScreen命令については、対象ウィンドウ(フォアグラウンドウィンドウやデスクトップウィンドウ)のハンドルを取得した直後にCaptureWindow命令を実行するという手続きをとっています。