c++ Program to take a screenshot - c++

I am making a program that will click the printscreen key of the keyboard. The code I am using is the following:
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
for some reason the code doesn't work what so ever. If I go to paint and try to paist from clipboard, it will only past whatever printscreen I had done before I had used my program. Also my keyboard doesn't need me to press the "alt" with the print screen in order for it to work..
I had tryed to included the pressing of the Alt key beeeforee the pressing of the printscreen key, as well as the release of the Alt key afffftterr the releasing of the printscreen key, and the difference I got was that when I tried to past it on paint, I paist some kind of a full black screen... This was just a test I did to see if it makes a difference, but my actual keyboard takes screenshots with only the hit of the print screen button.
Any ideas on what I am doing wrong guys?
Edited:
just to let you guys know, the program does in fact compile. I have also added other code that saves the clipboard file to a directory, and I do save a file correctly if I manually hit the print screen button... but if I keep looping this code with the saving to a directory, the same picture of the manually obtained screenshot appears... so that is how I know for sure that there is a problem with the hitting of the printscreen button.

On the windows platform:
You have to follow a certain sequence of simulated key presses.
The code below is a simulates keybd_event() keyboard events and puts the captured screen into the clipboard.
#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;
}

That is code for taking a screenshot in BMP and to convert it to 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();
}

Related

C++ How Do I Simulate a MouseClick On a BackGround Process?

As The Title Says I want to make a code or a app that runs in the background which clicks repeatedly so far I was only able to make a click code which is
void Click() {
INPUT iNPUTh = { 0 };
iNPUTh.type = INPUT_MOUSE;
iNPUTh.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(1, &iNPUTh, sizeof(iNPUTh));
ZeroMemory(&iNPUTh, sizeof(iNPUTh));
iNPUTh.type = INPUT_MOUSE;
iNPUTh.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1, &iNPUTh, sizeof(iNPUTh));
}
int main() {
HWND hhProcess;
hhProcess = FindWindow(NULL, L"ARK: Survival Evolved");
if (hhProcess) {
AllocConsole();
cout << "Process Found!" << endl;
}
while (true) {
if (GetAsyncKeyState(VK_Numpad0) {
Click()
}
}
}
But my problem is that once I start to run it, it clicks on the surface what I want to happen is that it clicks on a background process
I have found myself an answer :) I tried testing some codes myself and tried to use Post Message
PostMessage(hhProcess, WM_LBUTTONDOWN, 0, 0);
Sleep(100);
PostMessage(hhProcess, WM_LBUTTONUP, 0, 0);
everytime i press numpad 6 while the window is not active it punches i thank you guys for helping me find ways even tho sometimes i dont understand it :)
Now My Problem is How do i make it click on a certain coords x,y in the background

How to make a screenshot with a C++ application?[•RESOLVED•]

I want to make a program that make a screenshot and save it in a bitmap (bmp file).
I Have this code:
#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;
}
First thing I want to say is that i'm approaching windows graphics in C++ for the first time, that's my first program that make screenshots
This program doesn't give me errors but, during the debug, i gives me an error in the "atlimage.h" file,
error:
>Expression: hBitmap != 0
How can I fix that? I think that the real problem is when it has to save the screenshot in the file.
(I think that because while writing this question on stackoverflow I accidentally pressed "Ctrl + V" and stackoverflow detected an image...The program basically do what it has to do but not completely because it doesn't save screenshot on a file, it saves the screenshot in the clipboard :/ )
EDIT:
I tried with this other code:
#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;
}
And it seems it works, it saves the file and doesn't give any error.
The problem is that the out.jpg file is completely black :/. I think there is an error in the File save instructions. Anyone can help me?
EDIT 2:
I have resolved the problem :D
Now I have this code:
#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;
}
I just added the last part with the cout and upped the stop time on line 21 from 100ms to 1000ms.
Enjoy my experience with this program :)

ShowCursor(FALSE) does not hide cursor on console application

I know this may sound to be a duplicate question but trust me it's not.
I have referred this question, but was not of much help as I am trying with a console application and the answerer himself tells he does not know the reason why ShowCursor(FALSE) does not work for console applications.
This thread did not help me either.
Here are the things I tried:
Using ShowCursor():
while(ShowCursor(false)>=0); //did not work
I first suspected that it was because of this statement in the msdn :
When Windows starts up, it checks if you have a mouse. If so, then the cursor show count is initialized to zero; otherwise, it is initialized to negative one.
I thought maybe in the latest windows, it doesn't recognize the connected mouse or the trackpad as an installed mouse and maybe that's why it didn't work. The following code shows it is not the case:
void UsingShowCursor()
{
CURSORINFO info;
info.cbSize = sizeof(CURSORINFO);
cout << ShowCursor(FALSE);
cout << ShowCursor(FALSE);
cout << ShowCursor(FALSE);
GetCursorInfo( &info ); //info.flags is CURSOR_SHOWING
}
Because I get -1, -2, -3. That means the initial show cursor count is obviously 0 and it does identify the installed mouse.
And another thing to note is that the GetCursorInfo() also tells that the cursor is showing.
Using SetCursor()
void UsingSetCursor()
{
HCURSOR prev = SetCursor(NULL);
int i = 0;
while(i++<10)
{
cout<<i<<endl;
Sleep(1000);
}
if( SetCursor(prev) == NULL ) //check if the previos cursor was NULL
cout<<"cursor was hidden and shown after 10 secs\n";
}
Doesn't work either.
This also did not work:
SetCursor(LoadCursor(NULL, NULL));
Edit:
Using LoadImage
Did not work either.
void UsingLoadImage()
{
// Save a copy of the default cursor
HANDLE arrowHandle = LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_SHARED);
HCURSOR hcArrow = CopyCursor(arrowHandle);
HCURSOR noCursorHandle = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR,1,1,LR_SHARED); //a single pixel thick cursor so that it wont be visible
HCURSOR noCursor = CopyCursor(noCursorHandle);
SetSystemCursor(noCursor, OCR_NORMAL);
int i =0 ;
while(i++<10)
{
cout<<i<<endl;
Sleep(1000);
}
//revert to previous cursor
SetSystemCursor(hcArrow, OCR_NORMAL);
DestroyCursor(hcArrow);
}
What can be the mistake? How can we hide the mouse for a console application?
You can use LoadImage() to achieve what you want. Here is the modified working version of the function UsingLoadImage() you quoted in the question. You have to include a cursor resource file to your visual studio project. Download the cursor from here or create your own.
Resource Files->Add->Existng Item and browse to the nocursor.cur file.
void UsingLoadImage()
{
// Save a copy of the default cursor
HANDLE arrowHandle = LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_SHARED);
HCURSOR hcArrow = CopyCursor(arrowHandle);
// Set the cursor to a transparent one to emulate no cursor
HANDLE noCursorHandle = LoadImage(GetModuleHandle(NULL), L"nocursor.cur", IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE); //worked
//HANDLE noCursorHandle = LoadCursorFromFile(L"nocursor.cur"); //this also worked
HCURSOR noCursor = CopyCursor(noCursorHandle);
SetSystemCursor(noCursor, OCR_NORMAL);
int i =0 ;
while(i++<10)
{
cout<<i<<endl;
Sleep(1000);
}
SetSystemCursor(hcArrow, OCR_NORMAL);
DestroyCursor(hcArrow);
}
This would replace the normal arrow cursor with the transparent one. If you want to hide all the other cursor like the text, loading, hand cursors etc you have to hide them individually. If you don't want that to be the case, then you should opt out of the console application as many commenters have pointed out.
Hope this helps.

In Windows, Does SetCurrentConsoleFontEx change console's font size?

Other guys recommend the SetCurrentConsoleFontEx function but I don't know how to apply it to my project.
I want to change the font size of only some texts, not all texts.
Does SetCurrentConsoleFontEx() change the console's font size?
Or are there other ways to change it?
If there is, please show me the console function and a simple example.
Here is an example of using SetCurrentConsoleFontEx to change the console's font size. This affects the entire console window -- so like Joachim Pileborg already said, if you want mixed font sizes in a single console window, this won't help you.
#define _WIN32_WINNT 0x500
#include <Windows.h>
// PrintChars sends ASCII characters to console output
// for demonstration purposes.
// depends only on Win32 API
static void PrintChars() {
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD num_written;
static const char* cr_lf = "\r\n";
for(char c=' '; c<'\x7f'; ++c) {
WriteFile(hStdout, &c, 1, &num_written, NULL);
if(c % 16 == 15) WriteFile(hStdout, cr_lf, 2, &num_written, NULL);
}
WriteFile(hStdout, cr_lf, 2, &num_written, NULL);
}
// WaitEnter blocks execution until the user
// presses the enter key.
// depends only on Win32 API
static void WaitEnter() {
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
char buffer;
DWORD num_read;
do {
num_read = 0;
ReadFile(hStdin, &buffer, 1, &num_read, NULL);
} while(num_read && buffer != '\n');
}
int main() {
// Display some example characters
PrintChars();
// Wait for the user to see how the current font looks
WaitEnter();
// Get a handle to the current console screen buffer
HANDLE hcsb = CreateFileA("CONOUT$", GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
CONSOLE_FONT_INFOEX cfi = {sizeof(cfi)};
// Populate cfi with the screen buffer's current font info
GetCurrentConsoleFontEx(hcsb, FALSE, &cfi);
// Modify the font size in cfi
cfi.dwFontSize.X *= 2;
cfi.dwFontSize.Y *= 2;
// Use cfi to set the screen buffer's new font
SetCurrentConsoleFontEx(hcsb, FALSE, &cfi);
// Wait for the user to see the difference before exiting
WaitEnter();
CloseHandle(hcsb);
}

Beginner level code required to display a frame using vfw?

I want to be able to display a captured frame from my webcam using the vfw.h library. I have code which captures a single frame and saves it to a Bitmap file. However, I do not know how to then display this Bitmap file within a window. I only know how to display the live video feed within a window. Apologies in advance for the likely obviousness of this question but I have very little experience in this type of programming. Can anyone advise me on how to display the captured frame in another window, for further manipulation, i.e. examples of how to use the relevant macros? I am using C++ in Visual Studio.
ShowWindow(camhwnd,SW_SHOW);
SendMessage(camhwnd,WM_CAP_DRIVER_CONNECT,0,0);
SendMessage(camhwnd, WM_CAP_SET_SCALE, true , 0);
SendMessage(camhwnd, WM_CAP_SET_PREVIEWRATE, 66, 0);
SendMessage(camhwnd, WM_CAP_SET_PREVIEW, true , 0);
SendMessage(camhwnd, WM_CAP_GRAB_FRAME, 0, 0);
//Grab a Frame
SendMessage(camhwnd, WM_CAP_GRAB_FRAME, 0, 0);
//Copy the frame we have just grabbed to the clipboard
SendMessage(camhwnd, WM_CAP_EDIT_COPY,0,0);
//Copy the clipboard image data to a HBITMAP object called hbm
hdc = BeginPaint(camhwnd, &ps);
hdcMem = CreateCompatibleDC(hdc);
if (hdcMem != NULL)
{
if (OpenClipboard(camhwnd))
{
hbm = (HBITMAP) GetClipboardData(CF_BITMAP);
SelectObject(hdcMem, hbm);
GetClientRect(camhwnd, &rc);
CloseClipboard();
}
}
//Save hbm to a .bmp file called Frame.bmp
PBITMAPINFO pbi = CreateBitmapInfoStruct(hwnd, hbm);
CreateBMPFile(hwnd, "Frame.bmp", pbi, hbm, hdcMem);
SendMessage(camhwnd,WM_CAP_DRIVER_CONNECT,0,0);
SendMessage(camhwnd, WM_CAP_SET_SCALE, true , 0);
SendMessage(camhwnd, WM_CAP_SET_PREVIEWRATE, 66, 0);
SendMessage(camhwnd, WM_CAP_SET_PREVIEW, true , 0);
break;
}
}
break;
}
To display a bitmap, you first create a "handled" bitmap object, which results in your holding HBITMAP value which APIs accept for further manipulations, and then you actually display it.
The first step is achieved using CreateBitmap and friends.
On the second, see Displaying HBITMAP.