Загрузка данных


#NoEnv
#SingleInstance Force

F3::

; ============================================================
; НАСТРОЙКИ ОБЛАСТИ
; ============================================================

X := 0
Y := 0

Width := 500
Height := 500

FilePath := A_ScriptDir "\TEST_SCREEN.bmp"


; ============================================================
; ПОЛУЧАЕМ DC ЭКРАНА
; ============================================================

hdcScreen := DllCall("GetDC", "Ptr", 0, "Ptr")

if (!hdcScreen)
{
    MsgBox, 16, Ошибка, Не удалось получить DC экрана.
    return
}


; ============================================================
; СОЗДАЁМ MEMORY DC
; ============================================================

hdcMem := DllCall("gdi32\CreateCompatibleDC", "Ptr", hdcScreen, "Ptr")

if (!hdcMem)
{
    DllCall("ReleaseDC", "Ptr", 0, "Ptr", hdcScreen)

    MsgBox, 16, Ошибка, Не удалось создать Memory DC.
    return
}


; ============================================================
; СОЗДАЁМ BITMAP
; ============================================================

hBitmap := DllCall("gdi32\CreateCompatibleBitmap", "Ptr", hdcScreen, "Int", Width, "Int", Height, "Ptr")

if (!hBitmap)
{
    DllCall("gdi32\DeleteDC", "Ptr", hdcMem)
    DllCall("ReleaseDC", "Ptr", 0, "Ptr", hdcScreen)

    MsgBox, 16, Ошибка, Не удалось создать Bitmap.
    return
}


; ============================================================
; ПОМЕЩАЕМ BITMAP В MEMORY DC
; ============================================================

hOld := DllCall("gdi32\SelectObject", "Ptr", hdcMem, "Ptr", hBitmap, "Ptr")


; ============================================================
; ДЕЛАЕМ ЗАХВАТ ЭКРАНА
; ============================================================

Result := DllCall("gdi32\BitBlt", "Ptr", hdcMem, "Int", 0, "Int", 0, "Int", Width, "Int", Height, "Ptr", hdcScreen, "Int", X, "Int", Y, "UInt", 0x00CC0020)

if (!Result)
{
    ErrorCode := DllCall("GetLastError")

    DllCall("gdi32\SelectObject", "Ptr", hdcMem, "Ptr", hOld)
    DllCall("gdi32\DeleteObject", "Ptr", hBitmap)
    DllCall("gdi32\DeleteDC", "Ptr", hdcMem)
    DllCall("ReleaseDC", "Ptr", 0, "Ptr", hdcScreen)

    MsgBox, 16, Ошибка, BitBlt не смог сделать захват.`nКод Windows: %ErrorCode%
    return
}


; ============================================================
; ПОДГОТАВЛИВАЕМ BITMAPINFO
; ============================================================

VarSetCapacity(BitmapInfo, 40, 0)

NumPut(40, BitmapInfo, 0, "UInt")
NumPut(Width, BitmapInfo, 4, "Int")
NumPut(Height, BitmapInfo, 8, "Int")
NumPut(1, BitmapInfo, 12, "UShort")
NumPut(32, BitmapInfo, 14, "UShort")
NumPut(0, BitmapInfo, 16, "UInt")
NumPut(Width * Height * 4, BitmapInfo, 20, "UInt")


; ============================================================
; ВЫДЕЛЯЕМ ПАМЯТЬ ПОД ПИКСЕЛИ
; ============================================================

ImageSize := Width * Height * 4

VarSetCapacity(Pixels, ImageSize, 0)


; ============================================================
; ПОЛУЧАЕМ ПИКСЕЛИ ИЗ BITMAP
; ============================================================

Result := DllCall("gdi32\GetDIBits", "Ptr", hdcScreen, "Ptr", hBitmap, "UInt", 0, "UInt", Height, "Ptr", &Pixels, "Ptr", &BitmapInfo, "UInt", 0)

if (!Result)
{
    ErrorCode := DllCall("GetLastError")

    DllCall("gdi32\SelectObject", "Ptr", hdcMem, "Ptr", hOld)
    DllCall("gdi32\DeleteObject", "Ptr", hBitmap)
    DllCall("gdi32\DeleteDC", "Ptr", hdcMem)
    DllCall("ReleaseDC", "Ptr", 0, "Ptr", hdcScreen)

    MsgBox, 16, Ошибка, GetDIBits не смог получить пиксели.`nКод Windows: %ErrorCode%
    return
}


; ============================================================
; ОСВОБОЖДАЕМ WINDOWS OBJECTS
; ============================================================

DllCall("gdi32\SelectObject", "Ptr", hdcMem, "Ptr", hOld)
DllCall("gdi32\DeleteObject", "Ptr", hBitmap)
DllCall("gdi32\DeleteDC", "Ptr", hdcMem)
DllCall("ReleaseDC", "Ptr", 0, "Ptr", hdcScreen)


; ============================================================
; СОЗДАЁМ BMP FILE HEADER
; ============================================================

FileSize := 54 + ImageSize

VarSetCapacity(FileHeader, 14, 0)

NumPut(0x4D42, FileHeader, 0, "UShort")
NumPut(FileSize, FileHeader, 2, "UInt")
NumPut(0, FileHeader, 6, "UShort")
NumPut(0, FileHeader, 8, "UShort")
NumPut(54, FileHeader, 10, "UInt")


; ============================================================
; СОЗДАЁМ BMP-ФАЙЛ
; ============================================================

FileDelete, %FilePath%

File := FileOpen(FilePath, "w")

if (!IsObject(File))
{
    MsgBox, 16, Ошибка, Не удалось создать BMP-файл.
    return
}

File.RawWrite(FileHeader, 14)
File.RawWrite(BitmapInfo, 40)
File.RawWrite(Pixels, ImageSize)

File.Close()


; ============================================================
; ПРОВЕРЯЕМ ФАЙЛ
; ============================================================

if (!FileExist(FilePath))
{
    MsgBox, 16, Ошибка, BMP-файл не был создан.
    return
}


FileGetSize, FileSizeCheck, %FilePath%

if (FileSizeCheck <= 54)
{
    MsgBox, 16, Ошибка, BMP-файл создан, но в нём нет изображения.
    return
}


; ============================================================
; УСПЕХ
; ============================================================

MsgBox, 64, УСПЕХ!, Скриншот успешно сохранён!`n`nФайл:`n%FilePath%`n`nРазмер: %FileSizeCheck% байт

return