#NoEnv
SetBatchLines, -1
; #################################
; 参数处理
; #################################
;拖动图片文件到脚本上,自动存到剪贴板中
ImageFile = %1%
; 展开为完整路径
if !RegExMatch(ImageFile, "i)^(https?|ftp)://")
{
Loop, %ImageFile%
ImageFile := A_LoopFileLongPath
}
; #################################
; 复制到剪贴板
; #################################
html =
(
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD></HEAD>
<BODY><!--StartFragment--><IMG src="%ImageFile%"><!--EndFragment--></BODY>
</HTML>
)
WinClip.Clear()
WinClip.SetHTML( html )
if RegExMatch(ImageFile, "i)^(https?|ftp)://")
return
WinClip.SetFiles( ImageFile )
WinClip.SetBitmap( ImageFile )
return
;=========================================
class WinClip extends WinClip_base
{
_toclipboard( ByRef data, size ) ;==================================
{
if !WinClipAPI.OpenClipboard()
return 0
offset := 0
lastPartOffset := 0
WinClipAPI.EmptyClipboard()
while ( offset < size )
{
if !( fmt := NumGet( data, offset, "UInt" ) )
break
offset += 4
if !( dataSize := NumGet( data, offset, "UInt" ) )
break
offset += 4
if ( ( offset + dataSize ) > size )
break
if !( pData := WinClipAPI.GlobalLock( WinClipAPI.GlobalAlloc( 0x0042, dataSize ) ) )
{
offset += dataSize
continue
}
WinClipAPI.memcopy( pData, &data + offset, dataSize )
if ( fmt == this.ClipboardFormats.CF_ENHMETAFILE )
pClipData := WinClipAPI.SetEnhMetaFileBits( pData, dataSize )
else
pClipData := pData
if !pClipData
continue
WinClipAPI.SetClipboardData( fmt, pClipData )
if ( fmt == this.ClipboardFormats.CF_ENHMETAFILE )
WinClipAPI.DeleteEnhMetaFile( pClipData )
WinClipAPI.GlobalUnlock( pData )
offset += dataSize
lastPartOffset := offset
}
WinClipAPI.CloseClipboard()
return lastPartOffset
}
_compileClipData( ByRef out_data, objClip ) ;==================================
{
if !IsObject( objClip )
return 0
;calculating required data size
clipSize := 0
for fmt, params in objClip
clipSize += 8 + params.size
VarSetCapacity( out_data, clipSize, 0 )
offset := 0
for fmt, params in objClip
{
NumPut( fmt, out_data, offset, "UInt" )
offset += 4
NumPut( params.size, out_data, offset, "UInt" )
offset += 4
WinClipAPI.memcopy( &out_data + offset, ObjGetAddress( params, "buffer" ), params.size )
offset += params.size
}
return clipSize
}
_fromclipboard( ByRef clipData ) ;==================================
{
if !WinClipAPI.OpenClipboard()
return 0
nextformat := 0
objFormats := object()
clipSize := 0
formatsNum := 0
while ( nextformat := WinClipAPI.EnumClipboardFormats( nextformat ) )
{
if this.skipFormats.hasKey( nextformat )
continue
if ( dataHandle := WinClipAPI.GetClipboardData( nextformat ) )
{
pObjPtr := 0, nObjSize := 0
if ( nextFormat == this.ClipboardFormats.CF_ENHMETAFILE )
{
if ( bufSize := WinClipAPI.GetEnhMetaFileBits( dataHandle, hemfBuf ) )
pObjPtr := &hemfBuf, nObjSize := bufSize
}
else if ( nSize := WinClipAPI.GlobalSize( WinClipAPI.GlobalLock( dataHandle ) ) )
pObjPtr := dataHandle, nObjSize := nSize
else
continue
if !( pObjPtr && nObjSize )
continue
objFormats[ nextformat ] := { handle : pObjPtr, size : nObjSize }
clipSize += nObjSize
formatsNum++
}
}
structSize := formatsNum*( 4 + 4 ) + clipSize ;allocating 4 bytes for format ID and 4 for data size
if !structSize
return 0
VarSetCapacity( clipData, structSize, 0 )
; array in form of:
; format UInt
; dataSize UInt
; data Byte[]
offset := 0
for fmt, params in objFormats
{
NumPut( fmt, &clipData, offset, "UInt" )
offset += 4
NumPut( params.size, &clipData, offset, "UInt" )
offset += 4
WinClipAPI.memcopy( &clipData + offset, params.handle, params.size )
offset += params.size
WinClipAPI.GlobalUnlock( params.handle )
}
WinClipAPI.CloseClipboard()
return structSize
}
_IsInstance( funcName ) ;==================================
{
if !this.isinstance
{
throw Exception( "Error in '" funcName "':`nInstantiate the object first to use this method!", -1 )
return 0
}
return 1
}
_getClipData( ByRef data ) ;==================================
{
if !( clipSize := ObjGetCapacity( this, "allData" ) )
return 0
if !( pData := ObjGetAddress( this, "allData" ) )
return 0
VarSetCapacity( data, clipSize, 0 )
WinClipAPI.memcopy( &data, pData, clipSize )
return clipSize
}
_parseClipboardData( ByRef data, size ) ;==================================
{
offset := 0
formats := object()
while ( offset < size )
{
if !( fmt := NumGet( data, offset, "UInt" ) )
break
offset += 4
if !( dataSize := NumGet( data, offset, "UInt" ) )
break
offset += 4
if ( ( offset + dataSize ) > size )
break
params := { name : this._getFormatName( fmt ), size : dataSize }
ObjSetCapacity( params, "buffer", dataSize )
pBuf := ObjGetAddress( params, "buffer" )
WinClipAPI.memcopy( pBuf, &data + offset, dataSize )
formats[ fmt ] := params
offset += dataSize
}
return formats
}
Clear() ;==================================
{
if !WinClipAPI.OpenClipboard()
return 0
WinClipAPI.EmptyClipboard()
WinClipAPI.CloseClipboard()
return 1
}
SetHTML( html, source = "" ) ;==================================
{
if ( html = "" )
return 0
clipSize := this._fromclipboard( clipData )
if !( clipSize := this._setHTML( clipData, clipSize, html, source ) )
return 0
return this._toclipboard( clipData, clipSize )
}
iSetHTML( html, source = "" ) ;==================================
{
if ( html = "" )
return 0
this._IsInstance( A_ThisFunc )
clipSize := this._getClipData( clipData )
if !( clipSize := this._setHTML( clipData, clipSize, html, source ) )
return 0
return this._setClipData( clipData, clipSize )
}
_calcHTMLLen( num ) ;==================================
{
while ( StrLen( num ) < 10 )
num := "0" . num
return num
}
_setHTML( ByRef clipData, clipSize, htmlData, source ) ;==================================
{
objFormats := this._parseClipboardData( clipData, clipSize )
uFmt := WinClipAPI.RegisterClipboardFormat( "HTML Format" )
objFormats[ uFmt ] := object()
encoding := "UTF-8"
htmlLen := StrPut( htmlData, encoding ) - 1 ;substract null
srcLen := 2 + 10 + StrPut( source, encoding ) - 1 ;substract null
StartHTML := this._calcHTMLLen( 105 + srcLen )
EndHTML := this._calcHTMLLen( StartHTML + htmlLen + 76 )
StartFragment := this._calcHTMLLen( StartHTML + 38 )
EndFragment := this._calcHTMLLen( StartFragment + htmlLen )
html =
( Join`r`n
Version:0.9
StartHTML:%StartHTML%
EndHTML:%EndHTML%
StartFragment:%StartFragment%
EndFragment:%EndFragment%
SourceURL:%source%
<html>
<body>
<!--StartFragment-->
%htmlData%
<!--EndFragment-->
</body>
</html>
)
sLen := StrPut( html, encoding )
ObjSetCapacity( objFormats[ uFmt ], "buffer", sLen )
StrPut( html, ObjGetAddress( objFormats[ uFmt ], "buffer" ), sLen, encoding )
objFormats[ uFmt ].size := sLen
return this._compileClipData( clipData, objFormats )
}
_getFiles( pDROPFILES ) ;==================================
{
fWide := numget( pDROPFILES + 0, 16, "uchar" ) ;getting fWide value from DROPFILES struct
pFiles := numget( pDROPFILES + 0, 0, "UInt" ) + pDROPFILES ;getting address of files list
list := ""
while numget( pFiles + 0, 0, fWide ? "UShort" : "UChar" )
{
lastPath := strget( pFiles+0, fWide ? "UTF-16" : "CP0" )
list .= ( list ? "`n" : "" ) lastPath
pFiles += ( StrLen( lastPath ) + 1 ) * ( fWide ? 2 : 1 )
}
return list
}
_setFiles( ByRef clipData, clipSize, files, append = 0, isCut = 0 ) ;==================================
{
objFormats := this._parseClipboardData( clipData, clipSize )
uFmt := this.ClipboardFormats.CF_HDROP
if ( append && objFormats.haskey( uFmt ) )
prevList := this._getFiles( ObjGetAddress( objFormats[ uFmt ], "buffer" ) ) "`n"
objFiles := WinClipAPI.StrSplit( prevList . files, "`n", A_Space A_Tab )
objFiles := WinClipAPI.RemoveDubls( objFiles )
if !objFiles.MaxIndex()
return 0
objFormats[ uFmt ] := object()
DROP_size := 20 + 2
for i,str in objFiles
DROP_size += ( StrLen( str ) + 1 ) * 2
VarSetCapacity( DROPFILES, DROP_size, 0 )
NumPut( 20, DROPFILES, 0, "UInt" ) ;offset
NumPut( 1, DROPFILES, 16, "uchar" ) ;NumPut( 20, DROPFILES, 0, "UInt" )
offset := &DROPFILES + 20
for i,str in objFiles
{
StrPut( str, offset, "UTF-16" )
offset += ( StrLen( str ) + 1 ) * 2
}
ObjSetCapacity( objFormats[ uFmt ], "buffer", DROP_size )
WinClipAPI.memcopy( ObjGetAddress( objFormats[ uFmt ], "buffer" ), &DROPFILES, DROP_size )
objFormats[ uFmt ].size := DROP_size
prefFmt := WinClipAPI.RegisterClipboardFormat( "Preferred DropEffect" )
objFormats[ prefFmt ] := { size : 4 }
ObjSetCapacity( objFormats[ prefFmt ], "buffer", 4 )
NumPut( isCut ? 2 : 5, ObjGetAddress( objFormats[ prefFmt ], "buffer" ), 0 "UInt" )
return this._compileClipData( clipData, objFormats )
}
SetFiles( files, isCut = 0 ) ;==================================
{
if ( files = "" )
return 0
clipSize := this._fromclipboard( clipData )
if !( clipSize := this._setFiles( clipData, clipSize, files, 0, isCut ) )
return 0
return this._toclipboard( clipData, clipSize )
}
_BITMAPtoDIB( bitmap, ByRef DIB ) ;==================================
{
if !bitmap
return 0
if !WinClipAPI.IsInteger( bitmap )
{
gdip_token := WinClipAPI.Gdip_Startup()
DllCall("gdiplus\GdipCreateBitmapFromFileICM", "wstr", bitmap, "Ptr*", pBitmap )
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "Ptr*", hBitmap, "int", 0xffffffff )
DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmap)
WinClipAPI.Gdip_Shutdown( gdip_token )
bmMade := 1
}
else
hBitmap := bitmap, bmMade := 0
if !hBitmap
return 0
;http://www.codeguru.com/Cpp/G-M/bitmap/article.php/c1765
if !( hdc := DllCall( "GetDC", "Ptr", 0 ) )
goto, _BITMAPtoDIB_cleanup
hPal := DllCall( "GetStockObject", "UInt", 15 ) ;DEFAULT_PALLETE
hPal := DllCall( "SelectPalette", "ptr", hdc, "ptr", hPal, "Uint", 0 )
DllCall( "RealizePalette", "ptr", hdc )
size := DllCall( "GetObject", "Ptr", hBitmap, "Uint", 0, "ptr", 0 )
VarSetCapacity( bm, size, 0 )
DllCall( "GetObject", "Ptr", hBitmap, "Uint", size, "ptr", &bm )
biBitCount := NumGet( bm, 16, "UShort" )*NumGet( bm, 18, "UShort" )
nColors := (1 << biBitCount)
if ( nColors > 256 )
nColors := 0
bmiLen := 40 + nColors * 4
VarSetCapacity( bmi, bmiLen, 0 )
;BITMAPINFOHEADER initialization
NumPut( 40, bmi, 0, "Uint" )
NumPut( NumGet( bm, 4, "Uint" ), bmi, 4, "Uint" ) ;width
NumPut( biHeight := NumGet( bm, 8, "Uint" ), bmi, 8, "Uint" ) ;height
NumPut( 1, bmi, 12, "UShort" )
NumPut( biBitCount, bmi, 14, "UShort" )
NumPut( 0, bmi, 16, "UInt" ) ;compression must be BI_RGB
; Get BITMAPINFO.
if !DllCall("GetDIBits"
,"ptr",hdc
,"ptr",hBitmap
,"uint",0
,"uint",biHeight
,"ptr",0 ;lpvBits
,"ptr",&bmi ;lpbi
,"uint",0) ;DIB_RGB_COLORS
goto, _BITMAPtoDIB_cleanup
biSizeImage := NumGet( &bmi, 20, "UInt" )
if ( biSizeImage = 0 )
{
biBitCount := numget( &bmi, 14, "UShort" )
biWidth := numget( &bmi, 4, "UInt" )
biHeight := numget( &bmi, 8, "UInt" )
biSizeImage := (((( biWidth * biBitCount + 31 ) & ~31 ) >> 3 ) * biHeight )
;~ dwCompression := numget( bmi, 16, "UInt" )
;~ if ( dwCompression != 0 ) ;BI_RGB
;~ biSizeImage := ( biSizeImage * 3 ) / 2
numput( biSizeImage, &bmi, 20, "UInt" )
}
DIBLen := bmiLen + biSizeImage
VarSetCapacity( DIB, DIBLen, 0 )
WinClipAPI.memcopy( &DIB, &bmi, bmiLen )
if !DllCall("GetDIBits"
,"ptr",hdc
,"ptr",hBitmap
,"uint",0
,"uint",biHeight
,"ptr",&DIB + bmiLen ;lpvBits
,"ptr",&DIB ;lpbi
,"uint",0) ;DIB_RGB_COLORS
goto, _BITMAPtoDIB_cleanup
_BITMAPtoDIB_cleanup:
if bmMade
DllCall( "DeleteObject", "ptr", hBitmap )
DllCall( "SelectPalette", "ptr", hdc, "ptr", hPal, "Uint", 0 )
DllCall( "RealizePalette", "ptr", hdc )
DllCall("ReleaseDC","ptr",hdc)
if ( A_ThisLabel = "_BITMAPtoDIB_cleanup" )
return 0
return DIBLen
}
SetBitmap( bitmap ) ;==================================
{
if ( DIBSize := this._BITMAPtoDIB( bitmap, DIB ) )
{
clipSize := this._fromclipboard( clipData )
if ( clipSize := this._setBitmap( DIB, DIBSize, clipData, clipSize ) )
return this._toclipboard( clipData, clipSize )
}
return 0
}
_setBitmap( ByRef DIB, DIBSize, ByRef clipData, clipSize ) ;==================================
{
objFormats := this._parseClipboardData( clipData, clipSize )
uFmt := this.ClipboardFormats.CF_DIB
objFormats[ uFmt ] := { size : DIBSize }
ObjSetCapacity( objFormats[ uFmt ], "buffer", DIBSize )
WinClipAPI.memcopy( ObjGetAddress( objFormats[ uFmt ], "buffer" ), &DIB, DIBSize )
return this._compileClipData( clipData, objFormats )
}
_getFormatName( iformat ) ;==================================
{
if this.formatByValue.HasKey( iformat )
return this.formatByValue[ iformat ]
else
return WinClipAPI.GetClipboardFormatName( iformat )
}
}
;-------------------------------------------------------------------
class WinClip_base
{
__Call( aTarget, aParams* ) {
if ObjHasKey( WinClip_base, aTarget )
return WinClip_base[ aTarget ].( this, aParams* )
throw Exception( "Unknown function '" aTarget "' requested from object '" this.__Class "'", -1 )
}
Err( msg ) {
throw Exception( this.__Class " : " msg ( A_LastError != 0 ? "`n" this.ErrorFormat( A_LastError ) : "" ), -2 )
}
ErrorFormat( error_id ) {
VarSetCapacity(msg,1000,0)
if !len := DllCall("FormatMessageW"
,"UInt",FORMAT_MESSAGE_FROM_SYSTEM := 0x00001000 | FORMAT_MESSAGE_IGNORE_INSERTS := 0x00000200 ;dwflags
,"Ptr",0 ;lpSource
,"UInt",error_id ;dwMessageId
,"UInt",0 ;dwLanguageId
,"Ptr",&msg ;lpBuffer
,"UInt",500) ;nSize
return
return strget(&msg,len)
}
}
class WinClipAPI_base extends WinClip_base
{
__Get( name ) {
if !ObjHasKey( this, initialized )
this.Init()
else
throw Exception( "Unknown field '" name "' requested from object '" this.__Class "'", -1 )
}
}
class WinClipAPI extends WinClip_base
{
memcopy( dest, src, size ) { ;==================================
return DllCall( "msvcrt\memcpy", "ptr", dest, "ptr", src, "uint", size )
}
GlobalSize( hObj ) { ;==================================
return DllCall( "GlobalSize", "Ptr", hObj )
}
GlobalLock( hMem ) { ;==================================
return DllCall( "GlobalLock", "Ptr", hMem )
}
GlobalUnlock( hMem ) { ;==================================
return DllCall( "GlobalUnlock", "Ptr", hMem )
}
GlobalAlloc( flags, size ) { ;==================================
return DllCall( "GlobalAlloc", "Uint", flags, "Uint", size )
}
OpenClipboard() { ;==================================
return DllCall( "OpenClipboard", "Ptr", 0 )
}
CloseClipboard() { ;==================================
return DllCall( "CloseClipboard" )
}
SetClipboardData( format, hMem ) { ;==================================
return DllCall( "SetClipboardData", "Uint", format, "Ptr", hMem )
}
GetClipboardData( format ) { ;==================================
return DllCall( "GetClipboardData", "Uint", format )
}
EmptyClipboard() { ;==================================
return DllCall( "EmptyClipboard" )
}
EnumClipboardFormats( format ) { ;==================================
return DllCall( "EnumClipboardFormats", "UInt", format )
}
GetClipboardFormatName( iFormat ) { ;==================================
size := VarSetCapacity( bufName, 255*( A_IsUnicode ? 2 : 1 ), 0 )
DllCall( "GetClipboardFormatName", "Uint", iFormat, "str", bufName, "Uint", size )
return bufName
}
GetEnhMetaFileBits( hemf, ByRef buf ) { ;==================================
if !( bufSize := DllCall( "GetEnhMetaFileBits", "Ptr", hemf, "Uint", 0, "Ptr", 0 ) )
return 0
VarSetCapacity( buf, bufSize, 0 )
if !( bytesCopied := DllCall( "GetEnhMetaFileBits", "Ptr", hemf, "Uint", bufSize, "Ptr", &buf ) )
return 0
return bytesCopied
}
SetEnhMetaFileBits( pBuf, bufSize ) { ;==================================
return DllCall( "SetEnhMetaFileBits", "Uint", bufSize, "Ptr", pBuf )
}
DeleteEnhMetaFile( hemf ) { ;==================================
return DllCall( "DeleteEnhMetaFile", "Ptr", hemf )
}
IsInteger( var ) { ;==================================
if var is integer
return True
else
return False
}
Gdip_Startup() {
if !DllCall( "GetModuleHandleW", "Wstr", "gdiplus", "UPtr" )
DllCall( "LoadLibraryW", "Wstr", "gdiplus", "UPtr" )
VarSetCapacity(GdiplusStartupInput , 3*A_PtrSize, 0), NumPut(1,GdiplusStartupInput ,0,"UInt") ; GdiplusVersion = 1
DllCall("gdiplus\GdiplusStartup", "Ptr*", pToken, "Ptr", &GdiplusStartupInput, "Ptr", 0)
return pToken
}
Gdip_Shutdown(pToken) {
DllCall("gdiplus\GdiplusShutdown", "Ptr", pToken)
if hModule := DllCall( "GetModuleHandleW", "Wstr", "gdiplus", "UPtr" )
DllCall("FreeLibrary", "Ptr", hModule)
return 0
}
StrSplit(str,delim,omit = "") ;==================================
{
if (strlen(delim) > 1)
{
StringReplace,str,str,% delim,ƒ,1 ;■¶╬
delim = ƒ
}
ra := Array()
loop, parse,str,% delim,% omit
if (A_LoopField != "")
ra.Insert(A_LoopField)
return ra
}
RemoveDubls( objArray ) ;==================================
{
while True
{
nodubls := 1
tempArr := Object()
for i,val in objArray
{
if tempArr.haskey( val )
{
nodubls := 0
objArray.Remove( i )
break
}
tempArr[ val ] := 1
}
if nodubls
break
}
return objArray
}
RegisterClipboardFormat( fmtName ) { ;==================================
return DllCall( "RegisterClipboardFormat", "ptr", &fmtName )
}
}
暂无讨论,说说你的看法吧