bakuchan.com

プログラミングなコーナ

Windows Programming なコーナーを作ってみました。 開発環境は、Microsoft VisualStudio C++ Express Edition で .NET(3.5)で動くようなものを考えています。

画面キャプチャソフトを作ってみる。

MFCコードに多くの間違いが見つかったので訂正します 画面キャプチャ、スクリーンショットともいう、とにかく画面を 撮影したい、という目的を果たすためのソフトです。 「PrintScreen」ボタンを押して、 「ペイント」で貼り付けたらいいというものありますが、 私がものすごくめんどくさがりなので、 画面キャプチャソフト(PF-KAMERA:無料ソフト)を作りました。 (PF-KAMERA)はMFCで書かれていますが、 ここでは.NETプログラミングで作る方法を書きたいと思います。
画面キャプチャソフトの作り方のうち、PictureBoxを使う方法は他のサイトで紹介されています。 ここでは、PicutureBoxを使わない方法を紹介したいと思います。

.NET(C++)で見た画面キャプチャ

.NETの場合は
Bitmap
Image
Graphics
の三つのクラスだけを使います。 VisualStudioを使う場合、 まず、プロジェクトの新規作成を行います。 次に、Form1にボタンを一つつけてください。 つけたボタンをダブルクリックすると、 ボタンの動作を記述するコード(Form1.h)が表示されます。
それではボタンの動作、の中身を書いていきます。
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
//ここから
	//第一画面を取得
	Screen^ screen;screen=Screen::PrimaryScreen;
	//第一画面のサイズを取得
	System::Drawing::Rectangle rc=screen->Bounds;
	//第一画面のサイズをもとにBitmapを作成
	Bitmap^ myBitmapScreen=gcnew Bitmap(rc.Width,rc.Height);
	//BitmapでImageを初期化。これで保存の準備完了
	Image^ imgScreen=myBitmapScreen;
	//ImageでGraphicsを初期化、これで画面のはりつけ準備完了
	Graphics^ g= Graphics::FromImage(imgScreen);
	//画面をImageにはりつけ
	g->CopyFromScreen(0,0,0,0,rc.Size);
	//Imageの画像を名前を付けて保存
	imgScreen->Save("名前を付けて保存.bmp");
//ここまで書き込む
}

MFCで見た画面キャプチャ

MFCを用いたプログラミングでは、 Windows95APIのお世話にいろいろとなるわけでして、中でも次の3つのお世話になるわけです。
HWND、ウィンドハンドル
HDC、デバイスコンテキストのハンドル
HBITMAP、ビットマップハンドル
これにCImageを加えて、画面の保存を行います。 MFCだとこんな感じになります。
//ここから(ソース1)
HWND hWnd;//ウィンドハンドル
HDC hDC;//デバイスコンテキストのハンドル
HBITMAP hBitmap;//ビットマップハンドル


CWnd cWnd;//Windowクラス.MFC
cWnd.GetDesktopWindow();//画面を取得


//画面のデバイスコンテキストを取得
CWindowDC cWndDC(&cWnd);//WindowDCクラス.MFC
CDC  *pDC;//デバイスコンテキストクラスへのポインタ.MFC
hDC=cWndDC.m_hDC;//画面のデバイスコンテキストのハンドルを取得

int nSizeX=GetSystemMetrics(SM_CXSCREEN);//画面の横幅を取得;
int nSizeY=GetSystemMetrics(SM_CYSCREEN);//画面のたて幅を取得;

hBitmap=CreateCompatibleBitmap(hDC,nSizeX,nSizeY);
/*取得した画面のデバイスコンテキストのハンドルと
画面サイズからhBitmapに画面をはりつけます*/


cWndDC.DeleteDC();
//画面のデバイスコンテキストを解放。これをしないとエラーになります。
//ここまで(ソース1)
この時点でhBitmapには、画面の画像が格納されています。
hBitmapの保存ですが、ATLのCImageクラスを使うなら、 (ソース1)を次のように書き換えます。
//ここから(ソース2)

/*CImageを使う場合には
#include "atlstr.h"
#include "atlimage.h"
が必要です。
*/


HWND hWnd;//ウィンドハンドル
HDC hDC;//デバイスコンテキストのハンドル
HBITMAP hBitmap;//ビットマップハンドル


CWnd cWnd;//Windowクラス.MFC
cWnd.GetDesktopWindow();//画面を取得


//画面のデバイスコンテキストを取得
CWindowDC cWndDC(&cWnd);//WindowDCクラス.MFC
CDC  *pDC;//デバイスコンテキストクラスへのポインタ.MFC
hDC=cWndDC.m_hDC;//画面のデバイスコンテキストのハンドルを取得

int nSizeX=GetSystemMetrics(SM_CXSCREEN);//画面の横幅を取得;
int nSizeY=GetSystemMetrics(SM_CYSCREEN);//画面のたて幅を取得;

hBitmap=CreateCompatibleBitmap(hDC,nSizeX,nSizeY);
/*取得した画面のデバイスコンテキストのハンドルと
画面サイズからhBitmapに画面をはりつけます*/


	//ここから追加分
   if(hBitmap){
	CImage image;//CImageクラス
	HRESULT hResult;//処理の結果を格納
	//CImageクラスのためのデバイスコンテキストクラスへのポインタ.MFC
	CDC* pCImageDC;
	HDC hCImageDC;//CImageクラスのためのデバイスコンテキストのハンドル
		image.Attach(hBitmap);//CImageにhBitmapをはりつけ
		//CImageクラスからデバイスコンテキストのハンドルを取得
		pCImageDC = CDC::FromHandle(image.GetDC());
		hCImageDC=pCImageDC->m_hDC;
		//BitBltで画面をはりつける
		BitBlt(hCImageDC,0,0,nSizeX,nSizeY,hDC,0,0,SRCCOPY);
		hResult=image.Save("名前を付けて保存.bmp");//ここで保存
	image.ReleaseDC();//これをしないとエラーになります。

    }
	//追加おわり



cWndDC.DeleteDC();
//画面のデバイスコンテキストを解放。これをしないとエラーになります。

//ここまで(ソース2)

最後に

画面キャプチャソフトの作り方を.NET(C++)とMFC(C++)でみてきましたが、 .NETの場合、7行で、画面が保存できてしまいます。正直、MFCよりもかなり楽です。 ここに書いた内容に間違いがありました。 すみません。お読みくださりありがとうございました。

おまけ

ATLのCImageも、.NETのImageも、 BMP,JPG,GIF,PNGのファイル形式をサポートしています。 拡張子を適宜変えるだけで、保存できてしまいます。 .NETのコードで エラーになる場合には、Form1.hのファイルの先頭を見てください。

#pragma once
の数行下に使用する名前空間が出てきますので
	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;
	using namespace System::Drawing::Drawing2D;
	using namespace System::Drawing::Imaging;
となるように書き換えてください。 不必要なものも書いてありますが、 これだけそろっていれば、エラーは吐かないと思います。

Powered by poipos.net

ネット検閲回避ソフト 戦中戦後、70年以上にわたる人権活動のノウハウをもとに開発された検閲回避技術と蓄積があります。 ネット検閲回避ソフトのご用命はbakuchan.comまで。 mail@bakuchan.com MIDIフェイクプログラムmfango はこちら