3

VS2008、MFC、C++ プロジェクトで、ウィンドウの内容 (クライアント領域) をキャプチャしたいと考えています。ここで説明されている PrintWindow 手法を使用してみました: C++ でウィンドウのスクリーンショットをビットマップ オブジェクトとして取得する方法は?

次のコードを使用して、ウィンドウの内容をブリットすることも試みました。

void captureWindow(int winId)
{
HDC handle(::GetDC(HWND(winId)));
CDC sourceContext;
CBitmap bm;
CDC destContext;

if( !sourceContext.Attach(handle) )
{
    printf("Failed to attach to window\n");
    goto cleanup;
}

RECT winRect;
sourceContext.GetWindow()->GetWindowRect(&winRect);
int width = winRect.right-winRect.left;
int height = winRect.bottom-winRect.top;

destContext.CreateCompatibleDC( &sourceContext );

if(!bm.CreateCompatibleBitmap(&sourceContext, width, height)) {
    printf("Failed to create bm\n");
    goto cleanup;
}

{
    //show a message in the window to enable us to visually confirm we got the right window
    CRect rcText( 0, 0, 0 ,0 );
    CPen pen(PS_SOLID, 5, 0x00ffff);
    sourceContext.SelectObject(&pen);
    const char *msg = "Window Captured!";
    sourceContext.DrawText( msg, &rcText, DT_CALCRECT );
    sourceContext.DrawText( msg, &rcText, DT_CENTER );

    HGDIOBJ hOldDest = destContext.SelectObject(bm);
    if( hOldDest==NULL )
    {
        printf("SelectObject failed with error %d\n", GetLastError());
        goto cleanup;
    }

    if ( !destContext.BitBlt( 0, 0, width, height, &sourceContext, 0, 0, SRCCOPY ) ){
        printf("Failed to blit\n");
        goto cleanup;
    }

    //assume this function saves the bitmap to a file
    saveImage(bm, "capture.bmp");

    destContext.SelectObject(hOldDest);
}
cleanup:
    destContext.DeleteDC();
    sourceContext.Detach();
    ::ReleaseDC(0, handle);
}

このコードは、ほとんどのアプリケーションで正常に機能します。ただし、スクリーンショットをキャプチャする必要がある特定のアプリケーションには、OpenGl または Direct3D を使用してレンダリングされたと思われるウィンドウがあります。どちらの方法でも、アプリの大部分を問題なくキャプチャできますが、「3D」領域は黒く残るか文字化けします。

私はアプリケーション コードにアクセスできないため、変更することはできません。

「3d」ウィンドウを含むすべてのコンテンツをキャプチャする方法はありますか?

4

1 に答える 1

0

The data in your 3D area is generated by the graphics adapter further down the graphics funnel and may not be available to your application to read the byte data from the rendering context. In OpenGL you can can use glReadPixels() to pull that data back up the funnel into your application memory. See here for usage: http://www.opengl.org/sdk/docs/man/xhtml/glReadPixels.xml

于 2013-02-01T22:59:30.003 に答える