首页 > 解决方案 > 如何使用 C++ 应用程序制作屏幕截图?[•已解决•]

问题描述

我想制作一个制作屏幕截图并将其保存在位图(bmp 文件)中的程序。我有这个代码:

#include <atlsafe.h>
#include <iostream>
#include <windows.h>
#include <vector>
#include <fstream>
#include <atlimage.h>

using namespace std;


void TakeScreenShot(const std::string& path)
{
    //setting to the screen shot
    keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY, 0);
    keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);

    //handler of the bitmap that save the screen shot
    HBITMAP hBitmap;

    //I have to give for it time to make it work
    Sleep(100);

    //take the screen shot
    OpenClipboard(NULL);

    //save the screen shot in the bitmap handler 
    hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);

    //relese the screen shot
    CloseClipboard();

    std::vector<BYTE> buf;
    IStream* stream = NULL;
    HRESULT hr = CreateStreamOnHGlobal(0, TRUE, &stream);
    CImage image;
    ULARGE_INTEGER liSize;

    // screenshot to jpg and save to stream
    image.Attach(hBitmap);
    image.Save(stream, Gdiplus::ImageFormatJPEG);
    IStream_Size(stream, &liSize);
    DWORD len = liSize.LowPart;
    IStream_Reset(stream);
    buf.resize(len);
    IStream_Read(stream, &buf[0], len);
    stream->Release();

    // put the imapge in the file
    std::fstream fi;
    fi.open(path, std::fstream::binary | std::fstream::out);
    fi.write(reinterpret_cast<const char*>(&buf[0]), buf.size() * sizeof(BYTE));
    fi.close();
}
int main()
{
    string path = "C:\\";

    TakeScreenShot(path);
    return 0;
}

我想说的第一件事是我第一次在 C++ 中处理 Windows 图形,这是我第一个制作屏幕截图的程序

该程序没有给我错误,但是在调试期间,我在"atlimage.h"文件中给了我一个错误,

错误:

>Expression: hBitmap != 0

我该如何解决?我认为真正的问题是它必须将屏幕截图保存在文件中。(我认为因为在stackoverflow上写这个问题时我不小心按下了“Ctrl + V”并且stackoverflow检测到了一个图像......该程序基本上做了它必须做的事情但不是完全因为它没有将屏幕截图保存在文件中,它将屏幕截图保存在剪贴板中:/)

编辑: 我尝试使用其他代码:

#include <atlsafe.h>
#include <iostream>
#include <windows.h>
#include <vector>
#include <fstream>
#include <atlimage.h>
#include <string>
using namespace std;


void TakeScreenShot(const std::string& path, POINT a, POINT b)
{
    //setting to the screen shot
    keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY, 0);
    keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
    HDC     hScreen = GetDC(NULL);

    //handler of the bitmap that save the screen shot
    HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, abs(b.x - a.x), abs(b.y - a.y));;

    //I have to give for it time to make it work
    Sleep(100);

    //take the screen shot
    OpenClipboard(NULL);
    EmptyClipboard();

    //save the screen shot in the bitmap handler 
     
    SetClipboardData(CF_BITMAP, hBitmap);
    
    //relese the screen shot
    CloseClipboard();

    std::vector<BYTE> buf;
    IStream* stream = NULL;
    HRESULT hr = CreateStreamOnHGlobal(0, TRUE, &stream);
    CImage image;
    ULARGE_INTEGER liSize;

    // screenshot to jpg and save to stream
    image.Attach(hBitmap);
    image.Save(stream, Gdiplus::ImageFormatJPEG);
    IStream_Size(stream, &liSize);
    DWORD len = liSize.LowPart;
    IStream_Reset(stream);
    buf.resize(len);
    IStream_Read(stream, &buf[0], len);
    stream->Release();

    // put the imapge in the file
    std::fstream fi;
    fi.open(path, std::fstream::binary | std::fstream::out);
    fi.write(reinterpret_cast<const char*>(&buf[0]), buf.size() * sizeof(BYTE));
    fi.close();
}
int main()
{
    string path = "out.jpg";
    POINT a, b;
    a.x = 0;
    a.y = 0;

    b.x = 800;
    b.y = 800;
    TakeScreenShot(path,a,b);
    return 0;
}

它似乎有效,它保存了文件并且没有给出任何错误。问题是 out.jpg 文件完全是黑色的:/。我认为文件保存说明中有错误。任何人都可以帮助我吗?

编辑 2: 我已经解决了问题:D 现在我有这个代码:

#include <atlsafe.h>
#include <iostream>
#include <windows.h>
#include <vector>
#include <fstream>
#include <atlimage.h>

using namespace std;


void TakeScreenShot(const std::string& path)
{
    //setting to the screen shot
    keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY, 0);
    keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);

    //handler of the bitmap that save the screen shot
    HBITMAP hBitmap;

    //I have to give for it time to make it work in pratica guarda
    Sleep(1000); //Modified

    //take the screen shot
    OpenClipboard(NULL);

    //save the screen shot in the bitmap handler
    hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);

    //relese the screen shot
    CloseClipboard();

    std::vector<BYTE> buf;
    IStream* stream = NULL;
    HRESULT hr = CreateStreamOnHGlobal(0, TRUE, &stream);
    CImage image;
    ULARGE_INTEGER liSize;

    // screenshot to jpg and save to stream
    image.Attach(hBitmap);
    image.Save(stream, Gdiplus::ImageFormatJPEG);
    IStream_Size(stream, &liSize);
    DWORD len = liSize.LowPart;
    IStream_Reset(stream);
    buf.resize(len);
    IStream_Read(stream, &buf[0], len);
    stream->Release();

    // put the imapge in the file
    std::fstream fi;
    fi.open(path, std::fstream::binary | std::fstream::out);
    fi.write(reinterpret_cast<const char*>(&buf[0]), buf.size() * sizeof(BYTE));
    fi.close();
}
int main()
{
    string path = "sus.jpg";


    TakeScreenShot(path);
    cout << "Calling TakeScreenShot function..." << endl; //added
    Sleep(3000); //added
    return 0;
}

我刚刚添加了 cout 的最后一部分,并将第 21 行的停止时间从 100 毫秒增加到 1000 毫秒。

享受我对这个程序的体验:)

标签: c++imagescreenshot

解决方案


推荐阅读