Skip to content

Instantly share code, notes, and snippets.

@daaximus
Last active May 3, 2024 03:31
Show Gist options
  • Save daaximus/a402fad67aca8339f7cc743cd55b7c27 to your computer and use it in GitHub Desktop.
Save daaximus/a402fad67aca8339f7cc743cd55b7c27 to your computer and use it in GitHub Desktop.
#include <windows.h>
#include <gdiplus.h>
#include <string>
#include <iostream>
#include <fstream>
using namespace Gdiplus;
#pragma comment (lib,"Gdiplus.lib")
int get_encoder_clsid( const WCHAR* format, CLSID* clsid )
{
UINT num_encoders = 0;
UINT size_encoders = 0;
ImageCodecInfo* codec_info = nullptr;
GetImageEncodersSize( &num_encoders, &size_encoders );
if ( size_encoders == 0 ) return -1;
codec_info = static_cast< ImageCodecInfo* >( malloc( size_encoders ) );
if ( codec_info == nullptr ) return -1;
GetImageEncoders( num_encoders, size_encoders, codec_info );
for ( UINT it = 0; it < num_encoders; ++it )
{
if ( wcscmp( codec_info[ it ].MimeType, format ) == 0 )
{
*clsid = codec_info[ it ].Clsid;
free( codec_info );
return it;
}
}
free( codec_info );
return -1;
}
void capture_screenshot( const std::wstring& filename, HWND hwnd )
{
GdiplusStartupInput gdipsi;
ULONG_PTR token;
GdiplusStartup( &token, &gdipsi, nullptr );
const HDC hdc_screen = GetDC( nullptr );
const HDC hdc_capture = CreateCompatibleDC( hdc_screen );
int left = GetSystemMetrics( SM_XVIRTUALSCREEN );
int top = GetSystemMetrics( SM_YVIRTUALSCREEN );
int width = GetSystemMetrics( SM_CXVIRTUALSCREEN );
int height = GetSystemMetrics( SM_CYVIRTUALSCREEN );
if ( hwnd != nullptr )
{
RECT window_rect;
GetWindowRect( hwnd, &window_rect );
left = window_rect.left;
top = window_rect.top;
width = window_rect.right - window_rect.left;
height = window_rect.bottom - window_rect.top;
}
const HBITMAP hbm = CreateCompatibleBitmap( hdc_screen, width, height );
SelectObject( hdc_capture, hbm );
BitBlt( hdc_capture, 0, 0, width, height, hdc_screen, left, top, SRCCOPY );
Bitmap* bitmap = Bitmap::FromHBITMAP( hbm, nullptr );
CLSID png_clsid;
get_encoder_clsid( L"image/png", &png_clsid );
bitmap->Save( filename.c_str(), &png_clsid, nullptr );
delete bitmap;
DeleteObject( hbm );
DeleteDC( hdc_capture );
ReleaseDC( nullptr, hdc_screen );
GdiplusShutdown( token );
}
HWND main_window = nullptr;
LRESULT CALLBACK window_proc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
switch ( message )
{
case WM_DESTROY:
PostQuitMessage( 0 );
return 0;
case WM_ACTIVATE:
if ( wparam == WA_INACTIVE )
{
ShowWindow( hwnd, SW_MINIMIZE );
return 0;
}
break;
case WM_KEYDOWN:
switch ( wparam )
{
case VK_TAB:
if ( ( GetKeyState( VK_MENU ) & 0x1 ) != 0 )
ShowWindow( hwnd, SW_MINIMIZE );
return 0;
case VK_LWIN:
case VK_RWIN:
ShowWindow( hwnd, SW_MINIMIZE );
return 0;
case VK_ESCAPE:
PostQuitMessage( 0 );
return 0;
default: break;
}
break;
default: break;
}
return DefWindowProc( hwnd, message, wparam, lparam );
}
void capture_gamers()
{
HWND backup_hwnd = main_window;
// gamer vision brrrrrrrr...
for ( auto n = 0; ; n++ )
{
if ( GetAsyncKeyState( VK_F1 ) & 0x1 )
{
if ( main_window )
main_window = nullptr;
else
main_window = backup_hwnd;
}
std::wstring filename = L"ss_" + std::to_wstring( n ) + L".png";
capture_screenshot( filename, main_window );
Sleep( 1000 );
}
}
// While window is active, screenshots capture the client window. If you alt-tab, it will not capture the window and results in
// a single null box. In this junk, if the window handle becomes invalid, it will screenshot the entire screen (press F1 and
// review the screenshots).
//
int WINAPI WinMain( HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmd_line, int cmd_show )
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof( WNDCLASSEX );
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = window_proc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = instance;
wcex.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
wcex.hbrBackground = HBRUSH( COLOR_WINDOW + 1 );
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"OhNoScreenshots";
wcex.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
RegisterClassEx( &wcex );
main_window = CreateWindowEx(
0,
L"OhNoScreenshots",
L"FairFight Never Did This! /s",
WS_POPUP | WS_VISIBLE,
0, 0,
GetSystemMetrics( SM_CXSCREEN ),
GetSystemMetrics( SM_CYSCREEN ),
nullptr, nullptr,
instance, nullptr );
ShowWindow( main_window, cmd_show );
UpdateWindow( main_window );
CreateThread( nullptr, 0, reinterpret_cast< LPTHREAD_START_ROUTINE >( capture_gamers ), nullptr, 0, nullptr );
MSG msg;
while ( GetMessage( &msg, nullptr, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return int( msg.wParam );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment