The result is significantly smaller in size without any quality distortion.
A screenshot is captured automatically every 5 seconds and the image is overwritten.
You would have to stop the process manually through Task Manager to end it.
This application also uses minimal memory usage.
// screenshot.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <fstream>
#include <GdiPlus.h>
#include <stdio.h>
#pragma comment( lib, "gdiplus" )
using namespace std;
using namespace Gdiplus;
//This is for debugging purposes
ofstream outputFile;
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
using namespace Gdiplus;
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if(size == 0)
return -1; // Failure
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1; // Failure
GetImageEncoders(num, size, pImageCodecInfo);
for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}
free(pImageCodecInfo);
return 0;
}
void BMPtoPNG(const char* filenamebmp,const wchar_t* filenamepng)
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
HBITMAP hbm = (HBITMAP)LoadImage( NULL, filenamebmp, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
if( hbm )
{
Bitmap *pBitmap = Bitmap::FromHBITMAP( hbm, (HPALETTE)GetStockObject(DEFAULT_PALETTE) );
if( pBitmap )
{
CLSID clsidEncoder;
if( GetEncoderClsid(L"image/png", &clsidEncoder) )
{
pBitmap->Save(filenamepng, &clsidEncoder, NULL);
}
delete pBitmap;
}
DeleteObject(hbm);
}
Gdiplus::GdiplusShutdown(gdiplusToken);
}
void gdiscreen()
{
using namespace Gdiplus;
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
{
HDC scrdc, memdc;
HBITMAP membit;
scrdc = ::GetDC(0);
int Height = GetSystemMetrics(SM_CYSCREEN);
int Width = GetSystemMetrics(SM_CXSCREEN);
memdc = CreateCompatibleDC(scrdc);
membit = CreateCompatibleBitmap(scrdc, Width, Height);
HDESK hDesktop = OpenInputDesktop( 0, FALSE, GENERIC_ALL );
HBITMAP hOldBitmap =(HBITMAP)
SelectObject(memdc, membit);
if(hOldBitmap == NULL)
{
if((GetLastError() != 183) && (GetLastError() != 0))
{
//If desktop is locked, it throws a false positive error 183 for some reason
if(SwitchDesktop(OpenDesktop("Default", 0, false, DESKTOP_SWITCHDESKTOP)) != 0) //Make sure the desktop isn't locked
{
outputFile.open("Screenshot-log.txt", ios::out | ios::app | ios::binary);
outputFile << "hOldBitmap Failed with error: " << GetLastError() << "\r\n" << endl;
outputFile.close();
}
CloseDesktop( hDesktop );
}
}
if(!BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY))
{
if((GetLastError() != 183) && (GetLastError() != 0))
{
//If desktop is locked, it throws a false positive error 183 for some reason
if(SwitchDesktop(OpenDesktop("Default", 0, false, DESKTOP_SWITCHDESKTOP)) != 0) //Make sure the desktop isn't locked
{
outputFile.open("Screenshot-log.txt", ios::out | ios::app | ios::binary);
outputFile << "BitBlt Failed with error: " << GetLastError() << "\r\n" << endl;
outputFile.close();
}
CloseDesktop( hDesktop );
}
}
Bitmap bitmap(membit, NULL);
CLSID clsid;
if(!GetEncoderClsid(L"image/bmp", &clsid))
{
if((GetLastError() != 183) && (GetLastError() != 0))
{
//If desktop is locked, it throws a false positive error 183 for some reason
if(SwitchDesktop(OpenDesktop("Default", 0, false, DESKTOP_SWITCHDESKTOP)) != 0) //Make sure the desktop isn't locked
{
outputFile.open("Screenshot-log.txt", ios::out | ios::app | ios::binary);
outputFile << "GetEncoderClsid Failed with error: " << GetLastError() << "\r\n" << endl;
outputFile.close();
}
CloseDesktop( hDesktop );
}
}
if(!bitmap.Save(L"ScreenShot.bmp", &clsid))
{
if((GetLastError() != 183) && (GetLastError() != 0))
{
//If desktop is locked, it throws a false positive error 183 for some reason
if(SwitchDesktop(OpenDesktop("Default", 0, false, DESKTOP_SWITCHDESKTOP)) != 0) //Make sure the desktop isn't locked
{
outputFile.open("Screenshot-log.txt", ios::out | ios::app | ios::binary);
outputFile << "bitmap.Save Failed with error: " << GetLastError() << "\r\n" << endl;
outputFile.close();
}
CloseDesktop( hDesktop );
}
}
if(!SelectObject(memdc, hOldBitmap))
{
if((GetLastError() != 183) && (GetLastError() != 0))
{
//If desktop is locked, it throws a false positive error 183 for some reason
if(SwitchDesktop(OpenDesktop("Default", 0, false, DESKTOP_SWITCHDESKTOP)) != 0) //Make sure the desktop isn't locked
{
outputFile.open("Screenshot-log.txt", ios::out | ios::app | ios::binary);
outputFile << "SelectObject Failed with error: " << GetLastError() << "\r\n" << endl;
outputFile.close();
}
CloseDesktop( hDesktop );
}
}
DeleteObject(membit);
DeleteObject(memdc);
::ReleaseDC(0,scrdc);
}
GdiplusShutdown(gdiplusToken);
}
bool isRunning()
{
//This checks if the process is already running so you don't have multiple instances running.
HANDLE handle = CreateMutex(NULL, true, "screenshot");
if(GetLastError() != ERROR_SUCCESS)
{
MessageBox(0, "Process is already running", "Warning", MB_ICONWARNING);
return false;
}
else
return true;
}
int main()
{
//Don't show the console window
FreeConsole();
//Check if this process is running
if(isRunning() == false)
return 0;
//Run this loop until we explicitly close the process
while(1)
{
Sleep(5000);
//Take a screenshot of our screen
gdiscreen();
//Convert BMP to PNG
BMPtoPNG("ScreenShot.bmp",L"ScreenShot.png");
//Delete BMP
DeleteFile("Screenshot.bmp");
}
return 0;
}