我正在编写一个程序,该程序将单击键盘的打印屏幕键。我使用的代码如下:
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
由于某些原因,代码无法工作。如果我去画画,并尝试从剪贴板上画画,它只会经过我在使用我的程序之前所做的任何打印屏幕。此外,我的键盘不需要我在打印屏幕上按"alt"键才能工作。
我试着在按下截屏键之前按下Alt键,以及在按下截屏键之后释放Alt键,我得到的不同之处在于,当我试图在绘画上超越它时,我画出了一个完整的黑屏……这只是我做的一个测试,看看它是否有不同,但我的实际键盘只需要点击打印屏幕按钮就可以截取屏幕截图。
有什么想法我做错了吗?
编辑:只是让你们知道,这个程序实际上是可以编译的。我还添加了其他代码,将剪贴板文件保存到一个目录中,如果我手动点击打印屏幕按钮,我确实可以正确保存文件…但如果我一直循环这段代码保存到一个目录,手动获取的屏幕截图的相同图片出现…这就是为什么我知道有一个问题与点击打印屏幕按钮
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;
}
这是用于在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();
}