Click here to Skip to main content
15,867,921 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Dear All,
I have a question that is : How can I get each application's surface..
That means I want to get each application windows' contents.

I use GDI function to get window handle and get it's DC

I use below code and pass g_FGWnd to this funtion to get DC.
But it is wired, it works fine at Win 7 32bit OS.
But can't get Win8 64 bit's OS, I build both 32bit app and 64bit app.
It still can't.

I can't get IE under Win8.
And can't get Windows Media Player when using it playing a video. it retrieve a black block with white background.
Windows Media Player is consist on both Win 7 and Win 8.

Could Someone know why it was?
Thanks.


CPaintDC dc(g_FGWnd);
    CRect rect;
    g_FGWnd->GetClientRect(&rect);

    bmpWin.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
    memDC.CreateCompatibleDC(&dc);
    memDC.SelectObject(&bmpWin);

    memDC.BitBlt(0, 0, rect.Width(), rect.Height(), &dc, 0, 0, SRCCOPY|CAPTUREBLT);

    CFile file;
    CFileException e;

    if(!file.Open(dlg.GetPathName(), CFile::modeWrite | CFile::modeCreate, &e))
    {
        e.ReportError();
        return;
    }

    BITMAP bmp;
    bmpWin.GetBitmap(&bmp);

    WORD wColorBits = bmp.bmBitsPixel * bmp.bmPlanes;
    if (wColorBits == 1)
        wColorBits = 1;
    else if (wColorBits <= 4)
        wColorBits = 4;
    else if (wColorBits <= 8)
        wColorBits = 8;
    else if (wColorBits <= 16)
        wColorBits = 16;
    else if (wColorBits <= 24)
        wColorBits = 24;
    else wColorBits = 32;


    PBITMAPINFO pBitmapInfo;
    pBitmapInfo = (PBITMAPINFO) _alloca(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1 << wColorBits));
    memset(pBitmapInfo, 0, sizeof(BITMAPINFOHEADER));

    pBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    pBitmapInfo->bmiHeader.biWidth = bmp.bmWidth;
    pBitmapInfo->bmiHeader.biHeight = bmp.bmHeight;
    pBitmapInfo->bmiHeader.biPlanes = bmp.bmPlanes;
    pBitmapInfo->bmiHeader.biBitCount = bmp.bmBitsPixel;

    if (wColorBits < 24)
        pBitmapInfo->bmiHeader.biClrUsed = (1 << wColorBits);

    pBitmapInfo->bmiHeader.biCompression = BI_RGB;

    pBitmapInfo->bmiHeader.biSizeImage = ((pBitmapInfo->bmiHeader.biWidth * wColorBits +31) & ~31) / 8 * pBitmapInfo->bmiHeader.biHeight;

    pBitmapInfo->bmiHeader.biClrImportant = 0;

    LPBYTE pBits = (LPBYTE) malloc(pBitmapInfo->bmiHeader.biSizeImage);

    if(!GetDIBits(
        memDC,
        bmpWin,
        0,
        pBitmapInfo->bmiHeader.biHeight,
        pBits,
        pBitmapInfo,
        DIB_RGB_COLORS))
    {
        AfxMessageBox("Error al crear el Bitmap");
        free(pBits);
        return;
    }

    BITMAPFILEHEADER fileHeader;
    fileHeader.bfType = 0x4d42;
    fileHeader.bfSize = (DWORD) sizeof(BITMAPFILEHEADER)
        + pBitmapInfo->bmiHeader.biSizeImage
        + pBitmapInfo->bmiHeader.biClrUsed * sizeof(RGBQUAD)
        + pBitmapInfo->bmiHeader.biSize;
    fileHeader.bfReserved1 = 0;
    fileHeader.bfReserved2 = 0;
    fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER)
        + pBitmapInfo->bmiHeader.biClrUsed * sizeof(RGBQUAD)
        + pBitmapInfo->bmiHeader.biSize;

    try
    {
        file.Write(
            (LPVOID) &fileHeader,
            sizeof(BITMAPFILEHEADER));

        file.Write(
            (LPVOID) pBitmapInfo,
            sizeof(BITMAPINFOHEADER) + pBitmapInfo->bmiHeader.biClrUsed * sizeof(RGBQUAD));

        file.Write(
            (LPVOID) pBits,
            (UINT) pBitmapInfo->bmiHeader.biSizeImage);

        file.Close();

    }

    catch(CFileException* e)
    {
        e->ReportError();
        e->Delete();
        file.SetLength(0);
    }

    free(pBits);
Posted
Comments
Sergey Alexandrovich Kryukov 2-Jul-14 10:57am    
It depends on what do you mean by "content". If this is just graphical content of the window, you can grab the part of the screen in the bounds of that window. Or its client area...
—SA
Rex Miao1014 2-Jul-14 21:36pm    
I used this method before, but don't think it is good enough for me, because when application is overlayed by others, it will retreive other's content.
Thanks anyway
Sergey Alexandrovich Kryukov 2-Jul-14 22:49pm    
Then explain what kind of content do you want to get and what's the problem.
—SA
Rage 2-Jul-14 12:16pm    
Are you trying to screenshot an application playing a movie ?

1 solution

If the program uses Direct X, the pixels might not be available through the GDI.

Some information on getting Direct 2D to play with GDI and GDI+:

http://msdn.microsoft.com/en-us/library/dd940320%28v=vs.85%29.aspx#gdi__interoperability[^]

http://msdn.microsoft.com/en-us/library/dd370971(v=VS.85).aspx
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900