Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
93 views
in Technique[技术] by (71.8m points)

c++ - Troubles capturing screen with winapi

I've been trying to capture the screen of my display using c++ and winapi to later convert it to a DIB for modifications. So far I've came up with this, in accordance with every guide out there:

#include "targetver.h"
#include "windows.h"
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <chrono>

void mainloop()
{ 
    auto start = std::chrono::steady_clock::now();
    
    HDC hdcScreen = GetDC(NULL);
    if (!hdcScreen)
    {
        std::cout << "Couldn't get DC for screen
";
    }

    auto width = GetSystemMetrics(SM_CXSCREEN);
    auto height = GetSystemMetrics(SM_CYSCREEN);   

    HDC memDc = CreateCompatibleDC(hdcScreen);  
    if (!memDc)
    {
        std::cout << "Create compatible DC failed!
";
    }

    HBITMAP hScreenBmp = CreateCompatibleBitmap(memDc, width, height);      
    BITMAP bmpScreen;
    if (!hScreenBmp)
    {
        std::cout << "CreateCompatibleBitmap to screen failed
";
    }
    SelectObject(memDc, hScreenBmp);

    if (!BitBlt(memDc,
        0, 0,
        width, height,
        hdcScreen,
        0, 0,
        SRCCOPY))
    {
        std::cout << "BitBlt failed
";
    }

    GetObject(hScreenBmp, sizeof(BITMAP), &bmpScreen);

    BITMAPINFOHEADER   bi;

    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bmpScreen.bmWidth;
    bi.biHeight = bmpScreen.bmHeight;
    bi.biPlanes = 1;
    bi.biBitCount = 32;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;

    DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;
    HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);
    char* lpbitmap = (char*)GlobalLock(hDIB);

    GetDIBits(memDc, hScreenBmp, 0,
        (UINT)bmpScreen.bmHeight,
        lpbitmap,
        (BITMAPINFO*)&bi, DIB_RGB_COLORS);

    std::cout << "Lines: " << bi.biWidth << " x " << bi.biHeight << "px 
";
    char* currPixel = (char*)lpbitmap;
    for (auto j = 0; j < bi.biHeight; j++)
    {
        std::cout << "Line" << j << ":
";
        for (auto i = 0; i < bi.biWidth; i++)
        {
            std::cout << "(" << std::to_string(static_cast<unsigned char>(currPixel[0])) << "," << std::to_string(static_cast<unsigned char>(currPixel[1]))
                << "," << std::to_string(static_cast<unsigned char>(currPixel[2])) << ")";
            currPixel += 4;
        }
        std::cout << std::endl;
    }  
  
    GlobalUnlock(hDIB);
    GlobalFree(hDIB);
    DeleteDC(hdcScreen);
    DeleteDC(memDc);   

    auto end = std::chrono::steady_clock::now();
    std::cout << "Main loop completed in: " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms
";
}

int main()
{
    mainloop();
} 

(and also every other variation of the above I could think of). However, the loop at the ends tries to print the values of the pixels in the DIB - and, unfortunately, all come out zeros: "(0,0,0)...". Not sure what the problem may be here and I'd love some feedback that could shed some light on this. I should probably note that the screen has a resolution of 3820x2160 pixels so the memory allocation needed for the bitmap is rather large. Also, this is a terminal-type program and not a windows-one (maybe something is not properly configured/linked - dunno - just guessing). I also tried moving the BitBlt call to every possible spot but to no avail (not sure at which time it should be called for the desired effect). Thanks for the help!

question from:https://stackoverflow.com/questions/65874576/troubles-capturing-screen-with-winapi

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...