c ++程序截取屏幕截图

时间:2014-07-27 20:23:55

标签: c++ screenshot printscreen

我正在制作一个程序,它将点击键盘的printscreen键。我正在使用的代码如下:

INPUT myInput;

myInput.type = INPUT_KEYBOARD;

KEYBDINPUT keyboardInput;
keyboardInput.wScan = 0;
keyboardInput.dwFlags = 0;
keyboardInput.time = 0;
keyboardInput.dwExtraInfo = 0;
keyboardInput.wVk = VK_SNAPSHOT; 
myInput.ki = keyboardInput;

SendInput(1, &myInput, sizeof(INPUT));//pressing the printscreen key

keyboardInput.dwFlags = KEYEVENTF_KEYUP;
myInput.ki = keyboardInput;

SendInput(1, &myInput, sizeof(INPUT));//releasing the printscreen key

由于某种原因,代码无法正常工作。如果我去绘画并试图从剪贴板中进行paist,那么它只会通过我在使用我的程序之前所做的任何打印屏幕。我的键盘也不需要我在打印屏幕上按“alt”以使其工作..

我曾尝试按下Alt键beeeforee按下打印屏幕键,以及释放Alt键关键字释放打印屏幕键,我得到的差异是当我试图在油漆上过去了,我在某种全黑屏幕上做了一个...这只是我做的一个测试,看看它是否有所作为,但我的实际键盘仅截取了打印屏幕按钮的截图。

关于我做错了什么的任何想法?

编辑: 只是为了让你们知道,该程序确实可以编译。我还添加了其他代码,将剪贴板文件保存到目录中,如果我手动点击打印屏幕按钮,我会正确保存文件...但是如果我继续循环这段代码并保存到目录,那么相同的图片手动获取的屏幕截图显示...这就是我确定打印屏幕按钮按下时的问题。

2 个答案:

答案 0 :(得分:1)

在Windows平台上: 您必须遵循一定的模拟按键序列。

以下代码是模拟keybd_event()键盘事件,并将捕获的屏幕放入剪贴板。

#include <iostream>
#include <windows.h>
using namespace std;



int main()
{
    keybd_event(VK_MENU, 0, 0, 0); //Alt Press
    keybd_event(VK_SNAPSHOT, 0, 0, 0); //PrntScrn Press


    keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_KEYUP, 0); //PrntScrn Release
    keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0); //Alt Release

return 0;
}

答案 1 :(得分:0)

这是用于在BMP中截屏并将其转换为JPG的代码:

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();
}