日々のコンピュータ情報の集積と整理

Dr.ウーパのコンピュータ備忘録

2014年2月3日月曜日

C#で他のプロセスのウインドウ画像をキャプチャする方法を検討して行き着いた結果

C#で他のプロセスが立ち上げたウィンドウの画像をキャプチャする方法をあれこれと検討していました。



方法1:ウィンドウハンドルからControlオブジェクトを生成し、Control.DrawToBitmapメソッドを使用し、ウィンドウの画像をビットマップに保存する


以下の記事を参考にし、

(1) ウィンドウのタイトルからウィンドウを保持するProcessオブジェクトを取得
(2) Processオブジェクトが保持するメインウィンドウのウィンドウハンドル(MainWindowHandle)を使って、Control.FromHandleによりControlオブジェクトを生成
(3) Control.DrawToBitmapを使用してウィンドウの画像をビットマップに保存

という流れを試してみました。

ウィンドウのタイトルからプロセスを探す
http://dobon.net/vb/dotnet/process/getprocessesbywindowtitle.html

フォームやコントロールの外観をキャプチャする - .NET Framework 2.0以降で、Control.DrawToBitmapメソッドを使用する方法
http://dobon.net/vb/dotnet/graphics/invokepaint.html#drawtobitmap


しかし、ProcessオブジェクトのMainWindowHandleには正常な値が入っていたにもかかわらず、Control.FromHandleの結果がnullとなってしまい、Control.DrawToBitmapにて例外が発生してしましました。
インターネットを検索してみると、どうやら他のプロセスのウィンドウハンドルを使用して、Control.FromHandleを行うとnullになってしまう模様。(要確認)

方法2:Win32APIのPrintWindow関数を使用して、ウィンドウの画像をビットマップに保存する

以下の記事を参考にし、

(1) ウィンドウのタイトルからウィンドウを保持するProcessオブジェクトを取得
(2) Win32APIのPrintWindow関数を使用して、ウィンドウの画像をビットマップに保存

という流れを試してみました。

フォームやコントロールの外観をキャプチャする - Win32 APIを使用した方法 - PrintWindow関数
http://dobon.net/vb/dotnet/graphics/invokepaint.html#section2


この方法でウィンドウのキャプチャはできたものの、自分が目的とするJavaのAwtで記載されたGUIアプリケーションのウィンドウ画像はうまくキャプチャできませんでした。(理由は良くわかりませんが、うまく画像キャプチャできなかったアプリケーションは一般的な方法で画面を描画していない?)
それと、ウィンドウが最小化されている場合もウィンドウの画像のキャプチャはうまくいかないことがわかりました。この点は妥協するしかなさそうです。

方法3:GraphicsクラスのCopyFromScreenメソッドを使用してウィンドウの画像をビットマップに保存する

以下の記事を参考にし、

(1) ウィンドウのタイトルからウィンドウを保持するProcessオブジェクトを取得
(2) ウィンドウを最前面に表示する
(3) ウィンドウの位置とサイズを目的のサイズに変更する
(4) GraphicsクラスのCopyFromScreenメソッドを使用して、ウィンドウの画像をビットマップに保存

という流れを試してみました。

スクリーンやウィンドウをキャプチャするには?[2.0のみ、C#、VB]

外部アプリケーションを起動して、ウィンドウの位置とサイズを変更する

多重起動禁止時に実行中のWindowsアプリケーションを最前面に表示するには?


この結果、目的とするウィンドウ画像をキャプチャすることが出来ました。
ただ、この方法だとウィンドウの上に他のウィンドウが表示されている場合などには、他のウィンドウが表示されたまま(ディスプレイで見たまま)、ウィンドウの画像がキャプチャされます。


まずは最低限の目的が達成できたので、まずはこの方法を採用します。







関連記事

関連記事を読み込み中...

同じラベルの記事を読み込み中...