I see.... Thank you very much!
Code: Select all
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
F2:: ; press F2 to save screenshot as .bmp file and also load it to clipboard
hBM := ""
hBM := GDI_CaptureScreen( 0, 0, A_ScreenWidth, A_ScreenHeight )
SaveToImageFile(hBM, A_ScriptDir . "\ClipboardImage.bmp")
GDI_CaptureScreenToClipboard(0, 0, A_ScreenWidth, A_ScreenHeight)
DllCall("DeleteObject", "Ptr", hbm) ; Clean-up
Return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GDI_CaptureScreen(X, Y, W, H) {
static flags := (SRCCOPY := 0x00CC0020) | (CAPTUREBLT := 0x40000000)
hDC := DllCall("GetDC", "Ptr", 0, "Ptr")
hBM := DllCall("CreateCompatibleBitmap", "Ptr", hDC, "Int", W, "Int", H, "Ptr")
hMDC := DllCall("CreateCompatibleDC", "Ptr", hDC, "Ptr")
hObj := DllCall("SelectObject", "Ptr", hMDC, "Ptr", hBM, "Ptr")
DllCall("BitBlt", "Ptr", hMDC, "Int", 0, "Int", 0, "Int", W, "Int", H
, "Ptr", hDC, "Int", X, "Int", Y, "UInt", flags)
DllCall("SelectObject", "Ptr", hMDC, "Ptr", hObj, "Ptr")
DllCall("DeleteDC", "Ptr", hMDC)
DllCall("ReleaseDC", "Ptr", 0, "Ptr", hDC)
Return hBM
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GDI_CaptureScreenToClipboard( X, Y, W, H) {
Static SizeOfDIB := A_PtrSize = 8 ? 104 : 84 ; DIBSECTION
Static SizeOfBM := A_PtrSize = 8 ? 32 : 24 ; BITMAP
Static SizeOfBIH := 40 ; BITMAPINFOHEADER
Static OffBits := A_PtrSize = 8 ? 24 : 20 ; BITMAP -> bmBits
Static OffSize := A_PtrSize = 8 ? 52 : 44 ; BITMAPINFOHEADER -> biSizeImage
Local
hDC := DllCall("GetDC", "Ptr", 0, "UPtr")
cDC := DllCall("CreateCompatibleDC", "Ptr", hDC, "UPtr")
hBM := DllCall("CreateCompatibleBitmap", "Ptr", hDC, "Int", W, "Int", H, "UPtr")
hBM := DllCall("CopyImage", "Ptr", hBM, "UInt", 0, "Int", 0, "Int", 0, "UInt", 0x2008, "UPtr")
oBM := DllCall("SelectObject", "Ptr", cDC, "Ptr", hBM, "UPtr")
DllCall("BitBlt", "Ptr", cDC, "Int", 0, "Int", 0, "Int", W, "Int", H
, "Ptr", hDC, "Int", X, "Int", Y, "UInt", 0x40CC0020)
DllCall("SelectObject", "Ptr", cDC, "Ptr", oBM)
DllCall("DeleteDC", "Ptr", tDC)
DllCall("ReleaseDC", "Ptr", 0, "Ptr", hDC)
VarSetCapacity(DIB, SizeOfDIB, 0) ; DIBSECTION
DllCall("GetObject", "Ptr", hBM, "Int", SizeOfDIB, "Ptr", &DIB)
Size := NumGet(DIB, OffSize, "UInt")
Bits := NumGet(DIB, OffBits, "UPtr")
hDIB := DllCall("GlobalAlloc", "UInt", 2, "UInt", SizeOfBIH + Size, "UPtr")
pDIB := DllCall("GlobalLock", "Ptr", hDIB, "UPtr")
DllCall("RtlMoveMemory", "Ptr", pDIB, "Ptr", &DIB + SizeOfBM, "UInt", SizeOfBIH)
DllCall("RtlMoveMemory", "Ptr", pDIB + SizeOfBIH, "Ptr", Bits, "UInt", Size)
DllCall("GlobalUnlock", "Ptr", hDIB)
DllCall("DeleteObject", "Ptr", hBM)
DllCall("OpenClipboard", "Ptr", 0)
DllCall("EmptyClipboard")
DllCall("SetClipboardData", "UInt", 8, "Ptr", hDIB)
DllCall("CloseClipboard")
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SaveToImageFile(hBM, destImageFilePath, jpegQuality := 75) {
gdip := new GDIplus()
pBM := gdip.CreateBitmapFromHBITMAP(hBM)
gdip.SaveBitmap(pBM, destImageFilePath, jpegQuality)
gdip.DisposeImage(pBM)
}
class GDIplus {
__New() {
this.hLib := DllCall("LoadLibrary", "Str", "gdiplus", "Ptr")
VarSetCapacity(si, 8 + A_PtrSize*2, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", "PtrP", pToken, "Ptr", &si, "Ptr", 0)
this.token := pToken
}
__Delete() {
DllCall("gdiplus\GdiplusShutdown", "Ptr", this.token)
DllCall("FreeLibrary", "Ptr", this.hLib)
}
CreateBitmapFromHBITMAP(hBM, Palette=0) {
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Ptr", hBM, "Ptr", Palette, "PtrP", pBM)
return pBM
}
SaveBitmap(pBM, ByRef info, Quality := 75, tobuff := "")
{
; info — if copying to buffer, then file extension, if copying to file, then file path
if tobuff
Extension := info
else
SplitPath, info,,, Extension
if Extension not in BMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,TIF,TIFF,PNG
return -1
DllCall("gdiplus\GdipGetImageEncodersSize", "UintP", nCount, "UintP", nSize)
VarSetCapacity(ci, nSize)
DllCall("gdiplus\GdipGetImageEncoders", "UInt", nCount, "UInt", nSize, "Ptr", &ci)
if !(nCount && nSize)
return -2
Loop, % nCount {
sString := StrGet(NumGet(ci, (idx := (48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize), "UTF-16")
if !InStr(sString, "*." Extension)
continue
pCodec := &ci+idx
break
}
if !pCodec
return -3
if RegExMatch(Extension, "i)^J(PG|PEG|PE|FIF)$") && Quality != 75 {
DllCall("gdiplus\GdipGetEncoderParameterListSize", "Ptr", pBM, "Ptr", pCodec, "UintP", nSize)
VarSetCapacity(EncoderParameters, nSize, 0)
DllCall("gdiplus\GdipGetEncoderParameterList", "Ptr", pBM, "Ptr", pCodec, "UInt", nSize, "Ptr", &EncoderParameters)
Loop, % NumGet(EncoderParameters, "UInt")
{
elem := (24+A_PtrSize)*(A_Index-1) + 4 + (pad := A_PtrSize = 8 ? 4 : 0)
if (NumGet(EncoderParameters, elem+16, "UInt") = 1) && (NumGet(EncoderParameters, elem+20, "UInt") = 6)
{
p := elem+&EncoderParameters-pad-4
NumPut(Quality, NumGet(NumPut(4, NumPut(1, p+0)+20, "UInt")), "UInt")
break
}
}
}
if !tobuff
E := DllCall("gdiplus\GdipSaveImageToFile", "Ptr", pBM, "WStr", info, "Ptr", pCodec, "UInt", p ? p : 0)
else {
DllCall( "ole32\CreateStreamOnHGlobal", "UInt", 0, "Int", 1, "PtrP", pStream )
if !E := DllCall( "gdiplus\GdipSaveImageToStream", "Ptr", pBM, "Ptr", pStream, "Ptr", pCodec, "UInt", p ? p : 0 ) {
DllCall( "ole32\GetHGlobalFromStream", "Ptr", pStream, "PtrP", hData )
pData := DllCall( "GlobalLock", "Ptr", hData, "Ptr" )
nSize := DllCall( "GlobalSize", "Ptr", hData, "Ptr" )
VarSetCapacity( info, 0), VarSetCapacity( info, nSize, 0 )
DllCall( "RtlMoveMemory", "Ptr", &info, "Ptr", pData, "UInt", nSize )
DllCall( "GlobalUnlock", "Ptr", hData )
DllCall( "GlobalFree", "Ptr", hData )
}
ObjRelease(pStream)
}
return E ? -4 : tobuff ? nSize : 0
}
DisposeImage(pBM) {
return DllCall("gdiplus\GdipDisposeImage", "Ptr", pBM)
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;