Skip to content

Instantly share code, notes, and snippets.

@CarsonSlovoka
Created June 19, 2024 06:14
Show Gist options
  • Save CarsonSlovoka/1f983cc040ae11eedfe3abf61307521a to your computer and use it in GitHub Desktop.
Save CarsonSlovoka/1f983cc040ae11eedfe3abf61307521a to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"syscall"
"unsafe"
)
var (
user32 = syscall.NewLazyDLL("user32.dll")
gdi32 = syscall.NewLazyDLL("gdi32.dll")
kernel32 = syscall.NewLazyDLL("kernel32.dll")
openClipboard = user32.NewProc("OpenClipboard")
closeClipboard = user32.NewProc("CloseClipboard")
emptyClipboard = user32.NewProc("EmptyClipboard")
setClipboardData = user32.NewProc("SetClipboardData")
getDC = user32.NewProc("GetDC")
releaseDC = user32.NewProc("ReleaseDC")
createCompatibleDC = gdi32.NewProc("CreateCompatibleDC")
createCompatibleBitmap = gdi32.NewProc("CreateCompatibleBitmap")
selectObject = gdi32.NewProc("SelectObject")
bitBlt = gdi32.NewProc("BitBlt")
deleteObject = gdi32.NewProc("DeleteObject")
getDIBits = gdi32.NewProc("GetDIBits")
globalAlloc = kernel32.NewProc("GlobalAlloc")
globalLock = kernel32.NewProc("GlobalLock")
globalUnlock = kernel32.NewProc("GlobalUnlock")
)
const (
SRCCOPY = 0x00CC0020
CF_DIB = 8
GMEM_MOVEABLE = 0x0002
)
type BITMAPINFOHEADER struct {
BiSize uint32
BiWidth int32
BiHeight int32
BiPlanes uint16
BiBitCount uint16
BiCompression uint32
BiSizeImage uint32
BiXPelsPerMeter int32
BiYPelsPerMeter int32
BiClrUsed uint32
BiClrImportant uint32
}
func main() {
hwnd := uintptr(0)
hdc, _, _ := getDC.Call(hwnd)
defer releaseDC.Call(hwnd, hdc)
memDC, _, _ := createCompatibleDC.Call(hdc)
defer deleteObject.Call(memDC)
screenWidth := 1920
screenHeight := 1080
hBitmap, _, _ := createCompatibleBitmap.Call(hdc, uintptr(screenWidth), uintptr(screenHeight))
defer deleteObject.Call(hBitmap)
oldBitmap, _, _ := selectObject.Call(memDC, hBitmap)
defer selectObject.Call(memDC, oldBitmap)
bitBlt.Call(memDC, 0, 0, uintptr(screenWidth), uintptr(screenHeight), hdc, 0, 0, SRCCOPY)
var bi BITMAPINFOHEADER
bi.BiSize = uint32(unsafe.Sizeof(bi))
bi.BiWidth = int32(screenWidth)
bi.BiHeight = int32(-screenHeight) // top-down DIB
bi.BiPlanes = 1
bi.BiBitCount = 24
bi.BiCompression = 0
hDIB, _, _ := globalAlloc.Call(GMEM_MOVEABLE, uintptr((screenWidth*screenHeight*3)+int(unsafe.Sizeof(bi))))
lpDIB, _, _ := globalLock.Call(hDIB)
defer globalUnlock.Call(hDIB)
// 取點集的資料,從lpDIB+unsafe.Sizeof(bi)的位置開始寫起
getDIBits.Call(hdc, hBitmap, 0, uintptr(screenHeight), lpDIB+unsafe.Sizeof(bi), uintptr(unsafe.Pointer(&bi)), 0)
// 將BITMAPINFOHEADER補上,即寫lpDIB開始寫入BITMAPINFOHEADER的資料
copy((*[1 << 30]byte)(unsafe.Pointer(lpDIB))[:], (*[1 << 30]byte)(unsafe.Pointer(&bi))[:unsafe.Sizeof(bi)])
openClipboard.Call(0)
defer closeClipboard.Call()
emptyClipboard.Call()
setClipboardData.Call(CF_DIB, hDIB)
fmt.Println("Screenshot copied to clipboard as CF_DIB")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment