Я пытаюсь использовать syscall с user32.dll, чтобы получить содержимое буфера обмена. Я ожидаю, что это будут данные изображения с экрана печати.Как получить буфер данных изображения из памяти буфера обмена (uintptr)?
Прямо сейчас у меня есть это:
if opened := openClipboard(0); !opened {
fmt.Println("Failed to open Clipboard")
}
handle := getClipboardData(CF_BITMAP)
// get buffer
img, _, err := Decode(buffer)
Мне нужно, чтобы получить данные в читаемый буфер с помощью ручки.
У меня было некоторое вдохновение от AllenDang/w32 и atotto/clipboard на github. Ниже будет работать на текст, основанный на реализации atotto в:
text := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(handle))[:])
Но как я могу получить буфер, содержащий данные изображения, я могу расшифровать?
[Update]
Going раствором @kostix при условии, я взломал вместе рабочий пример наполовину:
image.RegisterFormat("bmp", "bmp", bmp.Decode, bmp.DecodeConfig)
if opened := w32.OpenClipboard(0); opened == false {
fmt.Println("Error: Failed to open Clipboard")
}
//fmt.Printf("Format: %d\n", w32.EnumClipboardFormats(w32.CF_BITMAP))
handle := w32.GetClipboardData(w32.CF_DIB)
size := globalSize(w32.HGLOBAL(handle))
if handle != 0 {
pData := w32.GlobalLock(w32.HGLOBAL(handle))
if pData != nil {
data := (*[1 << 25]byte)(pData)[:size]
// The data is either in DIB format and missing the BITMAPFILEHEADER
// or there are other issues since it can't be decoded at this point
buffer := bytes.NewBuffer(data)
img, _, err := image.Decode(buffer)
if err != nil {
fmt.Printf("Failed decoding: %s", err)
os.Exit(1)
}
fmt.Println(img.At(0, 0).RGBA())
}
w32.GlobalUnlock(w32.HGLOBAL(pData))
}
w32.CloseClipboard()
AllenDang/w32 содержит большую часть того, что вам нужно, но иногда вам нужно реализовать что-то сами, как globalSize():
var (
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
procGlobalSize = modkernel32.NewProc("GlobalSize")
)
func globalSize(hMem w32.HGLOBAL) uint {
ret, _, _ := procGlobalSize.Call(uintptr(hMem))
if ret == 0 {
panic("GlobalSize failed")
}
return uint(ret)
}
Может быть, кто-то придет с решением, чтобы получить данные в формате BMP. Пока я буду идти по другому пути.
Вам нужно знать, какие большие данные «CF_BITMAP». Что делает 'getClipboardData'? – JimB
Ну, CF_BITMAP просто сообщает вызов, какой тип данных мы запрашиваем, он равен 2. Размер изображения/растрового изображения будет связан с разрешением, но я не мог придумать число, если это то, что ты имеешь в виду. getClipboardData возвращает uintptr, который должен быть указателем на данные изображения. Я просто не знаю, как правильно его получить. Я не совсем понимаю, как работает текстовая строка, возможно, вы или кто-то еще здесь знает, как она работает и какова будет версия буфера. – Kesarion
С быстрым взглядом на 'github.com/atotto/clipboard' ваш пример не будет работать над текстом, потому что' handle' не является указателем на строку с нулевым завершением, это WINAPI HANDLE. То же самое касается растрового изображения, указатель отличается от РУЧКИ. На самом деле это не просто «извлечение» некоторой памяти с помощью указателя, вы должны использовать API окон для доступа к растровому изображению через данный дескриптор. – JimB