スクリーンキャプチャ

概要:ディスプレイに表示されている画像を取得する

スクリーンキャプチャに似た言葉にデスクトップキャプチャというのがあります。
ここで、それぞれの言葉は次の意味であるとします。

デスクトップ:ウィンドウを含まない壁紙とアイコンなどで構成された画面
スクリーン:ウィンドウを含むデスクトップ

スクリーン自体もウィンドウです。

この定義が意味するところのデスクトップを(普通の方法で)キャプチャする事は出来ません。
今回解説するのもスクリーンキャプチャです。

■スクリーンのウィンドウハンドルを取得する

スクリーンのウィンドウハンドルは GetDesktopWindow 関数で取得できます。

HWND GetDesktopWindow(void);

戻り値はスクリーンのウィンドウハンドルです。

今回の要点はこれだけ!
後は分かると思うので、簡単に解説します。

ウィンドウハンドルを取得したら、ウィンドウのサイズを取得しましょう。
このサイズに合わせてビットマップを作成します。

HWND desktop;
RECT rc;
static int width,height;

//スクリーンの情報を得る
desktop=GetDesktopWindow();
GetWindowRect(desktop,&rc);
width=rc.right;
height=rc.bottom;

■ビットマップ作成

スクリーンのサイズに合わせてビットマップを作成します。

HDC hdc;
static BITMAPINFO bmpInfo;
static LPDWORD lpPixel;
static HBITMAP hBitmap;
static HDC hMemDC;

//DIBの情報を設定する
bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth=width;
bmpInfo.bmiHeader.biHeight=height;
bmpInfo.bmiHeader.biPlanes=1;
bmpInfo.bmiHeader.biBitCount=32;
bmpInfo.bmiHeader.biCompression=BI_RGB;

//DIBSection作成
hdc=GetDC(hWnd);
hBitmap=CreateDIBSection(hdc,&bmpInfo,DIB_RGB_COLORS,(void**)&lpPixel,NULL,0);
hMemDC=CreateCompatibleDC(hdc);
SelectObject(hMemDC,hBitmap);
ReleaseDC(hWnd,hdc);

■スクリーンをビットマップにコピー

スクリーンのウィンドウハンドルからデバイスコンテキストハンドルを取得して、これをコピー元とします。

//スクリーンをDIBSectionにコピー
hdc=GetDC(desktop);
BitBlt(hMemDC,0,0,width,height,hdc,0,0,SRCCOPY);
ReleaseDC(desktop,hdc);

ここで GetDC 関数に NULL を渡しても同じ事になります。
ヘルプには「NULL を指定すると、GetDC は画面全体を表すデバイスコンテキストを取得します」という記述があります。

■表示

キャプチャした画像は保存しても良いですが、今回は表示するだけにします。

PAINTSTRUCT ps;

case WM_PAINT:
    hdc=BeginPaint(hWnd,&ps);
    //表画面へ転送
    BitBlt(hdc,0,0,width,height,hMemDC,0,0,SRCCOPY);
    EndPaint(hWnd,&ps);
    return 0;

■後処理

解放処理です。
お忘れ無きように。

case WM_DESTROY:
    //自らlpPixelを解放するべからず
    DeleteDC(hMemDC);
    DeleteObject(hBitmap);  //BMPを削除した時、lpPixelも自動的に解放される
    PostQuitMessage(0);
    return 0;

キーカーソルやツールチップもキャプチャされます。
ただしマウスカーソルはキャプチャされないみたいです。
PaintShopPro ではマウスカーソルも含めない事も含める事も出来るので、何か方法があるのかもしれません。
何かが何であるかは今の私には分かりませんが……。

★☆ ソースファイル表示 ☆★


戻る / ホーム