├── .gitignore
├── README.md
└── evernoteeditor.ahk
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build and Release Folders
2 | bin/
3 | bin-debug/
4 | bin-release/
5 | [Oo]bj/ # FlashDevelop obj
6 | [Bb]in/ # FlashDevelop bin
7 |
8 | # Other files and folders
9 | .settings/
10 |
11 | # Executables
12 | *.swf
13 | *.air
14 | *.ipa
15 | *.apk
16 |
17 | # Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
18 | # should NOT be excluded as they contain compiler settings and other important
19 | # information for Eclipse / Flash Builder.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Evernote-editor
2 | 印象笔记编辑增强
3 |
4 | 1,去官网安装autohotkey 地址https://autohotkey.com/download/
5 | 2,下载此印象笔记AHK脚本,并双击打开(双击即可.没有打开动画效果)
6 | 3,参考下图
7 | 字体颜色 alt+shift 1/2/3/4红蓝灰绿
8 | 
9 |
10 |
11 | 背景颜色 alt+ctrl 1/2/3/4红蓝灰绿
12 | 
13 |
14 |
15 | 彩色框框 alt+q/w/e/r红黄灰绿
16 | 
17 |
18 |
19 | 常规标题 alt+1/2/3/4
20 | 图略了
21 |
22 |
23 | 超级标题 alt + a
24 | 
25 |
26 |
27 | 引用 alt + s
28 | 
29 |
30 |
31 | 虚线 alt + d
32 | 
33 |
34 |
35 | 方框/代码 alt + f
36 | 
37 |
--------------------------------------------------------------------------------
/evernoteeditor.ahk:
--------------------------------------------------------------------------------
1 | #SingleInstance Force
2 | #NoTrayIcon
3 |
4 | {
5 | #NoEnv ;不检查空变量是否为环境变量
6 | SetBatchLines, -1 ;行之间运行不留时间空隙,默认是有10ms的间隔
7 | SetKeyDelay, -1, -1 ;发送按键不留时间空隙
8 | SetMouseDelay, -1 ;每次鼠标移动或点击后自动的延时=0
9 | SetDefaultMouseSpeed, 0 ;设置在 Click 和 MouseMove/Click/Drag 中没有指定鼠标速度时使用的速度 = 瞬间移动.
10 | SetWinDelay, 0
11 | SetControlDelay, 0
12 | SendMode Input
13 |
14 | #InstallKeybdHook ;安装键盘和鼠标钩子 像Input和A_PriorKey,都需要钩子
15 | #InstallMouseHook
16 | SetTitleMatchMode Regex ;更改进程匹配模式为正则
17 | #SingleInstance force ;决定当脚本已经运行时是否允许它再次运行。
18 | #Persistent ;持续运行不退出
19 | #MaxThreadsPerHotkey 5
20 |
21 | ;Menu, tray, tip, 印象笔记-编辑增强小工具
22 | ;TrayTip, 提示, 印象笔记-编辑增强小工具, , 1
23 | Sleep, 1000
24 | TrayTip
25 |
26 | ;evernote编辑器增强函数
27 | evernoteEdit(eFoward, eEnd)
28 | {
29 | clipboard =
30 | Send ^c
31 | ClipWait, 1
32 | t := WinClip.GetHtml3()
33 | html = %eFoward%%t%%eEnd%
34 | WinClip.Clear()
35 | WinClip.SetHTML(html)
36 | Sleep, 300
37 | Send ^v
38 | Return
39 | }
40 |
41 | ;evernote不保留原格式,增强函数
42 | evernoteEditText(eFoward, eEnd)
43 | {
44 | clipboard =
45 | Send ^c
46 | ClipWait, 1
47 | t := WinClip.GetText()
48 | html = %eFoward%%t%%eEnd%
49 | WinClip.Clear()
50 | WinClip.SetHTML(html)
51 | Sleep, 300
52 | Send ^v
53 | Return
54 | }
55 |
56 | ;evernote无原文本的插入html增强函数
57 | evernoteInsertHTML(html)
58 | {
59 | clipboard =
60 | WinClip.SetHTML(html)
61 | Sleep, 300
62 | Send ^v
63 | Return
64 | }
65 |
66 | ;自定义setLink函数
67 | setLink()
68 | {
69 | clipboard = %clipboard%
70 | homeStr =
72 | div = %homeStr%%clipboard%%endStr%
73 | Return div
74 | }
75 | WinClip.GetHtml2 := Func("GetHtml2") ; 也可以直接覆盖原来的函数 -> WinClip.GetHtml := Func("GetHtml2")
76 | WinClip.GetHtml3 := Func("GetHtml_DOM")
77 |
78 | ;操作HTML DOM,比GetHTML函数更实用
79 | GetHtml_DOM(this, Encoding := "UTF-8")
80 | {
81 | html := this.GetHtml2(Encoding)
82 | static doc := ComObjCreate("htmlFile")
83 | doc.Write(html), doc.Close()
84 | return doc.all.tags("span")[0].InnerHtml
85 | }
86 |
87 | ;WinClip中Get的UTF-8改写,支持中文
88 | GetHtml2(this, Encoding := "UTF-8")
89 | {
90 | if !( clipSize := this._fromclipboard( clipData ) )
91 | return ""
92 | if !( out_size := this._getFormatData( out_data, clipData, clipSize, "HTML Format" ) )
93 | return ""
94 | return strget( &out_data, out_size, Encoding )
95 | }
96 |
97 | }
98 |
99 | #IfWinActive ahk_class (ENSingleNoteView|ENMainFrame)
100 | {
101 | ;快捷键: 非编辑器部分
102 | {
103 | ^Space::controlsend, , ^{Space}, A ;简化格式
104 | $RButton:: ;双击右键高亮
105 | {
106 | CountStp := ++CountStp
107 | SetTimer, TimerPrtSc, -500
108 | Return
109 | TimerPrtSc:
110 | if CountStp = 1 ;只按一次时执行
111 | SendInput, {RButton}
112 | if CountStp = 2 ;按两次时...
113 | SendInput, ^+h
114 | CountStp := 0 ;最后把记录的变量设置为0,于下次记录.
115 | Return
116 | }
117 | }
118 |
119 | ;颜色 字体格式等
120 | {
121 | ;方框环绕
122 | !f::evernoteEdit("","
")
125 | !2::evernoteEditText("","")
126 | !3::evernoteEditText("
")
132 | ;超级标题
133 | !a::evernoteEdit("","")
127 | ;引用
128 | !s::evernoteEdit("
", "") 136 | ;红框框 137 | !q::evernoteEdit(" ") 138 | ;黄框框 139 | !w::evernoteEdit(" " ) 140 | ;灰框框 141 | !e::evernoteEdit(" " ) 142 | ;绿框框 143 | !r::evernoteEdit(" " ) 144 | 145 | ;v6下用evernoteEditText()回帖,前面都会多一个空格,无解。但删除一下也不麻烦,聊胜于无吧 146 | ;背景色黄色 147 | ^!1::evernoteEditText("", "") 148 | ;背景色蓝色 149 | ^!2::evernoteEditText("", "") 150 | ;背景色灰色 151 | ^!3::evernoteEditText("", "") 152 | ;背景色绿色 153 | ^!4::evernoteEditText("", "") 154 | 155 | ;字体红色 156 | !+1::evernoteEditText("", "") 157 | ;字体蓝色 158 | !+2::evernoteEditText("", "") 159 | ;字体灰色 160 | !+3::evernoteEditText("", "") 161 | ;字体绿色 162 | !+4::evernoteEditText("", "") 163 | 164 | ;v6版本,鼠标点击方式,实现修改文字颜色 165 | evernoteMouseChangeColor(r, g, b) { 166 | CoordMode, Mouse, Screen ;鼠标坐标全屏幕模式,方便鼠标回归原位 167 | MouseGetPos, xpos, ypos 168 | 文字:="" 169 | 文字.="|<>52.0000300000000200000000401zzU007k03tw000V0073U002400840008k0000000R0008" 170 | if 查找文字(929,181,150000,150000,文字,"*147",X,Y,OCR,0.2,0.2) 171 | { 172 | CoordMode, Mouse 173 | Click, %X%, %Y% ;点击颜色按钮 174 | Y1 := Y + 180 175 | Click, %X%, %Y1% ;点击更多颜色 176 | } 177 | else 178 | { 179 | MsgBox, 没有找到颜色选择框,找字模块失败! 180 | } 181 | ;SendL("M") ;进入更多颜色 182 | WinWait, 颜色 183 | WinMove, 10, 10 184 | CoordMode, Mouse, Client ;鼠标坐标Client模式 185 | Click, 116, 333 ;进入自定义颜色 186 | SendInput, {Tab}{Tab}{Tab} 187 | SendInput %r%{Tab}%g%{Tab}%b%{Tab}{Space} 188 | Click, 21, 259 ;点击设定好自定义颜色 189 | SendInput, {Tab}{Space} 190 | CoordMode, Mouse, Screen ;鼠标坐标全屏幕模式 191 | MouseMove, %xpos%, %ypos%, 0 192 | return 193 | } 194 | 195 | ;字体红色 196 | ^!F1:: 197 | evernoteMouseChangeColor(240, 46, 55) 198 | SendInput, ^b 199 | return 200 | ;字体蓝色 201 | ^!F2:: 202 | evernoteMouseChangeColor(55, 64, 230) 203 | SendInput, ^b 204 | return 205 | ;字体灰色 206 | ^!F3:: 207 | evernoteMouseChangeColor(214, 214, 214) 208 | return 209 | ;字体绿色 210 | ^!F4:: 211 | evernoteMouseChangeColor(15, 130, 15) 212 | SendInput, ^b 213 | return 214 | ;字体白色 215 | ^!F5:: 216 | evernoteMouseChangeColor(255, 255, 255) 217 | return 218 | } 219 | } 220 | 221 | #IfWinActive 222 | 223 | ;~ 下面是库函数 224 | { 225 | class WinClip_base 226 | { 227 | __Call( aTarget, aParams* ) { 228 | if ObjHasKey( WinClip_base, aTarget ) 229 | return WinClip_base[ aTarget ].( this, aParams* ) 230 | throw Exception( "Unknown function '" aTarget "' requested from object '" this.__Class "'", -1 ) 231 | } 232 | 233 | Err( msg ) { 234 | throw Exception( this.__Class " : " msg ( A_LastError != 0 ? "`n" this.ErrorFormat( A_LastError ) : "" ), -2 ) 235 | } 236 | 237 | ErrorFormat( error_id ) { 238 | VarSetCapacity(msg,1000,0) 239 | if !len := DllCall("FormatMessageW" 240 | ,"UInt",FORMAT_MESSAGE_FROM_SYSTEM := 0x00001000 | FORMAT_MESSAGE_IGNORE_INSERTS := 0x00000200 ;dwflags 241 | ,"Ptr",0 ;lpSource 242 | ,"UInt",error_id ;dwMessageId 243 | ,"UInt",0 ;dwLanguageId 244 | ,"Ptr",&msg ;lpBuffer 245 | ,"UInt",500) ;nSize 246 | return 247 | return strget(&msg,len) 248 | } 249 | } 250 | 251 | class WinClipAPI_base extends WinClip_base 252 | { 253 | __Get( name ) { 254 | if !ObjHasKey( this, initialized ) 255 | this.Init() 256 | else 257 | throw Exception( "Unknown field '" name "' requested from object '" this.__Class "'", -1 ) 258 | } 259 | } 260 | 261 | class WinClipAPI extends WinClip_base 262 | { 263 | memcopy( dest, src, size ) { 264 | return DllCall( "msvcrt\memcpy", "ptr", dest, "ptr", src, "uint", size ) 265 | } 266 | GlobalSize( hObj ) { 267 | return DllCall( "GlobalSize", "Ptr", hObj ) 268 | } 269 | GlobalLock( hMem ) { 270 | return DllCall( "GlobalLock", "Ptr", hMem ) 271 | } 272 | GlobalUnlock( hMem ) { 273 | return DllCall( "GlobalUnlock", "Ptr", hMem ) 274 | } 275 | GlobalAlloc( flags, size ) { 276 | return DllCall( "GlobalAlloc", "Uint", flags, "Uint", size ) 277 | } 278 | OpenClipboard() { 279 | return DllCall( "OpenClipboard", "Ptr", 0 ) 280 | } 281 | CloseClipboard() { 282 | return DllCall( "CloseClipboard" ) 283 | } 284 | SetClipboardData( format, hMem ) { 285 | return DllCall( "SetClipboardData", "Uint", format, "Ptr", hMem ) 286 | } 287 | GetClipboardData( format ) { 288 | return DllCall( "GetClipboardData", "Uint", format ) 289 | } 290 | EmptyClipboard() { 291 | return DllCall( "EmptyClipboard" ) 292 | } 293 | EnumClipboardFormats( format ) { 294 | return DllCall( "EnumClipboardFormats", "UInt", format ) 295 | } 296 | CountClipboardFormats() { 297 | return DllCall( "CountClipboardFormats" ) 298 | } 299 | GetClipboardFormatName( iFormat ) { 300 | size := VarSetCapacity( bufName, 255*( A_IsUnicode ? 2 : 1 ), 0 ) 301 | DllCall( "GetClipboardFormatName", "Uint", iFormat, "str", bufName, "Uint", size ) 302 | return bufName 303 | } 304 | GetEnhMetaFileBits( hemf, ByRef buf ) { 305 | if !( bufSize := DllCall( "GetEnhMetaFileBits", "Ptr", hemf, "Uint", 0, "Ptr", 0 ) ) 306 | return 0 307 | VarSetCapacity( buf, bufSize, 0 ) 308 | if !( bytesCopied := DllCall( "GetEnhMetaFileBits", "Ptr", hemf, "Uint", bufSize, "Ptr", &buf ) ) 309 | return 0 310 | return bytesCopied 311 | } 312 | SetEnhMetaFileBits( pBuf, bufSize ) { 313 | return DllCall( "SetEnhMetaFileBits", "Uint", bufSize, "Ptr", pBuf ) 314 | } 315 | DeleteEnhMetaFile( hemf ) { 316 | return DllCall( "DeleteEnhMetaFile", "Ptr", hemf ) 317 | } 318 | ErrorFormat(error_id) { 319 | VarSetCapacity(msg,1000,0) 320 | if !len := DllCall("FormatMessageW" 321 | ,"UInt",FORMAT_MESSAGE_FROM_SYSTEM := 0x00001000 | FORMAT_MESSAGE_IGNORE_INSERTS := 0x00000200 ;dwflags 322 | ,"Ptr",0 ;lpSource 323 | ,"UInt",error_id ;dwMessageId 324 | ,"UInt",0 ;dwLanguageId 325 | ,"Ptr",&msg ;lpBuffer 326 | ,"UInt",500) ;nSize 327 | return 328 | return strget(&msg,len) 329 | } 330 | IsInteger( var ) { 331 | if var is integer 332 | return True 333 | else 334 | return False 335 | } 336 | LoadDllFunction( file, function ) { 337 | if !hModule := DllCall( "GetModuleHandleW", "Wstr", file, "UPtr" ) 338 | hModule := DllCall( "LoadLibraryW", "Wstr", file, "UPtr" ) 339 | 340 | ret := DllCall("GetProcAddress", "Ptr", hModule, "AStr", function, "UPtr") 341 | return ret 342 | } 343 | SendMessage( hWnd, Msg, wParam, lParam ) { 344 | static SendMessageW 345 | 346 | If not SendMessageW 347 | SendMessageW := this.LoadDllFunction( "user32.dll", "SendMessageW" ) 348 | 349 | ret := DllCall( SendMessageW, "UPtr", hWnd, "UInt", Msg, "UPtr", wParam, "UPtr", lParam ) 350 | return ret 351 | } 352 | GetWindowThreadProcessId( hwnd ) { 353 | return DllCall( "GetWindowThreadProcessId", "Ptr", hwnd, "Ptr", 0 ) 354 | } 355 | WinGetFocus( hwnd ) { 356 | GUITHREADINFO_cbsize := 24 + A_PtrSize*6 357 | VarSetCapacity( GuiThreadInfo, GUITHREADINFO_cbsize, 0 ) ;GuiThreadInfoSize = 48 358 | NumPut(GUITHREADINFO_cbsize, GuiThreadInfo, 0, "UInt") 359 | threadWnd := this.GetWindowThreadProcessId( hwnd ) 360 | if not DllCall( "GetGUIThreadInfo", "uint", threadWnd, "UPtr", &GuiThreadInfo ) 361 | return 0 362 | return NumGet( GuiThreadInfo, 8+A_PtrSize,"UPtr") ; Retrieve the hwndFocus field from the struct. 363 | } 364 | GetPixelInfo( ByRef DIB ) { 365 | ;~ typedef struct tagBITMAPINFOHEADER { 366 | ;~ DWORD biSize; 0 367 | ;~ LONG biWidth; 4 368 | ;~ LONG biHeight; 8 369 | ;~ WORD biPlanes; 12 370 | ;~ WORD biBitCount; 14 371 | ;~ DWORD biCompression; 16 372 | ;~ DWORD biSizeImage; 20 373 | ;~ LONG biXPelsPerMeter; 24 374 | ;~ LONG biYPelsPerMeter; 28 375 | ;~ DWORD biClrUsed; 32 376 | ;~ DWORD biClrImportant; 36 377 | 378 | bmi := &DIB ;BITMAPINFOHEADER pointer from DIB 379 | biSize := numget( bmi+0, 0, "UInt" ) 380 | ;~ return bmi + biSize 381 | biSizeImage := numget( bmi+0, 20, "UInt" ) 382 | biBitCount := numget( bmi+0, 14, "UShort" ) 383 | if ( biSizeImage == 0 ) 384 | { 385 | biWidth := numget( bmi+0, 4, "UInt" ) 386 | biHeight := numget( bmi+0, 8, "UInt" ) 387 | biSizeImage := (((( biWidth * biBitCount + 31 ) & ~31 ) >> 3 ) * biHeight ) 388 | numput( biSizeImage, bmi+0, 20, "UInt" ) 389 | } 390 | p := numget( bmi+0, 32, "UInt" ) ;biClrUsed 391 | if ( p == 0 && biBitCount <= 8 ) 392 | p := 1 << biBitCount 393 | p := p * 4 + biSize + bmi 394 | return p 395 | } 396 | Gdip_Startup() { 397 | if !DllCall( "GetModuleHandleW", "Wstr", "gdiplus", "UPtr" ) 398 | DllCall( "LoadLibraryW", "Wstr", "gdiplus", "UPtr" ) 399 | 400 | VarSetCapacity(GdiplusStartupInput , 3*A_PtrSize, 0), NumPut(1,GdiplusStartupInput ,0,"UInt") ; GdiplusVersion = 1 401 | DllCall("gdiplus\GdiplusStartup", "Ptr*", pToken, "Ptr", &GdiplusStartupInput, "Ptr", 0) 402 | return pToken 403 | } 404 | Gdip_Shutdown(pToken) { 405 | DllCall("gdiplus\GdiplusShutdown", "Ptr", pToken) 406 | if hModule := DllCall( "GetModuleHandleW", "Wstr", "gdiplus", "UPtr" ) 407 | DllCall("FreeLibrary", "Ptr", hModule) 408 | return 0 409 | } 410 | StrSplit(str,delim,omit = "") { 411 | if (strlen(delim) > 1) 412 | { 413 | StringReplace,str,str,% delim,ƒ,1 ;■¶╬ 414 | delim = ƒ 415 | } 416 | ra := Array() 417 | loop, parse,str,% delim,% omit 418 | if (A_LoopField != "") 419 | ra.Insert(A_LoopField) 420 | return ra 421 | } 422 | RemoveDubls( objArray ) { 423 | while True 424 | { 425 | nodubls := 1 426 | tempArr := Object() 427 | for i,val in objArray 428 | { 429 | if tempArr.haskey( val ) 430 | { 431 | nodubls := 0 432 | objArray.Remove( i ) 433 | break 434 | } 435 | tempArr[ val ] := 1 436 | } 437 | if nodubls 438 | break 439 | } 440 | return objArray 441 | } 442 | RegisterClipboardFormat( fmtName ) { 443 | return DllCall( "RegisterClipboardFormat", "ptr", &fmtName ) 444 | } 445 | GetOpenClipboardWindow() { 446 | return DllCall( "GetOpenClipboardWindow" ) 447 | } 448 | IsClipboardFormatAvailable( iFmt ) { 449 | return DllCall( "IsClipboardFormatAvailable", "UInt", iFmt ) 450 | } 451 | GetImageEncodersSize( ByRef numEncoders, ByRef size ) { 452 | return DllCall( "gdiplus\GdipGetImageEncodersSize", "Uint*", numEncoders, "UInt*", size ) 453 | } 454 | GetImageEncoders( numEncoders, size, pImageCodecInfo ) { 455 | return DllCall( "gdiplus\GdipGetImageEncoders", "Uint", numEncoders, "UInt", size, "Ptr", pImageCodecInfo ) 456 | } 457 | GetEncoderClsid( format, ByRef CLSID ) { 458 | ;format should be the following 459 | ;~ bmp 460 | ;~ jpeg 461 | ;~ gif 462 | ;~ tiff 463 | ;~ png 464 | if !format 465 | return 0 466 | format := "image/" format 467 | this.GetImageEncodersSize( num, size ) 468 | if ( size = 0 ) 469 | return 0 470 | VarSetCapacity( ImageCodecInfo, size, 0 ) 471 | this.GetImageEncoders( num, size, &ImageCodecInfo ) 472 | loop,% num 473 | { 474 | pici := &ImageCodecInfo + ( 48+7*A_PtrSize )*(A_Index-1) 475 | pMime := NumGet( pici+0, 32+4*A_PtrSize, "UPtr" ) 476 | MimeType := StrGet( pMime, "UTF-16") 477 | if ( MimeType = format ) 478 | { 479 | VarSetCapacity( CLSID, 16, 0 ) 480 | this.memcopy( &CLSID, pici, 16 ) 481 | return 1 482 | } 483 | } 484 | return 0 485 | } 486 | } 487 | 488 | class WinClip extends WinClip_base 489 | { 490 | __New() 491 | { 492 | this.isinstance := 1 493 | this.allData := "" 494 | } 495 | 496 | _toclipboard( ByRef data, size ) 497 | { 498 | if !WinClipAPI.OpenClipboard() 499 | return 0 500 | offset := 0 501 | lastPartOffset := 0 502 | WinClipAPI.EmptyClipboard() 503 | while ( offset < size ) 504 | { 505 | if !( fmt := NumGet( data, offset, "UInt" ) ) 506 | break 507 | offset += 4 508 | if !( dataSize := NumGet( data, offset, "UInt" ) ) 509 | break 510 | offset += 4 511 | if ( ( offset + dataSize ) > size ) 512 | break 513 | if !( pData := WinClipAPI.GlobalLock( WinClipAPI.GlobalAlloc( 0x0042, dataSize ) ) ) 514 | { 515 | offset += dataSize 516 | continue 517 | } 518 | WinClipAPI.memcopy( pData, &data + offset, dataSize ) 519 | if ( fmt == this.ClipboardFormats.CF_ENHMETAFILE ) 520 | pClipData := WinClipAPI.SetEnhMetaFileBits( pData, dataSize ) 521 | else 522 | pClipData := pData 523 | if !pClipData 524 | continue 525 | WinClipAPI.SetClipboardData( fmt, pClipData ) 526 | if ( fmt == this.ClipboardFormats.CF_ENHMETAFILE ) 527 | WinClipAPI.DeleteEnhMetaFile( pClipData ) 528 | WinClipAPI.GlobalUnlock( pData ) 529 | offset += dataSize 530 | lastPartOffset := offset 531 | } 532 | WinClipAPI.CloseClipboard() 533 | return lastPartOffset 534 | } 535 | 536 | _fromclipboard( ByRef clipData ) 537 | { 538 | if !WinClipAPI.OpenClipboard() 539 | return 0 540 | nextformat := 0 541 | objFormats := object() 542 | clipSize := 0 543 | formatsNum := 0 544 | while ( nextformat := WinClipAPI.EnumClipboardFormats( nextformat ) ) 545 | { 546 | if this.skipFormats.hasKey( nextformat ) 547 | continue 548 | if ( dataHandle := WinClipAPI.GetClipboardData( nextformat ) ) 549 | { 550 | pObjPtr := 0, nObjSize := 0 551 | if ( nextFormat == this.ClipboardFormats.CF_ENHMETAFILE ) 552 | { 553 | if ( bufSize := WinClipAPI.GetEnhMetaFileBits( dataHandle, hemfBuf ) ) 554 | pObjPtr := &hemfBuf, nObjSize := bufSize 555 | } 556 | else if ( nSize := WinClipAPI.GlobalSize( WinClipAPI.GlobalLock( dataHandle ) ) ) 557 | pObjPtr := dataHandle, nObjSize := nSize 558 | else 559 | continue 560 | if !( pObjPtr && nObjSize ) 561 | continue 562 | objFormats[ nextformat ] := { handle : pObjPtr, size : nObjSize } 563 | clipSize += nObjSize 564 | formatsNum++ 565 | } 566 | } 567 | structSize := formatsNum*( 4 + 4 ) + clipSize ;allocating 4 bytes for format ID and 4 for data size 568 | if !structSize 569 | return 0 570 | VarSetCapacity( clipData, structSize, 0 ) 571 | ; array in form of: 572 | ; format UInt 573 | ; dataSize UInt 574 | ; data Byte[] 575 | offset := 0 576 | for fmt, params in objFormats 577 | { 578 | NumPut( fmt, &clipData, offset, "UInt" ) 579 | offset += 4 580 | NumPut( params.size, &clipData, offset, "UInt" ) 581 | offset += 4 582 | WinClipAPI.memcopy( &clipData + offset, params.handle, params.size ) 583 | offset += params.size 584 | WinClipAPI.GlobalUnlock( params.handle ) 585 | } 586 | WinClipAPI.CloseClipboard() 587 | return structSize 588 | } 589 | 590 | _IsInstance( funcName ) 591 | { 592 | if !this.isinstance 593 | { 594 | throw Exception( "Error in '" funcName "':`nInstantiate the object first to use this method!", -1 ) 595 | return 0 596 | } 597 | return 1 598 | } 599 | 600 | _loadFile( filePath, ByRef Data ) 601 | { 602 | f := FileOpen( filePath, "r","CP0" ) 603 | if !IsObject( f ) 604 | return 0 605 | f.Pos := 0 606 | dataSize := f.RawRead( Data, f.Length ) 607 | f.close() 608 | return dataSize 609 | } 610 | 611 | _saveFile( filepath, byRef data, size ) 612 | { 613 | f := FileOpen( filepath, "w","CP0" ) 614 | bytes := f.RawWrite( &data, size ) 615 | f.close() 616 | return bytes 617 | } 618 | 619 | _setClipData( ByRef data, size ) 620 | { 621 | if !size 622 | return 0 623 | if !ObjSetCapacity( this, "allData", size ) 624 | return 0 625 | if !( pData := ObjGetAddress( this, "allData" ) ) 626 | return 0 627 | WinClipAPI.memcopy( pData, &data, size ) 628 | return size 629 | } 630 | 631 | _getClipData( ByRef data ) 632 | { 633 | if !( clipSize := ObjGetCapacity( this, "allData" ) ) 634 | return 0 635 | if !( pData := ObjGetAddress( this, "allData" ) ) 636 | return 0 637 | VarSetCapacity( data, clipSize, 0 ) 638 | WinClipAPI.memcopy( &data, pData, clipSize ) 639 | return clipSize 640 | } 641 | 642 | __Delete() 643 | { 644 | ObjSetCapacity( this, "allData", 0 ) 645 | return 646 | } 647 | 648 | _parseClipboardData( ByRef data, size ) 649 | { 650 | offset := 0 651 | formats := object() 652 | while ( offset < size ) 653 | { 654 | if !( fmt := NumGet( data, offset, "UInt" ) ) 655 | break 656 | offset += 4 657 | if !( dataSize := NumGet( data, offset, "UInt" ) ) 658 | break 659 | offset += 4 660 | if ( ( offset + dataSize ) > size ) 661 | break 662 | params := { name : this._getFormatName( fmt ), size : dataSize } 663 | ObjSetCapacity( params, "buffer", dataSize ) 664 | pBuf := ObjGetAddress( params, "buffer" ) 665 | WinClipAPI.memcopy( pBuf, &data + offset, dataSize ) 666 | formats[ fmt ] := params 667 | offset += dataSize 668 | } 669 | return formats 670 | } 671 | 672 | _compileClipData( ByRef out_data, objClip ) 673 | { 674 | if !IsObject( objClip ) 675 | return 0 676 | ;calculating required data size 677 | clipSize := 0 678 | for fmt, params in objClip 679 | clipSize += 8 + params.size 680 | VarSetCapacity( out_data, clipSize, 0 ) 681 | offset := 0 682 | for fmt, params in objClip 683 | { 684 | NumPut( fmt, out_data, offset, "UInt" ) 685 | offset += 4 686 | NumPut( params.size, out_data, offset, "UInt" ) 687 | offset += 4 688 | WinClipAPI.memcopy( &out_data + offset, ObjGetAddress( params, "buffer" ), params.size ) 689 | offset += params.size 690 | } 691 | return clipSize 692 | } 693 | 694 | GetFormats() 695 | { 696 | if !( clipSize := this._fromclipboard( clipData ) ) 697 | return 0 698 | return this._parseClipboardData( clipData, clipSize ) 699 | } 700 | 701 | iGetFormats() 702 | { 703 | this._IsInstance( A_ThisFunc ) 704 | if !( clipSize := this._getClipData( clipData ) ) 705 | return 0 706 | return this._parseClipboardData( clipData, clipSize ) 707 | } 708 | 709 | Snap( ByRef data ) 710 | { 711 | return this._fromclipboard( data ) 712 | } 713 | 714 | iSnap() 715 | { 716 | this._IsInstance( A_ThisFunc ) 717 | if !( dataSize := this._fromclipboard( clipData ) ) 718 | return 0 719 | return this._setClipData( clipData, dataSize ) 720 | } 721 | 722 | Restore( ByRef clipData ) 723 | { 724 | clipSize := VarSetCapacity( clipData ) 725 | return this._toclipboard( clipData, clipSize ) 726 | } 727 | 728 | iRestore() 729 | { 730 | this._IsInstance( A_ThisFunc ) 731 | if !( clipSize := this._getClipData( clipData ) ) 732 | return 0 733 | return this._toclipboard( clipData, clipSize ) 734 | } 735 | 736 | Save( filePath ) 737 | { 738 | if !( size := this._fromclipboard( data ) ) 739 | return 0 740 | return this._saveFile( filePath, data, size ) 741 | } 742 | 743 | iSave( filePath ) 744 | { 745 | this._IsInstance( A_ThisFunc ) 746 | if !( clipSize := this._getClipData( clipData ) ) 747 | return 0 748 | return this._saveFile( filePath, clipData, clipSize ) 749 | } 750 | 751 | Load( filePath ) 752 | { 753 | if !( dataSize := this._loadFile( filePath, dataBuf ) ) 754 | return 0 755 | return this._toclipboard( dataBuf, dataSize ) 756 | } 757 | 758 | iLoad( filePath ) 759 | { 760 | this._IsInstance( A_ThisFunc ) 761 | if !( dataSize := this._loadFile( filePath, dataBuf ) ) 762 | return 0 763 | return this._setClipData( dataBuf, dataSize ) 764 | } 765 | 766 | Clear() 767 | { 768 | if !WinClipAPI.OpenClipboard() 769 | return 0 770 | WinClipAPI.EmptyClipboard() 771 | WinClipAPI.CloseClipboard() 772 | return 1 773 | } 774 | 775 | iClear() 776 | { 777 | this._IsInstance( A_ThisFunc ) 778 | ObjSetCapacity( this, "allData", 0 ) 779 | } 780 | 781 | Copy( timeout = 1, method = 1 ) 782 | { 783 | this.Snap( data ) 784 | this.Clear() ;clearing the clipboard 785 | if( method = 1 ) 786 | SendInput, ^{Ins} 787 | else 788 | SendInput, ^{vk43sc02E} ;ctrl+c 789 | ClipWait,% timeout, 1 790 | if ( ret := this._isClipEmpty() ) 791 | this.Restore( data ) 792 | return !ret 793 | } 794 | 795 | iCopy( timeout = 1, method = 1 ) 796 | { 797 | this._IsInstance( A_ThisFunc ) 798 | this.Snap( data ) 799 | this.Clear() ;clearing the clipboard 800 | if( method = 1 ) 801 | SendInput, ^{Ins} 802 | else 803 | SendInput, ^{vk43sc02E} ;ctrl+c 804 | ClipWait,% timeout, 1 805 | bytesCopied := 0 806 | if !this._isClipEmpty() 807 | { 808 | this.iClear() ;clearing the variable containing the clipboard data 809 | bytesCopied := this.iSnap() 810 | } 811 | this.Restore( data ) 812 | return bytesCopied 813 | } 814 | 815 | Paste( plainText = "", method = 1 ) 816 | { 817 | ret := 0 818 | if ( plainText != "" ) 819 | { 820 | this.Snap( data ) 821 | this.Clear() 822 | ret := this.SetText( plainText ) 823 | } 824 | if( method = 1 ) 825 | SendInput, +{Ins} 826 | else 827 | SendInput, ^{vk56sc02F} ;ctrl+v 828 | this._waitClipReady( 3000 ) 829 | if ( plainText != "" ) 830 | { 831 | this.Restore( data ) 832 | } 833 | else 834 | ret := !this._isClipEmpty() 835 | return ret 836 | } 837 | 838 | iPaste( method = 1 ) 839 | { 840 | this._IsInstance( A_ThisFunc ) 841 | this.Snap( data ) 842 | if !( bytesRestored := this.iRestore() ) 843 | return 0 844 | if( method = 1 ) 845 | SendInput, +{Ins} 846 | else 847 | SendInput, ^{vk56sc02F} ;ctrl+v 848 | this._waitClipReady( 3000 ) 849 | this.Restore( data ) 850 | return bytesRestored 851 | } 852 | 853 | IsEmpty() 854 | { 855 | return this._isClipEmpty() 856 | } 857 | 858 | iIsEmpty() 859 | { 860 | return !this.iGetSize() 861 | } 862 | 863 | _isClipEmpty() 864 | { 865 | return !WinClipAPI.CountClipboardFormats() 866 | } 867 | 868 | _waitClipReady( timeout = 10000 ) 869 | { 870 | start_time := A_TickCount 871 | sleep 100 872 | while ( WinClipAPI.GetOpenClipboardWindow() && ( A_TickCount - start_time < timeout ) ) 873 | sleep 100 874 | } 875 | 876 | iSetText( textData ) 877 | { 878 | if ( textData = "" ) 879 | return 0 880 | this._IsInstance( A_ThisFunc ) 881 | clipSize := this._getClipData( clipData ) 882 | if !( clipSize := this._appendText( clipData, clipSize, textData, 1 ) ) 883 | return 0 884 | return this._setClipData( clipData, clipSize ) 885 | } 886 | 887 | SetText( textData ) 888 | { 889 | if ( textData = "" ) 890 | return 0 891 | clipSize := this._fromclipboard( clipData ) 892 | if !( clipSize := this._appendText( clipData, clipSize, textData, 1 ) ) 893 | return 0 894 | return this._toclipboard( clipData, clipSize ) 895 | } 896 | 897 | GetRTF() 898 | { 899 | if !( clipSize := this._fromclipboard( clipData ) ) 900 | return "" 901 | if !( out_size := this._getFormatData( out_data, clipData, clipSize, "Rich Text Format" ) ) 902 | return "" 903 | return strget( &out_data, out_size, "CP0" ) 904 | } 905 | 906 | iGetRTF() 907 | { 908 | this._IsInstance( A_ThisFunc ) 909 | if !( clipSize := this._getClipData( clipData ) ) 910 | return "" 911 | if !( out_size := this._getFormatData( out_data, clipData, clipSize, "Rich Text Format" ) ) 912 | return "" 913 | return strget( &out_data, out_size, "CP0" ) 914 | } 915 | 916 | SetRTF( textData ) 917 | { 918 | if ( textData = "" ) 919 | return 0 920 | clipSize := this._fromclipboard( clipData ) 921 | if !( clipSize := this._setRTF( clipData, clipSize, textData ) ) 922 | return 0 923 | return this._toclipboard( clipData, clipSize ) 924 | } 925 | 926 | iSetRTF( textData ) 927 | { 928 | if ( textData = "" ) 929 | return 0 930 | this._IsInstance( A_ThisFunc ) 931 | clipSize := this._getClipData( clipData ) 932 | if !( clipSize := this._setRTF( clipData, clipSize, textData ) ) 933 | return 0 934 | return this._setClipData( clipData, clipSize ) 935 | } 936 | 937 | _setRTF( ByRef clipData, clipSize, textData ) 938 | { 939 | objFormats := this._parseClipboardData( clipData, clipSize ) 940 | uFmt := WinClipAPI.RegisterClipboardFormat( "Rich Text Format" ) 941 | objFormats[ uFmt ] := object() 942 | sLen := StrLen( textData ) 943 | ObjSetCapacity( objFormats[ uFmt ], "buffer", sLen ) 944 | StrPut( textData, ObjGetAddress( objFormats[ uFmt ], "buffer" ), sLen, "CP0" ) 945 | objFormats[ uFmt ].size := sLen 946 | return this._compileClipData( clipData, objFormats ) 947 | } 948 | 949 | iAppendText( textData ) 950 | { 951 | if ( textData = "" ) 952 | return 0 953 | this._IsInstance( A_ThisFunc ) 954 | clipSize := this._getClipData( clipData ) 955 | if !( clipSize := this._appendText( clipData, clipSize, textData ) ) 956 | return 0 957 | return this._setClipData( clipData, clipSize ) 958 | } 959 | 960 | AppendText( textData ) 961 | { 962 | if ( textData = "" ) 963 | return 0 964 | clipSize := this._fromclipboard( clipData ) 965 | if !( clipSize := this._appendText( clipData, clipSize, textData ) ) 966 | return 0 967 | return this._toclipboard( clipData, clipSize ) 968 | } 969 | 970 | SetHTML( html, source = "" ) 971 | { 972 | if ( html = "" ) 973 | return 0 974 | clipSize := this._fromclipboard( clipData ) 975 | if !( clipSize := this._setHTML( clipData, clipSize, html, source ) ) 976 | return 0 977 | return this._toclipboard( clipData, clipSize ) 978 | } 979 | 980 | iSetHTML( html, source = "" ) 981 | { 982 | if ( html = "" ) 983 | return 0 984 | this._IsInstance( A_ThisFunc ) 985 | clipSize := this._getClipData( clipData ) 986 | if !( clipSize := this._setHTML( clipData, clipSize, html, source ) ) 987 | return 0 988 | return this._setClipData( clipData, clipSize ) 989 | } 990 | 991 | _calcHTMLLen( num ) 992 | { 993 | while ( StrLen( num ) < 10 ) 994 | num := "0" . num 995 | return num 996 | } 997 | 998 | _setHTML( ByRef clipData, clipSize, htmlData, source ) 999 | { 1000 | objFormats := this._parseClipboardData( clipData, clipSize ) 1001 | uFmt := WinClipAPI.RegisterClipboardFormat( "HTML Format" ) 1002 | objFormats[ uFmt ] := object() 1003 | encoding := "UTF-8" 1004 | htmlLen := StrPut( htmlData, encoding ) - 1 ;substract null 1005 | srcLen := 2 + 10 + StrPut( source, encoding ) - 1 ;substract null 1006 | StartHTML := this._calcHTMLLen( 105 + srcLen ) 1007 | EndHTML := this._calcHTMLLen( StartHTML + htmlLen + 76 ) 1008 | StartFragment := this._calcHTMLLen( StartHTML + 38 ) 1009 | EndFragment := this._calcHTMLLen( StartFragment + htmlLen ) 1010 | html = 1011 | ( Join`r`n 1012 | Version:0.9 1013 | StartHTML:%StartHTML% 1014 | EndHTML:%EndHTML% 1015 | StartFragment:%StartFragment% 1016 | EndFragment:%EndFragment% 1017 | SourceURL:%source% 1018 | 1019 | 1020 | 1021 | %htmlData% 1022 | 1023 | 1024 | 1025 | ) 1026 | sLen := StrPut( html, encoding ) 1027 | ObjSetCapacity( objFormats[ uFmt ], "buffer", sLen ) 1028 | StrPut( html, ObjGetAddress( objFormats[ uFmt ], "buffer" ), sLen, encoding ) 1029 | objFormats[ uFmt ].size := sLen 1030 | return this._compileClipData( clipData, objFormats ) 1031 | } 1032 | 1033 | _appendText( ByRef clipData, clipSize, textData, IsSet = 0 ) 1034 | { 1035 | objFormats := this._parseClipboardData( clipData, clipSize ) 1036 | uFmt := this.ClipboardFormats.CF_UNICODETEXT 1037 | str := "" 1038 | if ( objFormats.haskey( uFmt ) && !IsSet ) 1039 | str := strget( ObjGetAddress( objFormats[ uFmt ], "buffer" ), "UTF-16" ) 1040 | else 1041 | objFormats[ uFmt ] := object() 1042 | str .= textData 1043 | sLen := ( StrLen( str ) + 1 ) * 2 1044 | ObjSetCapacity( objFormats[ uFmt ], "buffer", sLen ) 1045 | StrPut( str, ObjGetAddress( objFormats[ uFmt ], "buffer" ), sLen, "UTF-16" ) 1046 | objFormats[ uFmt ].size := sLen 1047 | return this._compileClipData( clipData, objFormats ) 1048 | } 1049 | 1050 | _getFiles( pDROPFILES ) 1051 | { 1052 | fWide := numget( pDROPFILES + 0, 16, "uchar" ) ;getting fWide value from DROPFILES struct 1053 | pFiles := numget( pDROPFILES + 0, 0, "UInt" ) + pDROPFILES ;getting address of files list 1054 | list := "" 1055 | while numget( pFiles + 0, 0, fWide ? "UShort" : "UChar" ) 1056 | { 1057 | lastPath := strget( pFiles+0, fWide ? "UTF-16" : "CP0" ) 1058 | list .= ( list ? "`n" : "" ) lastPath 1059 | pFiles += ( StrLen( lastPath ) + 1 ) * ( fWide ? 2 : 1 ) 1060 | } 1061 | return list 1062 | } 1063 | 1064 | _setFiles( ByRef clipData, clipSize, files, append = 0, isCut = 0 ) 1065 | { 1066 | objFormats := this._parseClipboardData( clipData, clipSize ) 1067 | uFmt := this.ClipboardFormats.CF_HDROP 1068 | if ( append && objFormats.haskey( uFmt ) ) 1069 | prevList := this._getFiles( ObjGetAddress( objFormats[ uFmt ], "buffer" ) ) "`n" 1070 | objFiles := WinClipAPI.StrSplit( prevList . files, "`n", A_Space A_Tab ) 1071 | objFiles := WinClipAPI.RemoveDubls( objFiles ) 1072 | if !objFiles.MaxIndex() 1073 | return 0 1074 | objFormats[ uFmt ] := object() 1075 | DROP_size := 20 + 2 1076 | for i,str in objFiles 1077 | DROP_size += ( StrLen( str ) + 1 ) * 2 1078 | VarSetCapacity( DROPFILES, DROP_size, 0 ) 1079 | NumPut( 20, DROPFILES, 0, "UInt" ) ;offset 1080 | NumPut( 1, DROPFILES, 16, "uchar" ) ;NumPut( 20, DROPFILES, 0, "UInt" ) 1081 | offset := &DROPFILES + 20 1082 | for i,str in objFiles 1083 | { 1084 | StrPut( str, offset, "UTF-16" ) 1085 | offset += ( StrLen( str ) + 1 ) * 2 1086 | } 1087 | ObjSetCapacity( objFormats[ uFmt ], "buffer", DROP_size ) 1088 | WinClipAPI.memcopy( ObjGetAddress( objFormats[ uFmt ], "buffer" ), &DROPFILES, DROP_size ) 1089 | objFormats[ uFmt ].size := DROP_size 1090 | prefFmt := WinClipAPI.RegisterClipboardFormat( "Preferred DropEffect" ) 1091 | objFormats[ prefFmt ] := { size : 4 } 1092 | ObjSetCapacity( objFormats[ prefFmt ], "buffer", 4 ) 1093 | NumPut( isCut ? 2 : 5, ObjGetAddress( objFormats[ prefFmt ], "buffer" ), 0 "UInt" ) 1094 | return this._compileClipData( clipData, objFormats ) 1095 | } 1096 | 1097 | SetFiles( files, isCut = 0 ) 1098 | { 1099 | if ( files = "" ) 1100 | return 0 1101 | clipSize := this._fromclipboard( clipData ) 1102 | if !( clipSize := this._setFiles( clipData, clipSize, files, 0, isCut ) ) 1103 | return 0 1104 | return this._toclipboard( clipData, clipSize ) 1105 | } 1106 | 1107 | iSetFiles( files, isCut = 0 ) 1108 | { 1109 | this._IsInstance( A_ThisFunc ) 1110 | if ( files = "" ) 1111 | return 0 1112 | clipSize := this._getClipData( clipData ) 1113 | if !( clipSize := this._setFiles( clipData, clipSize, files, 0, isCut ) ) 1114 | return 0 1115 | return this._setClipData( clipData, clipSize ) 1116 | } 1117 | 1118 | AppendFiles( files, isCut = 0 ) 1119 | { 1120 | if ( files = "" ) 1121 | return 0 1122 | clipSize := this._fromclipboard( clipData ) 1123 | if !( clipSize := this._setFiles( clipData, clipSize, files, 1, isCut ) ) 1124 | return 0 1125 | return this._toclipboard( clipData, clipSize ) 1126 | } 1127 | 1128 | iAppendFiles( files, isCut = 0 ) 1129 | { 1130 | this._IsInstance( A_ThisFunc ) 1131 | if ( files = "" ) 1132 | return 0 1133 | clipSize := this._getClipData( clipData ) 1134 | if !( clipSize := this._setFiles( clipData, clipSize, files, 1, isCut ) ) 1135 | return 0 1136 | return this._setClipData( clipData, clipSize ) 1137 | } 1138 | 1139 | GetFiles() 1140 | { 1141 | if !( clipSize := this._fromclipboard( clipData ) ) 1142 | return "" 1143 | if !( out_size := this._getFormatData( out_data, clipData, clipSize, this.ClipboardFormats.CF_HDROP ) ) 1144 | return "" 1145 | return this._getFiles( &out_data ) 1146 | } 1147 | 1148 | iGetFiles() 1149 | { 1150 | this._IsInstance( A_ThisFunc ) 1151 | if !( clipSize := this._getClipData( clipData ) ) 1152 | return "" 1153 | if !( out_size := this._getFormatData( out_data, clipData, clipSize, this.ClipboardFormats.CF_HDROP ) ) 1154 | return "" 1155 | return this._getFiles( &out_data ) 1156 | } 1157 | 1158 | _getFormatData( ByRef out_data, ByRef data, size, needleFormat ) 1159 | { 1160 | needleFormat := WinClipAPI.IsInteger( needleFormat ) ? needleFormat : WinClipAPI.RegisterClipboardFormat( needleFormat ) 1161 | if !needleFormat 1162 | return 0 1163 | offset := 0 1164 | while ( offset < size ) 1165 | { 1166 | if !( fmt := NumGet( data, offset, "UInt" ) ) 1167 | break 1168 | offset += 4 1169 | if !( dataSize := NumGet( data, offset, "UInt" ) ) 1170 | break 1171 | offset += 4 1172 | if ( fmt == needleFormat ) 1173 | { 1174 | VarSetCapacity( out_data, dataSize, 0 ) 1175 | WinClipAPI.memcopy( &out_data, &data + offset, dataSize ) 1176 | return dataSize 1177 | } 1178 | offset += dataSize 1179 | } 1180 | return 0 1181 | } 1182 | 1183 | _DIBtoHBITMAP( ByRef dibData ) 1184 | { 1185 | ;http://ebersys.blogspot.com/2009/06/how-to-convert-dib-to-bitmap.html 1186 | pPix := WinClipAPI.GetPixelInfo( dibData ) 1187 | gdip_token := WinClipAPI.Gdip_Startup() 1188 | DllCall("gdiplus\GdipCreateBitmapFromGdiDib", "Ptr", &dibData, "Ptr", pPix, "Ptr*", pBitmap ) 1189 | DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "Ptr*", hBitmap, "int", 0xffffffff ) 1190 | DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmap) 1191 | WinClipAPI.Gdip_Shutdown( gdip_token ) 1192 | return hBitmap 1193 | } 1194 | 1195 | GetBitmap() 1196 | { 1197 | if !( clipSize := this._fromclipboard( clipData ) ) 1198 | return "" 1199 | if !( out_size := this._getFormatData( out_data, clipData, clipSize, this.ClipboardFormats.CF_DIB ) ) 1200 | return "" 1201 | return this._DIBtoHBITMAP( out_data ) 1202 | } 1203 | 1204 | iGetBitmap() 1205 | { 1206 | this._IsInstance( A_ThisFunc ) 1207 | if !( clipSize := this._getClipData( clipData ) ) 1208 | return "" 1209 | if !( out_size := this._getFormatData( out_data, clipData, clipSize, this.ClipboardFormats.CF_DIB ) ) 1210 | return "" 1211 | return this._DIBtoHBITMAP( out_data ) 1212 | } 1213 | 1214 | _BITMAPtoDIB( bitmap, ByRef DIB ) 1215 | { 1216 | if !bitmap 1217 | return 0 1218 | if !WinClipAPI.IsInteger( bitmap ) 1219 | { 1220 | gdip_token := WinClipAPI.Gdip_Startup() 1221 | DllCall("gdiplus\GdipCreateBitmapFromFileICM", "wstr", bitmap, "Ptr*", pBitmap ) 1222 | DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "Ptr*", hBitmap, "int", 0xffffffff ) 1223 | DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmap) 1224 | WinClipAPI.Gdip_Shutdown( gdip_token ) 1225 | bmMade := 1 1226 | } 1227 | else 1228 | hBitmap := bitmap, bmMade := 0 1229 | if !hBitmap 1230 | return 0 1231 | ;http://www.codeguru.com/Cpp/G-M/bitmap/article.php/c1765 1232 | if !( hdc := DllCall( "GetDC", "Ptr", 0 ) ) 1233 | goto, _BITMAPtoDIB_cleanup 1234 | hPal := DllCall( "GetStockObject", "UInt", 15 ) ;DEFAULT_PALLETE 1235 | hPal := DllCall( "SelectPalette", "ptr", hdc, "ptr", hPal, "Uint", 0 ) 1236 | DllCall( "RealizePalette", "ptr", hdc ) 1237 | size := DllCall( "GetObject", "Ptr", hBitmap, "Uint", 0, "ptr", 0 ) 1238 | VarSetCapacity( bm, size, 0 ) 1239 | DllCall( "GetObject", "Ptr", hBitmap, "Uint", size, "ptr", &bm ) 1240 | biBitCount := NumGet( bm, 16, "UShort" )*NumGet( bm, 18, "UShort" ) 1241 | nColors := (1 << biBitCount) 1242 | if ( nColors > 256 ) 1243 | nColors := 0 1244 | bmiLen := 40 + nColors * 4 1245 | VarSetCapacity( bmi, bmiLen, 0 ) 1246 | ;BITMAPINFOHEADER initialization 1247 | NumPut( 40, bmi, 0, "Uint" ) 1248 | NumPut( NumGet( bm, 4, "Uint" ), bmi, 4, "Uint" ) ;width 1249 | NumPut( biHeight := NumGet( bm, 8, "Uint" ), bmi, 8, "Uint" ) ;height 1250 | NumPut( 1, bmi, 12, "UShort" ) 1251 | NumPut( biBitCount, bmi, 14, "UShort" ) 1252 | NumPut( 0, bmi, 16, "UInt" ) ;compression must be BI_RGB 1253 | 1254 | ; Get BITMAPINFO. 1255 | if !DllCall("GetDIBits" 1256 | ,"ptr",hdc 1257 | ,"ptr",hBitmap 1258 | ,"uint",0 1259 | ,"uint",biHeight 1260 | ,"ptr",0 ;lpvBits 1261 | ,"ptr",&bmi ;lpbi 1262 | ,"uint",0) ;DIB_RGB_COLORS 1263 | goto, _BITMAPtoDIB_cleanup 1264 | biSizeImage := NumGet( &bmi, 20, "UInt" ) 1265 | if ( biSizeImage = 0 ) 1266 | { 1267 | biBitCount := numget( &bmi, 14, "UShort" ) 1268 | biWidth := numget( &bmi, 4, "UInt" ) 1269 | biHeight := numget( &bmi, 8, "UInt" ) 1270 | biSizeImage := (((( biWidth * biBitCount + 31 ) & ~31 ) >> 3 ) * biHeight ) 1271 | ;~ dwCompression := numget( bmi, 16, "UInt" ) 1272 | ;~ if ( dwCompression != 0 ) ;BI_RGB 1273 | ;~ biSizeImage := ( biSizeImage * 3 ) / 2 1274 | numput( biSizeImage, &bmi, 20, "UInt" ) 1275 | } 1276 | DIBLen := bmiLen + biSizeImage 1277 | VarSetCapacity( DIB, DIBLen, 0 ) 1278 | WinClipAPI.memcopy( &DIB, &bmi, bmiLen ) 1279 | if !DllCall("GetDIBits" 1280 | ,"ptr",hdc 1281 | ,"ptr",hBitmap 1282 | ,"uint",0 1283 | ,"uint",biHeight 1284 | ,"ptr",&DIB + bmiLen ;lpvBits 1285 | ,"ptr",&DIB ;lpbi 1286 | ,"uint",0) ;DIB_RGB_COLORS 1287 | goto, _BITMAPtoDIB_cleanup 1288 | _BITMAPtoDIB_cleanup: 1289 | if bmMade 1290 | DllCall( "DeleteObject", "ptr", hBitmap ) 1291 | DllCall( "SelectPalette", "ptr", hdc, "ptr", hPal, "Uint", 0 ) 1292 | DllCall( "RealizePalette", "ptr", hdc ) 1293 | DllCall("ReleaseDC","ptr",hdc) 1294 | if ( A_ThisLabel = "_BITMAPtoDIB_cleanup" ) 1295 | return 0 1296 | return DIBLen 1297 | } 1298 | 1299 | _setBitmap( ByRef DIB, DIBSize, ByRef clipData, clipSize ) 1300 | { 1301 | objFormats := this._parseClipboardData( clipData, clipSize ) 1302 | uFmt := this.ClipboardFormats.CF_DIB 1303 | objFormats[ uFmt ] := { size : DIBSize } 1304 | ObjSetCapacity( objFormats[ uFmt ], "buffer", DIBSize ) 1305 | WinClipAPI.memcopy( ObjGetAddress( objFormats[ uFmt ], "buffer" ), &DIB, DIBSize ) 1306 | return this._compileClipData( clipData, objFormats ) 1307 | } 1308 | 1309 | SetBitmap( bitmap ) 1310 | { 1311 | if ( DIBSize := this._BITMAPtoDIB( bitmap, DIB ) ) 1312 | { 1313 | clipSize := this._fromclipboard( clipData ) 1314 | if ( clipSize := this._setBitmap( DIB, DIBSize, clipData, clipSize ) ) 1315 | return this._toclipboard( clipData, clipSize ) 1316 | } 1317 | return 0 1318 | } 1319 | 1320 | iSetBitmap( bitmap ) 1321 | { 1322 | this._IsInstance( A_ThisFunc ) 1323 | if ( DIBSize := this._BITMAPtoDIB( bitmap, DIB ) ) 1324 | { 1325 | clipSize := this._getClipData( clipData ) 1326 | if ( clipSize := this._setBitmap( DIB, DIBSize, clipData, clipSize ) ) 1327 | return this._setClipData( clipData, clipSize ) 1328 | } 1329 | return 0 1330 | } 1331 | 1332 | GetText() 1333 | { 1334 | if !( clipSize := this._fromclipboard( clipData ) ) 1335 | return "" 1336 | if !( out_size := this._getFormatData( out_data, clipData, clipSize, this.ClipboardFormats.CF_UNICODETEXT ) ) 1337 | return "" 1338 | return strget( &out_data, out_size, "UTF-16" ) 1339 | } 1340 | 1341 | iGetText() 1342 | { 1343 | this._IsInstance( A_ThisFunc ) 1344 | if !( clipSize := this._getClipData( clipData ) ) 1345 | return "" 1346 | if !( out_size := this._getFormatData( out_data, clipData, clipSize, this.ClipboardFormats.CF_UNICODETEXT ) ) 1347 | return "" 1348 | return strget( &out_data, out_size, "UTF-16" ) 1349 | } 1350 | 1351 | GetHtml() 1352 | { 1353 | if !( clipSize := this._fromclipboard( clipData ) ) 1354 | return "" 1355 | if !( out_size := this._getFormatData( out_data, clipData, clipSize, "HTML Format" ) ) 1356 | return "" 1357 | return strget( &out_data, out_size, "CP0" ) 1358 | } 1359 | 1360 | iGetHtml() 1361 | { 1362 | this._IsInstance( A_ThisFunc ) 1363 | if !( clipSize := this._getClipData( clipData ) ) 1364 | return "" 1365 | if !( out_size := this._getFormatData( out_data, clipData, clipSize, "HTML Format" ) ) 1366 | return "" 1367 | return strget( &out_data, out_size, "CP0" ) 1368 | } 1369 | 1370 | _getFormatName( iformat ) 1371 | { 1372 | if this.formatByValue.HasKey( iformat ) 1373 | return this.formatByValue[ iformat ] 1374 | else 1375 | return WinClipAPI.GetClipboardFormatName( iformat ) 1376 | } 1377 | 1378 | iGetData( ByRef Data ) 1379 | { 1380 | this._IsInstance( A_ThisFunc ) 1381 | return this._getClipData( Data ) 1382 | } 1383 | 1384 | iSetData( ByRef data ) 1385 | { 1386 | this._IsInstance( A_ThisFunc ) 1387 | return this._setClipData( data, VarSetCapacity( data ) ) 1388 | } 1389 | 1390 | iGetSize() 1391 | { 1392 | this._IsInstance( A_ThisFunc ) 1393 | return ObjGetCapacity( this, "alldata" ) 1394 | } 1395 | 1396 | HasFormat( fmt ) 1397 | { 1398 | if !fmt 1399 | return 0 1400 | return WinClipAPI.IsClipboardFormatAvailable( WinClipAPI.IsInteger( fmt ) ? fmt 1401 | : WinClipAPI.RegisterClipboardFormat( fmt ) ) 1402 | } 1403 | 1404 | iHasFormat( fmt ) 1405 | { 1406 | this._IsInstance( A_ThisFunc ) 1407 | if !( clipSize := this._getClipData( clipData ) ) 1408 | return 0 1409 | return this._hasFormat( clipData, clipSize, fmt ) 1410 | } 1411 | 1412 | _hasFormat( ByRef data, size, needleFormat ) 1413 | { 1414 | needleFormat := WinClipAPI.IsInteger( needleFormat ) ? needleFormat 1415 | : WinClipAPI.RegisterClipboardFormat( needleFormat ) 1416 | if !needleFormat 1417 | return 0 1418 | offset := 0 1419 | while ( offset < size ) 1420 | { 1421 | if !( fmt := NumGet( data, offset, "UInt" ) ) 1422 | break 1423 | if ( fmt == needleFormat ) 1424 | return 1 1425 | offset += 4 1426 | if !( dataSize := NumGet( data, offset, "UInt" ) ) 1427 | break 1428 | offset += 4 + dataSize 1429 | } 1430 | return 0 1431 | } 1432 | 1433 | iSaveBitmap( filePath, format ) 1434 | { 1435 | this._IsInstance( A_ThisFunc ) 1436 | if ( filePath = "" || format = "" ) 1437 | return 0 1438 | if !( clipSize := this._getClipData( clipData ) ) 1439 | return 0 1440 | if !( DIBsize := this._getFormatData( DIB, clipData, clipSize, this.ClipboardFormats.CF_DIB ) ) 1441 | return 0 1442 | gdip_token := WinClipAPI.Gdip_Startup() 1443 | if !WinClipAPI.GetEncoderClsid( format, CLSID ) 1444 | return 0 1445 | DllCall("gdiplus\GdipCreateBitmapFromGdiDib", "Ptr", &DIB, "Ptr", WinClipAPI.GetPixelInfo( DIB ), "Ptr*", pBitmap ) 1446 | DllCall("gdiplus\GdipSaveImageToFile", "Ptr", pBitmap, "wstr", filePath, "Ptr", &CLSID, "Ptr", 0 ) 1447 | DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmap) 1448 | WinClipAPI.Gdip_Shutdown( gdip_token ) 1449 | return 1 1450 | } 1451 | 1452 | SaveBitmap( filePath, format ) 1453 | { 1454 | if ( filePath = "" || format = "" ) 1455 | return 0 1456 | if !( clipSize := this._fromclipboard( clipData ) ) 1457 | return 0 1458 | if !( DIBsize := this._getFormatData( DIB, clipData, clipSize, this.ClipboardFormats.CF_DIB ) ) 1459 | return 0 1460 | gdip_token := WinClipAPI.Gdip_Startup() 1461 | if !WinClipAPI.GetEncoderClsid( format, CLSID ) 1462 | return 0 1463 | DllCall("gdiplus\GdipCreateBitmapFromGdiDib", "Ptr", &DIB, "Ptr", WinClipAPI.GetPixelInfo( DIB ), "Ptr*", pBitmap ) 1464 | DllCall("gdiplus\GdipSaveImageToFile", "Ptr", pBitmap, "wstr", filePath, "Ptr", &CLSID, "Ptr", 0 ) 1465 | DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmap) 1466 | WinClipAPI.Gdip_Shutdown( gdip_token ) 1467 | return 1 1468 | } 1469 | 1470 | static ClipboardFormats := { CF_BITMAP : 2 ;A handle to a bitmap (HBITMAP). 1471 | ,CF_DIB : 8 ;A memory object containing a BITMAPINFO structure followed by the bitmap bits. 1472 | ,CF_DIBV5 : 17 ;A memory object containing a BITMAPV5HEADER structure followed by the bitmap color space information and the bitmap bits. 1473 | ,CF_DIF : 5 ;Software Arts' Data Interchange Format. 1474 | ,CF_DSPBITMAP : 0x0082 ;Bitmap display format associated with a private format. The hMem parameter must be a handle to data that can be displayed in bitmap format in lieu of the privately formatted data. 1475 | ,CF_DSPENHMETAFILE : 0x008E ;Enhanced metafile display format associated with a private format. The hMem parameter must be a handle to data that can be displayed in enhanced metafile format in lieu of the privately formatted data. 1476 | ,CF_DSPMETAFILEPICT : 0x0083 ;Metafile-picture display format associated with a private format. The hMem parameter must be a handle to data that can be displayed in metafile-picture format in lieu of the privately formatted data. 1477 | ,CF_DSPTEXT : 0x0081 ;Text display format associated with a private format. The hMem parameter must be a handle to data that can be displayed in text format in lieu of the privately formatted data. 1478 | ,CF_ENHMETAFILE : 14 ;A handle to an enhanced metafile (HENHMETAFILE). 1479 | ,CF_GDIOBJFIRST : 0x0300 ;Start of a range of integer values for application-defined GDI object clipboard formats. The end of the range is CF_GDIOBJLAST.Handles associated with clipboard formats in this range are not automatically deleted using the GlobalFree function when the clipboard is emptied. Also, when using values in this range, the hMem parameter is not a handle to a GDI object, but is a handle allocated by the GlobalAlloc function with the GMEM_MOVEABLE flag. 1480 | ,CF_GDIOBJLAST : 0x03FF ;See CF_GDIOBJFIRST. 1481 | ,CF_HDROP : 15 ;A handle to type HDROP that identifies a list of files. An application can retrieve information about the files by passing the handle to the DragQueryFile function. 1482 | ,CF_LOCALE : 16 ;The data is a handle to the locale identifier associated with text in the clipboard. When you close the clipboard, if it contains CF_TEXT data but no CF_LOCALE data, the system automatically sets the CF_LOCALE format to the current input language. You can use the CF_LOCALE format to associate a different locale with the clipboard text. An application that pastes text from the clipboard can retrieve this format to determine which character set was used to generate the text. Note that the clipboard does not support plain text in multiple character sets. To achieve this, use a formatted text data type such as RTF instead. The system uses the code page associated with CF_LOCALE to implicitly convert from CF_TEXT to CF_UNICODETEXT. Therefore, the correct code page table is used for the conversion. 1483 | ,CF_METAFILEPICT : 3 ;Handle to a metafile picture format as defined by the METAFILEPICT structure. When passing a CF_METAFILEPICT handle by means of DDE, the application responsible for deleting hMem should also free the metafile referred to by the CF_METAFILEPICT handle. 1484 | ,CF_OEMTEXT : 7 ;Text format containing characters in the OEM character set. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data. 1485 | ,CF_OWNERDISPLAY : 0x0080 ;Owner-display format. The clipboard owner must display and update the clipboard viewer window, and receive the WM_ASKCBFORMATNAME, WM_HSCROLLCLIPBOARD, WM_PAINTCLIPBOARD, WM_SIZECLIPBOARD, and WM_VSCROLLCLIPBOARD messages. The hMem parameter must be NULL. 1486 | ,CF_PALETTE : 9 ;Handle to a color palette. Whenever an application places data in the clipboard that depends on or assumes a color palette, it should place the palette on the clipboard as well.If the clipboard contains data in the CF_PALETTE (logical color palette) format, the application should use the SelectPalette and RealizePalette functions to realize (compare) any other data in the clipboard against that logical palette.When displaying clipboard data, the clipboard always uses as its current palette any object on the clipboard that is in the CF_PALETTE format. 1487 | ,CF_PENDATA : 10 ;Data for the pen extensions to the Microsoft Windows for Pen Computing. 1488 | ,CF_PRIVATEFIRST : 0x0200 ;Start of a range of integer values for private clipboard formats. The range ends with CF_PRIVATELAST. Handles associated with private clipboard formats are not freed automatically; the clipboard owner must free such handles, typically in response to the WM_DESTROYCLIPBOARD message. 1489 | ,CF_PRIVATELAST : 0x02FF ;See CF_PRIVATEFIRST. 1490 | ,CF_RIFF : 11 ;Represents audio data more complex than can be represented in a CF_WAVE standard wave format. 1491 | ,CF_SYLK : 4 ;Microsoft Symbolic Link (SYLK) format. 1492 | ,CF_TEXT : 1 ;Text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data. Use this format for ANSI text. 1493 | ,CF_TIFF : 6 ;Tagged-image file format. 1494 | ,CF_UNICODETEXT : 13 ;Unicode text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data. 1495 | ,CF_WAVE : 12 } ;Represents audio data in one of the standard wave formats, such as 11 kHz or 22 kHz PCM. 1496 | 1497 | static WM_COPY := 0x301 1498 | ,WM_CLEAR := 0x0303 1499 | ,WM_CUT := 0x0300 1500 | ,WM_PASTE := 0x0302 1501 | 1502 | static skipFormats := { 2 : 0 ;"CF_BITMAP" 1503 | ,17 : 0 ;"CF_DIBV5" 1504 | ,0x0082 : 0 ;"CF_DSPBITMAP" 1505 | ,0x008E : 0 ;"CF_DSPENHMETAFILE" 1506 | ,0x0083 : 0 ;"CF_DSPMETAFILEPICT" 1507 | ,0x0081 : 0 ;"CF_DSPTEXT" 1508 | ,0x0080 : 0 ;"CF_OWNERDISPLAY" 1509 | ,3 : 0 ;"CF_METAFILEPICT" 1510 | ,7 : 0 ;"CF_OEMTEXT" 1511 | ,1 : 0 } ;"CF_TEXT" 1512 | 1513 | static formatByValue := { 2 : "CF_BITMAP" 1514 | ,8 : "CF_DIB" 1515 | ,17 : "CF_DIBV5" 1516 | ,5 : "CF_DIF" 1517 | ,0x0082 : "CF_DSPBITMAP" 1518 | ,0x008E : "CF_DSPENHMETAFILE" 1519 | ,0x0083 : "CF_DSPMETAFILEPICT" 1520 | ,0x0081 : "CF_DSPTEXT" 1521 | ,14 : "CF_ENHMETAFILE" 1522 | ,0x0300 : "CF_GDIOBJFIRST" 1523 | ,0x03FF : "CF_GDIOBJLAST" 1524 | ,15 : "CF_HDROP" 1525 | ,16 : "CF_LOCALE" 1526 | ,3 : "CF_METAFILEPICT" 1527 | ,7 : "CF_OEMTEXT" 1528 | ,0x0080 : "CF_OWNERDISPLAY" 1529 | ,9 : "CF_PALETTE" 1530 | ,10 : "CF_PENDATA" 1531 | ,0x0200 : "CF_PRIVATEFIRST" 1532 | ,0x02FF : "CF_PRIVATELAST" 1533 | ,11 : "CF_RIFF" 1534 | ,4 : "CF_SYLK" 1535 | ,1 : "CF_TEXT" 1536 | ,6 : "CF_TIFF" 1537 | ,13 : "CF_UNICODETEXT" 1538 | ,12 : "CF_WAVE" } 1539 | } 1540 | 1541 | 1542 | ;---- 将后面的函数附加到自己的脚本中 ---- 1543 | 1544 | 1545 | ;----------------------------------------- 1546 | ; 查找屏幕文字/图像字库及OCR识别 1547 | ; 注意:参数中的x、y为中心点坐标,w、h为左右上下偏移 1548 | ; cha1、cha0分别为0、_字符的容许误差百分比 1549 | ;----------------------------------------- 1550 | 查找文字(x,y,w,h,wz,c,ByRef rx="",ByRef ry="",ByRef ocr="" 1551 | , cha1=0, cha0=0) 1552 | { 1553 | xywh2xywh(x-w,y-h,2*w+1,2*h+1,x,y,w,h) 1554 | if (w<1 or h<1) 1555 | Return, 0 1556 | bch:=A_BatchLines 1557 | SetBatchLines, -1 1558 | ;-------------------------------------- 1559 | GetBitsFromScreen(x,y,w,h,Scan0,Stride,bits) 1560 | ;-------------------------------------- 1561 | ; 设定图内查找范围,注意不要越界 1562 | sx:=0, sy:=0, sw:=w, sh:=h 1563 | if PicOCR(Scan0,Stride,sx,sy,sw,sh,wz,c 1564 | ,rx,ry,ocr,cha1,cha0) 1565 | { 1566 | rx+=x, ry+=y 1567 | SetBatchLines, %bch% 1568 | Return, 1 1569 | } 1570 | ; 容差为0的若失败则使用 5% 的容差再找一次 1571 | if (cha1=0 and cha0=0) 1572 | and PicOCR(Scan0,Stride,sx,sy,sw,sh,wz,c 1573 | ,rx,ry,ocr,0.05,0.05) 1574 | { 1575 | rx+=x, ry+=y 1576 | SetBatchLines, %bch% 1577 | Return, 1 1578 | } 1579 | SetBatchLines, %bch% 1580 | Return, 0 1581 | } 1582 | 1583 | ;-- 规范输入范围在屏幕范围内 1584 | xywh2xywh(x1,y1,w1,h1,ByRef x,ByRef y,ByRef w,ByRef h) 1585 | { 1586 | ; 获取包含所有显示器的虚拟屏幕范围 1587 | SysGet, zx, 76 1588 | SysGet, zy, 77 1589 | SysGet, zw, 78 1590 | SysGet, zh, 79 1591 | left:=x1, right:=x1+w1-1, up:=y1, down:=y1+h1-1 1592 | left:=left