#include <Windows.h> 
#include <iostream> 
#include <string> 
#include <memory> 
 
class ScopedDeviceContext { 
public: 
    ScopedDeviceContext(HDC hdc) : hdc_(hdc) {} 
 
    ~ScopedDeviceContext() { 
        if (hdc_) { 
            ReleaseDC(NULL, hdc_); 
        } 
    } 
 
    HDC Get() const { return hdc_; } 
 
private: 
    HDC hdc_; 
 
    // Disable copy and assignment to prevent resource leaks 
    ScopedDeviceContext(const ScopedDeviceContext&); 
    ScopedDeviceContext& operator=(const ScopedDeviceContext&); 
}; 
 
class ScopedCompatibleDC { 
public: 
    ScopedCompatibleDC(HDC hdc) : hdc_(hdc), compatible_dc_(CreateCompatibleDC(hdc)) {} 
 
    ~ScopedCompatibleDC() { 
        if (compatible_dc_) { 
            DeleteDC(compatible_dc_); 
        } 
    } 
 
    HDC Get() const { return compatible_dc_; } 
 
private: 
    HDC hdc_; 
    HDC compatible_dc_; 
 
    // Disable copy and assignment to prevent resource leaks 
    ScopedCompatibleDC(const ScopedCompatibleDC&); 
    ScopedCompatibleDC& operator=(const ScopedCompatibleDC&); 
}; 
 
class ScopedBitmap { 
public: 
    ScopedBitmap(HBITMAP bitmap) : bitmap_(bitmap) {} 
 
    ~ScopedBitmap() { 
        if (bitmap_) { 
            DeleteObject(bitmap_); 
        } 
    } 
 
    HBITMAP Get() const { return bitmap_; } 
 
private: 
    HBITMAP bitmap_; 
 
    // Disable copy and assignment to prevent resource leaks 
    ScopedBitmap(const ScopedBitmap&); 
    ScopedBitmap& operator=(const ScopedBitmap&); 
}; 
 
bool CaptureScreenshot(int monitorIndex, const std::string& outputPath) { 
    HMONITOR monitors[16]; 
    int monitorCount = 0; 
    EnumDisplayMonitors(NULL, NULL, [](HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) -> BOOL { 
        HMONITOR* monitors = reinterpret_cast<HMONITOR*>(dwData); 
        monitors[monitorCount++] = hMonitor; 
        return TRUE; 
    }, reinterpret_cast<LPARAM>(monitors)); 
 
    if (monitorIndex >= monitorCount || monitorIndex < 0) { 
        std::cerr << "Invalid monitor index." << std::endl; 
        return false; 
    } 
 
    HMONITOR hMonitor = monitors[monitorIndex]; 
    MONITORINFOEX monitorInfo; 
    monitorInfo.cbSize = sizeof(MONITORINFOEX); 
    GetMonitorInfo(hMonitor, &monitorInfo); 
 
    int width = monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left; 
    int height = monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top; 
 
    HDC hScreenDC = GetDC(NULL); 
 
    ScopedCompatibleDC compatibleDC(hScreenDC); 
    ScopedBitmap bitmap(CreateCompatibleBitmap(hScreenDC, width, height)); 
    SelectObject(compatibleDC.Get(), bitmap.Get()); 
 
    BitBlt(compatibleDC.Get(), 0, 0, width, height, hScreenDC, monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, SRCCOPY); 
 
    BITMAPINFOHEADER bi; 
    bi.biSize = sizeof(BITMAPINFOHEADER); 
    bi.biWidth = width; 
    bi.biHeight = -height; 
    bi.biPlanes = 1; 
    bi.biBitCount = 24; 
    bi.biCompression = BI_RGB; 
    bi.biSizeImage = 0; 
    bi.biXPelsPerMeter = 0; 
    bi.biYPelsPerMeter = 0; 
    bi.biClrUsed = 0; 
    bi.biClrImportant = 0; 
 
    std::wstring wideOutputPath(outputPath.begin(), outputPath.end()); 
    const wchar_t* filename = wideOutputPath.c_str(); 
 
    FILE* file; 
    errno_t err = _wfopen_s(&file, filename, L"wb"); 
    if (err != 0) { 
        std::cerr << "Failed to open file for writing." << std::endl; 
        return false; 
    } 
 
    BITMAPFILEHEADER bmfh; 
    int size = ((width * bi.biBitCount + 31) / 32) * 4 * height; 
    bmfh.bfType = 0x4D42; 
    bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + size; 
    bmfh.bfReserved1 = 0; 
    bmfh.bfReserved2 = 0; 
    bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); 
 
    fwrite(&bmfh, sizeof(BITMAPFILEHEADER), 1, file); 
    fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, file); 
    fwrite(GetPixelData(bitmap.Get()), size, 1, file); 
    fclose(file); 
 
    std::cout << "Screenshot saved to " << outputPath << std::endl; 
 
    return true; 
} 
 
int main() { 
    int monitorIndex = 0; // Change this to the