Полезные сниппеты и функции

Орк

Известный
302
249
Описание: Скриншот экрана, который сохраняется в буфер обмена, типа Print Screen. Не знаю зачем, но пусть будет.
Пример использования:
Lua:
screenshotToClipboard()
Код:
Lua:
local ffi = require("ffi")

ffi.cdef[[
    typedef void* HANDLE;
    typedef void* HDC;
    typedef void* HBITMAP;
    typedef const char* LPCSTR;
    typedef unsigned int UINT;
    typedef int BOOL;
    typedef unsigned long DWORD;

    HDC GetDC(void* hWnd);
    int GetSystemMetrics(int nIndex);
    HDC CreateCompatibleDC(HDC hdc);
    HBITMAP CreateCompatibleBitmap(HDC hdc, int cx, int cy);
    HBITMAP SelectObject(HDC hdc, HBITMAP h);
    BOOL BitBlt(HDC hdcDest, int xDest, int yDest, int w, int h, HDC hdcSrc, int xSrc, int ySrc, DWORD rop);
    BOOL DeleteDC(HDC hdc);
    BOOL DeleteObject(HBITMAP hObject);

    BOOL OpenClipboard(void* hWndNewOwner);
    BOOL EmptyClipboard();
    BOOL CloseClipboard();
    HANDLE SetClipboardData(UINT uFormat, HANDLE hMem);

    HANDLE GlobalAlloc(UINT uFlags, size_t dwBytes);
    HANDLE GlobalLock(HANDLE hMem);
    BOOL GlobalUnlock(HANDLE hMem);
    BOOL IsClipboardFormatAvailable(UINT format);
    
    BOOL OpenClipboard(void*);
    BOOL CloseClipboard();
    enum { SM_CXSCREEN = 0, SM_CYSCREEN = 1 };
    enum { SRCCOPY = 0x00CC0020 };
    enum { CF_BITMAP = 2 };
]]

local user32 = ffi.load("user32")
local gdi32 = ffi.load("gdi32")
local kernel32 = ffi.load("kernel32")

function screenshotToClipboard()
    local width = user32.GetSystemMetrics(0)
    local height = user32.GetSystemMetrics(1)

    local hdcScreen = user32.GetDC(nil)
    local hdcMem = gdi32.CreateCompatibleDC(hdcScreen)
    local hBitmap = gdi32.CreateCompatibleBitmap(hdcScreen, width, height)
    gdi32.SelectObject(hdcMem, hBitmap)
    gdi32.BitBlt(hdcMem, 0, 0, width, height, hdcScreen, 0, 0, ffi.C.SRCCOPY)

    if user32.OpenClipboard(nil) ~= 0 then
        user32.EmptyClipboard()
        user32.SetClipboardData(ffi.C.CF_BITMAP, hBitmap)
        user32.CloseClipboard()
        print("Скриншот скопирован в буфер обмена.")
    else
        print("Не удалось открыть буфер обмена.")
    end

    -- очистка
    gdi32.DeleteDC(hdcMem)
    -- hBitmap не удаляем, т.к. он теперь в буфере обмена
end