How to save image in clipboard.
-
- Posts: 4358
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: How to save image in clipboard.
As a result, I don't see any advantages to use GDIp. Even though in some cases it can be faster, but WIC packs files better (and gives an ability to use custom codecs).
Re: How to save image in clipboard.
It depends on priority - much better speed in some cases vs better compression.
I prefer speed, because if I need really good compression I will not use wic, but use custom algorithms.
For example this one:
https://pngquant.org/
Also may be You can increase wic speed by modifying wic png encoder options.
https://docs.microsoft.com/en-us/windows/win32/wic/-wic-creating-encoder
I prefer speed, because if I need really good compression I will not use wic, but use custom algorithms.
For example this one:
https://pngquant.org/
Also may be You can increase wic speed by modifying wic png encoder options.
https://docs.microsoft.com/en-us/windows/win32/wic/-wic-creating-encoder
-
- Posts: 4358
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: How to save image in clipboard.
The same I can say to You - If You need packing files better, use C++, not ahk.
BTW my idea why wic is slower was right.
It is because of it encodes with WICPngFilterUnspecified.
If We replace it with WICPngFilterNone like this, then the size and the speed will be +- the same as with gdi.
BTW my idea why wic is slower was right.
It is because of it encodes with WICPngFilterUnspecified.
If We replace it with WICPngFilterNone like this, then the size and the speed will be +- the same as with gdi.
Code: Select all
HBitmapToPngWIC(hBitmap, destPngFilePath) {
static CLSID_WICImagingFactory := "{CACAF262-9370-4615-A13B-9F5539DA4C0A}"
, IID_IWICImagingFactory := "{EC5EC8A9-C395-4314-9C77-54D7A935FF70}"
, GUID_ContainerFormatPng := "{1B7CFAF4-713F-473C-BBCD-6137425FAEAF}"
, WICBitmapUseAlpha := 0x00000000, GENERIC_WRITE := 0x40000000
, WICBitmapEncoderNoCache := 0x00000002
VarSetCapacity(GUID, 16, 0)
DllCall("Ole32\CLSIDFromString", "WStr", GUID_ContainerFormatPng, "Ptr", &GUID)
IWICImagingFactory := ComObjCreate(CLSID_WICImagingFactory, IID_IWICImagingFactory)
; IWICImagingFactory::CreateBitmapFromHBITMAP
DllCall(NumGet(NumGet(IWICImagingFactory + 0) + A_PtrSize*21), "Ptr", IWICImagingFactory, "Ptr", hBitmap, "Ptr", 0, "UInt", WICBitmapUseAlpha, "PtrP", IWICBitmap)
; IWICImagingFactory::CreateStream
DllCall(NumGet(NumGet(IWICImagingFactory + 0) + A_PtrSize*14), "Ptr", IWICImagingFactory, "PtrP", IWICStream)
; IWICStream::InitializeFromFilename
DllCall(NumGet(NumGet(IWICStream + 0) + A_PtrSize*15), "Ptr", IWICStream, "WStr", destPngFilePath, "UInt", GENERIC_WRITE)
; IWICImagingFactory::CreateEncoder
DllCall(NumGet(NumGet(IWICImagingFactory + 0) + A_PtrSize*8), "Ptr", IWICImagingFactory, "Ptr", &GUID, "Ptr", 0, "PtrP", IWICBitmapEncoder)
; IWICBitmapEncoder::Initialize
DllCall(NumGet(NumGet(IWICBitmapEncoder + 0) + A_PtrSize*3), "Ptr", IWICBitmapEncoder, "Ptr", IWICStream, "UInt", WICBitmapEncoderNoCache)
; IWICBitmapEncoder::CreateNewFrame
DllCall(NumGet(NumGet(IWICBitmapEncoder + 0) + A_PtrSize*10), "Ptr", IWICBitmapEncoder, "PtrP", IWICBitmapFrameEncode, "PtrP", pPropertybag)
VarSetCapacity(variant, 8+A_PtrSize*2, 0)
NumPut(VT_UI1 := 0x11, variant, 0, "ushort")
NumPut(WICPngFilterNone := 1, variant, 8, "uchar")
VarSetCapacity(PROPBAG2, A_PtrSize*2+24, 0)
NumPut(11, PROPBAG2, 8, "uint")
NumPut(&(pstrName := "FilterOption"), PROPBAG2, A_PtrSize+8, "ptr")
DllCall(NumGet(NumGet(pPropertybag + 0) + A_PtrSize*4), "ptr", pPropertybag, "uint", 1, "ptr", &PROPBAG2, "ptr", &variant) ; IPropertyBag2::Write
; IWICBitmapFrameEncode::Initialize
DllCall(NumGet(NumGet(IWICBitmapFrameEncode + 0) + A_PtrSize*3), "Ptr", IWICBitmapFrameEncode, "Ptr", pPropertybag)
; IWICBitmapFrameEncode::WriteSource
DllCall(NumGet(NumGet(IWICBitmapFrameEncode + 0) + A_PtrSize*11), "Ptr", IWICBitmapFrameEncode, "Ptr", IWICBitmap, "Ptr", 0)
; IWICBitmapFrameEncode::Commit
DllCall(NumGet(NumGet(IWICBitmapFrameEncode + 0) + A_PtrSize*12), "Ptr", IWICBitmapFrameEncode)
; IWICBitmapEncoder::Commit
DllCall(NumGet(NumGet(IWICBitmapEncoder + 0) + A_PtrSize*11), "Ptr", IWICBitmapEncoder)
for k, v in [IWICBitmapFrameEncode, IWICBitmapEncoder, IWICStream, IWICBitmap, IWICImagingFactory, pPropertybag]
ObjRelease(v)
}
-
- Posts: 4358
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: How to save image in clipboard.
Thanks for your research!
But your statements
Also, I can't agree with this:
But your statements
and
contradict each other. It just takes longer for better packing, it could be assumed.
Also, I can't agree with this:
PL doesn't pack files, but algorithm does. Why do you think c++ will give the better result?
Re: How to save image in clipboard.
I would say it just chooses wrong filter for compression optimization.It just takes longer for better packing
If You use c++, You can forget about wic algorithms, because they are not perfect, for example with gif they will not work at all, and use custom libraries like this:PL doesn't pack files, but algorithm does. Why do you think c++ will give the better result?
https://github.com/kornelski/pngquant
-
- Posts: 4358
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: How to save image in clipboard.
This what I see:
Why do you call it «wrong filter»? What exactly is «wrong»?[urlhttps://docs.microsoft.com/en-us/windows/win32/api/wincodec/ne-wincodec-wicpngfilteroption#constants]MSDN[/url] wrote:WICPngFilterUnspecified
Indicates an unspecified PNG filter. This enables WIC to algorithmically choose the best filtering option for the image.
What do you mean? I've already created gif files using WIC. And why not compile this library as a dll file and use it with AHK?
Re: How to save image in clipboard.
It chooses algorithm that takes time, but the size remaining the same.Why do you call it «wrong filter»? What exactly is «wrong»?
I mean that Wic creates very big gif files.What do you mean? I've already created gif files using WIC.
If it exists and it is OK for You, of course You can compile.And why not compile this library as a dll file and use it with AHK?
-
- Posts: 4358
- Joined: 29 Mar 2015, 09:41
- Contact:
-
- Posts: 4358
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: How to save image in clipboard.
Try this, and you will see that you are mistaken:
Code: Select all
UrlDownloadToFile, https://i.imgur.com/QuB8MoV.jpeg, %A_Desktop%\test.jpeg
hBitmap := LoadPicture(A_Desktop . "\test.jpeg", "GDI+")
HBitmapToPngWIC_1(hBitmap, A_Desktop . "\test_1.png")
HBitmapToPngWIC_2(hBitmap, A_Desktop . "\test_2.png")
FileGetSize, size1, %A_Desktop%\test_1.png
FileGetSize, size2, %A_Desktop%\test_2.png
MsgBox, % "size1: " . size1 . "`nsize2: " size2
HBitmapToPngWIC_1(hBitmap, destPngFilePath) {
static CLSID_WICImagingFactory := "{CACAF262-9370-4615-A13B-9F5539DA4C0A}"
, IID_IWICImagingFactory := "{EC5EC8A9-C395-4314-9C77-54D7A935FF70}"
, GUID_ContainerFormatPng := "{1B7CFAF4-713F-473C-BBCD-6137425FAEAF}"
, WICBitmapUseAlpha := 0x00000000, GENERIC_WRITE := 0x40000000
, WICBitmapEncoderNoCache := 0x00000002
VarSetCapacity(GUID, 16, 0)
DllCall("Ole32\CLSIDFromString", "WStr", GUID_ContainerFormatPng, "Ptr", &GUID)
IWICImagingFactory := ComObjCreate(CLSID_WICImagingFactory, IID_IWICImagingFactory)
Vtable( IWICImagingFactory , CreateBitmapFromHBITMAP := 21 ).Call("Ptr", hBitmap, "Ptr", 0, "UInt", WICBitmapUseAlpha, "PtrP", IWICBitmap)
Vtable( IWICImagingFactory , CreateStream := 14 ).Call("PtrP", IWICStream)
Vtable( IWICStream , InitializeFromFilename := 15 ).Call("WStr", destPngFilePath, "UInt", GENERIC_WRITE)
Vtable( IWICImagingFactory , CreateEncoder := 8 ).Call("Ptr", &GUID, "Ptr", 0, "PtrP", IWICBitmapEncoder)
Vtable( IWICBitmapEncoder , Initialize := 3 ).Call("Ptr", IWICStream, "UInt", WICBitmapEncoderNoCache)
Vtable( IWICBitmapEncoder , CreateNewFrame := 10 ).Call("PtrP", IWICBitmapFrameEncode, "Ptr", 0)
Vtable( IWICBitmapFrameEncode , Initialize := 3 ).Call("Ptr", 0)
Vtable( IWICBitmapFrameEncode , WriteSource := 11 ).Call("Ptr", IWICBitmap, "Ptr", 0)
Vtable( IWICBitmapFrameEncode , Commit := 12 ).Call()
Vtable( IWICBitmapEncoder , Commit := 11 ).Call()
for k, v in [IWICBitmapFrameEncode, IWICBitmapEncoder, IWICStream, IWICBitmap, IWICImagingFactory]
ObjRelease(v)
}
Vtable(ptr, n) {
return Func("DllCall").Bind(NumGet(NumGet(ptr+0), A_PtrSize*n), "Ptr", ptr)
}
HBitmapToPngWIC_2(hBitmap, destPngFilePath) {
static CLSID_WICImagingFactory := "{CACAF262-9370-4615-A13B-9F5539DA4C0A}"
, IID_IWICImagingFactory := "{EC5EC8A9-C395-4314-9C77-54D7A935FF70}"
, GUID_ContainerFormatPng := "{1B7CFAF4-713F-473C-BBCD-6137425FAEAF}"
, WICBitmapUseAlpha := 0x00000000, GENERIC_WRITE := 0x40000000
, WICBitmapEncoderNoCache := 0x00000002
VarSetCapacity(GUID, 16, 0)
DllCall("Ole32\CLSIDFromString", "WStr", GUID_ContainerFormatPng, "Ptr", &GUID)
IWICImagingFactory := ComObjCreate(CLSID_WICImagingFactory, IID_IWICImagingFactory)
; IWICImagingFactory::CreateBitmapFromHBITMAP
DllCall(NumGet(NumGet(IWICImagingFactory + 0) + A_PtrSize*21), "Ptr", IWICImagingFactory, "Ptr", hBitmap, "Ptr", 0, "UInt", WICBitmapUseAlpha, "PtrP", IWICBitmap)
; IWICImagingFactory::CreateStream
DllCall(NumGet(NumGet(IWICImagingFactory + 0) + A_PtrSize*14), "Ptr", IWICImagingFactory, "PtrP", IWICStream)
; IWICStream::InitializeFromFilename
DllCall(NumGet(NumGet(IWICStream + 0) + A_PtrSize*15), "Ptr", IWICStream, "WStr", destPngFilePath, "UInt", GENERIC_WRITE)
; IWICImagingFactory::CreateEncoder
DllCall(NumGet(NumGet(IWICImagingFactory + 0) + A_PtrSize*8), "Ptr", IWICImagingFactory, "Ptr", &GUID, "Ptr", 0, "PtrP", IWICBitmapEncoder)
; IWICBitmapEncoder::Initialize
DllCall(NumGet(NumGet(IWICBitmapEncoder + 0) + A_PtrSize*3), "Ptr", IWICBitmapEncoder, "Ptr", IWICStream, "UInt", WICBitmapEncoderNoCache)
; IWICBitmapEncoder::CreateNewFrame
DllCall(NumGet(NumGet(IWICBitmapEncoder + 0) + A_PtrSize*10), "Ptr", IWICBitmapEncoder, "PtrP", IWICBitmapFrameEncode, "PtrP", pPropertybag)
VarSetCapacity(variant, 8+A_PtrSize*2, 0)
NumPut(VT_UI1 := 0x11, variant, 0, "ushort")
NumPut(WICPngFilterNone := 1, variant, 8, "uchar")
VarSetCapacity(PROPBAG2, A_PtrSize*2+24, 0)
NumPut(11, PROPBAG2, 8, "uint")
NumPut(&(pstrName := "FilterOption"), PROPBAG2, A_PtrSize+8, "ptr")
DllCall(NumGet(NumGet(pPropertybag + 0) + A_PtrSize*4), "ptr", pPropertybag, "uint", 1, "ptr", &PROPBAG2, "ptr", &variant) ; IPropertyBag2::Write
; IWICBitmapFrameEncode::Initialize
DllCall(NumGet(NumGet(IWICBitmapFrameEncode + 0) + A_PtrSize*3), "Ptr", IWICBitmapFrameEncode, "Ptr", pPropertybag)
; IWICBitmapFrameEncode::WriteSource
DllCall(NumGet(NumGet(IWICBitmapFrameEncode + 0) + A_PtrSize*11), "Ptr", IWICBitmapFrameEncode, "Ptr", IWICBitmap, "Ptr", 0)
; IWICBitmapFrameEncode::Commit
DllCall(NumGet(NumGet(IWICBitmapFrameEncode + 0) + A_PtrSize*12), "Ptr", IWICBitmapFrameEncode)
; IWICBitmapEncoder::Commit
DllCall(NumGet(NumGet(IWICBitmapEncoder + 0) + A_PtrSize*11), "Ptr", IWICBitmapEncoder)
for k, v in [IWICBitmapFrameEncode, IWICBitmapEncoder, IWICStream, IWICBitmap, IWICImagingFactory, pPropertybag]
ObjRelease(v)
}
Re: How to save image in clipboard.
But I dont speak about Your picture.
Try mine.
Try mine.
-
- Posts: 4358
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: How to save image in clipboard.
I've tried. You said that the size remains the same, my example proves that this is not the case.
Re: How to save image in clipboard.
I dont understand You.
I am not talking about Your picture.
For Your picture wic chooses algorithm OK.
Try this code.
I am not talking about Your picture.
For Your picture wic chooses algorithm OK.
Try this code.
Code: Select all
UrlDownloadToFile, https://i.imgur.com/psgZToZ.png, %A_Desktop%\test.png
hBitmap := LoadPicture(A_Desktop . "\test.png", "GDI+")
HBitmapToPngWIC_1(hBitmap, A_Desktop . "\test_1.png")
HBitmapToPngWIC_2(hBitmap, A_Desktop . "\test_2.png")
FileGetSize, size1, %A_Desktop%\test_1.png
FileGetSize, size2, %A_Desktop%\test_2.png
MsgBox, % "size1: " . size1 . "`nsize2: " size2
HBitmapToPngWIC_1(hBitmap, destPngFilePath) {
static CLSID_WICImagingFactory := "{CACAF262-9370-4615-A13B-9F5539DA4C0A}"
, IID_IWICImagingFactory := "{EC5EC8A9-C395-4314-9C77-54D7A935FF70}"
, GUID_ContainerFormatPng := "{1B7CFAF4-713F-473C-BBCD-6137425FAEAF}"
, WICBitmapUseAlpha := 0x00000000, GENERIC_WRITE := 0x40000000
, WICBitmapEncoderNoCache := 0x00000002
VarSetCapacity(GUID, 16, 0)
DllCall("Ole32\CLSIDFromString", "WStr", GUID_ContainerFormatPng, "Ptr", &GUID)
IWICImagingFactory := ComObjCreate(CLSID_WICImagingFactory, IID_IWICImagingFactory)
Vtable( IWICImagingFactory , CreateBitmapFromHBITMAP := 21 ).Call("Ptr", hBitmap, "Ptr", 0, "UInt", WICBitmapUseAlpha, "PtrP", IWICBitmap)
Vtable( IWICImagingFactory , CreateStream := 14 ).Call("PtrP", IWICStream)
Vtable( IWICStream , InitializeFromFilename := 15 ).Call("WStr", destPngFilePath, "UInt", GENERIC_WRITE)
Vtable( IWICImagingFactory , CreateEncoder := 8 ).Call("Ptr", &GUID, "Ptr", 0, "PtrP", IWICBitmapEncoder)
Vtable( IWICBitmapEncoder , Initialize := 3 ).Call("Ptr", IWICStream, "UInt", WICBitmapEncoderNoCache)
Vtable( IWICBitmapEncoder , CreateNewFrame := 10 ).Call("PtrP", IWICBitmapFrameEncode, "Ptr", 0)
Vtable( IWICBitmapFrameEncode , Initialize := 3 ).Call("Ptr", 0)
Vtable( IWICBitmapFrameEncode , WriteSource := 11 ).Call("Ptr", IWICBitmap, "Ptr", 0)
Vtable( IWICBitmapFrameEncode , Commit := 12 ).Call()
Vtable( IWICBitmapEncoder , Commit := 11 ).Call()
for k, v in [IWICBitmapFrameEncode, IWICBitmapEncoder, IWICStream, IWICBitmap, IWICImagingFactory]
ObjRelease(v)
}
Vtable(ptr, n) {
return Func("DllCall").Bind(NumGet(NumGet(ptr+0), A_PtrSize*n), "Ptr", ptr)
}
HBitmapToPngWIC_2(hBitmap, destPngFilePath) {
static CLSID_WICImagingFactory := "{CACAF262-9370-4615-A13B-9F5539DA4C0A}"
, IID_IWICImagingFactory := "{EC5EC8A9-C395-4314-9C77-54D7A935FF70}"
, GUID_ContainerFormatPng := "{1B7CFAF4-713F-473C-BBCD-6137425FAEAF}"
, WICBitmapUseAlpha := 0x00000000, GENERIC_WRITE := 0x40000000
, WICBitmapEncoderNoCache := 0x00000002
VarSetCapacity(GUID, 16, 0)
DllCall("Ole32\CLSIDFromString", "WStr", GUID_ContainerFormatPng, "Ptr", &GUID)
IWICImagingFactory := ComObjCreate(CLSID_WICImagingFactory, IID_IWICImagingFactory)
; IWICImagingFactory::CreateBitmapFromHBITMAP
DllCall(NumGet(NumGet(IWICImagingFactory + 0) + A_PtrSize*21), "Ptr", IWICImagingFactory, "Ptr", hBitmap, "Ptr", 0, "UInt", WICBitmapUseAlpha, "PtrP", IWICBitmap)
; IWICImagingFactory::CreateStream
DllCall(NumGet(NumGet(IWICImagingFactory + 0) + A_PtrSize*14), "Ptr", IWICImagingFactory, "PtrP", IWICStream)
; IWICStream::InitializeFromFilename
DllCall(NumGet(NumGet(IWICStream + 0) + A_PtrSize*15), "Ptr", IWICStream, "WStr", destPngFilePath, "UInt", GENERIC_WRITE)
; IWICImagingFactory::CreateEncoder
DllCall(NumGet(NumGet(IWICImagingFactory + 0) + A_PtrSize*8), "Ptr", IWICImagingFactory, "Ptr", &GUID, "Ptr", 0, "PtrP", IWICBitmapEncoder)
; IWICBitmapEncoder::Initialize
DllCall(NumGet(NumGet(IWICBitmapEncoder + 0) + A_PtrSize*3), "Ptr", IWICBitmapEncoder, "Ptr", IWICStream, "UInt", WICBitmapEncoderNoCache)
; IWICBitmapEncoder::CreateNewFrame
DllCall(NumGet(NumGet(IWICBitmapEncoder + 0) + A_PtrSize*10), "Ptr", IWICBitmapEncoder, "PtrP", IWICBitmapFrameEncode, "PtrP", pPropertybag)
VarSetCapacity(variant, 8+A_PtrSize*2, 0)
NumPut(VT_UI1 := 0x11, variant, 0, "ushort")
NumPut(WICPngFilterNone := 1, variant, 8, "uchar")
VarSetCapacity(PROPBAG2, A_PtrSize*2+24, 0)
NumPut(11, PROPBAG2, 8, "uint")
NumPut(&(pstrName := "FilterOption"), PROPBAG2, A_PtrSize+8, "ptr")
DllCall(NumGet(NumGet(pPropertybag + 0) + A_PtrSize*4), "ptr", pPropertybag, "uint", 1, "ptr", &PROPBAG2, "ptr", &variant) ; IPropertyBag2::Write
; IWICBitmapFrameEncode::Initialize
DllCall(NumGet(NumGet(IWICBitmapFrameEncode + 0) + A_PtrSize*3), "Ptr", IWICBitmapFrameEncode, "Ptr", pPropertybag)
; IWICBitmapFrameEncode::WriteSource
DllCall(NumGet(NumGet(IWICBitmapFrameEncode + 0) + A_PtrSize*11), "Ptr", IWICBitmapFrameEncode, "Ptr", IWICBitmap, "Ptr", 0)
; IWICBitmapFrameEncode::Commit
DllCall(NumGet(NumGet(IWICBitmapFrameEncode + 0) + A_PtrSize*12), "Ptr", IWICBitmapFrameEncode)
; IWICBitmapEncoder::Commit
DllCall(NumGet(NumGet(IWICBitmapEncoder + 0) + A_PtrSize*11), "Ptr", IWICBitmapEncoder)
for k, v in [IWICBitmapFrameEncode, IWICBitmapEncoder, IWICStream, IWICBitmap, IWICImagingFactory, pPropertybag]
ObjRelease(v)
}
-
- Posts: 4358
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: How to save image in clipboard.
Are you serious? Do you take an nearly empty file and suggest compressing it? Take any usual png and the size will be different.
For examle, this one. In your particular case, WIC is not optimal by default, but this case is not at all indicative.
For examle, this one. In your particular case, WIC is not optimal by default, but this case is not at all indicative.
Re: How to save image in clipboard.
Absolutely serious.
Wic badly analyzes images, badly compress them - just spends extra time.
Try compress with this utility and compare results.
https://pngquant.org/
I do not understand what do You try to prove me?
Wic badly analyzes images, badly compress them - just spends extra time.
Try compress with this utility and compare results.
https://pngquant.org/
I do not understand what do You try to prove me?
-
- Posts: 4358
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: How to save image in clipboard.
You forgot that we initially compared GDIplus and WIC. Compared to GDIplus, WIC packs files better, and at least in most cases is not inferior in speed with the same quality. Therefore, WIC is preferable, that's all.
Why do you suggest comparing with external libraries? It is clear that if they exist, they do better.
Re: How to save image in clipboard.
When We started to compare gdi and wic, I did not know that wic worked slower because of compression and We can turn off it.
So if We need speed, then We have to use gdi+ or Wic with WICPngFilterNone.
As for me I stopped to use wic because of speed in real situation, when I needed save screenshots of explorer window.
It took +-2x times more than with gdi.
But at that date I did not make researches about it, just compare speed with gdi+ and chose gdi+.
So if We need speed, then We have to use gdi+ or Wic with WICPngFilterNone.
As for me I stopped to use wic because of speed in real situation, when I needed save screenshots of explorer window.
It took +-2x times more than with gdi.
But at that date I did not make researches about it, just compare speed with gdi+ and chose gdi+.
Re: How to save image in clipboard.
Wow. That's a lot of code.
Anyways, to answer the OP's question, it's possible there is a PNG stream on the clipboard.
I can guarantee this code is the absolute fastest. Why? Because it never decodes the HBitmap, instead it only looks for a png on the clipboard and saves it.
Anyways, to answer the OP's question, it's possible there is a PNG stream on the clipboard.
Code: Select all
filepath := "test.png"
; Open the clipboard with exponential backoff.
loop
if DllCall("OpenClipboard", "ptr", A_ScriptHwnd)
break
else
if A_Index < 6
Sleep (2**(A_Index-1) * 30)
else throw Exception("Clipboard could not be opened.")
; Prefer the PNG stream if available because of transparency support.
png := DllCall("RegisterClipboardFormat", "str", "png", "uint")
if DllCall("IsClipboardFormatAvailable", "uint", png) {
if !(hData := DllCall("GetClipboardData", "uint", png, "ptr"))
throw Exception("Shared clipboard data has been deleted.")
; Allow the stream to be freed while leaving the hData intact.
; Please read: https://devblogs.microsoft.com/oldnewthing/20210930-00/?p=105745
DllCall("ole32\CreateStreamOnHGlobal", "ptr", hData, "int", false, "ptr*", pStream:=0, "uint")
DllCall("shlwapi\SHCreateStreamOnFileEx"
, "wstr", filepath
, "uint", 0x1001 ; STGM_CREATE | STGM_WRITE
, "uint", 0x80 ; FILE_ATTRIBUTE_NORMAL
, "int", true ; fCreate is ignored when STGM_CREATE is set.
, "ptr", 0 ; pstmTemplate (reserved)
, "ptr*", pFileStream:=0
, "uint")
DllCall("shlwapi\IStream_Size", "ptr", pStream, "ptr*", size:=0, "uint")
DllCall("shlwapi\IStream_Reset", "ptr", pStream, "uint")
DllCall("shlwapi\IStream_Copy", "ptr", pStream, "ptr", pFileStream, "uint", size, "uint")
ObjRelease(pFileStream)
ObjRelease(pStream)
}
DllCall("CloseClipboard")
Who is online
Users browsing this forum: Google [Bot], JPMuir, koolestani, shipaddicted and 111 guests