鼠标划选截图简单示例

鼠标划选截图简单示例

#NoEnv
#MaxMem 2048
#SingleInstance, Force
SetBatchLines, -1
Process, Priority,, High
#MaxThreadsPerHotkey 100
#MaxHotkeysPerInterval 400
#Persistent

MsgBox,4096,,F1键触发划选截图!!!

$F1::
	HighlightOutline:=New DrawHighlightOutline("e81010",3)
Return

class DrawHighlightOutline {
	__New(Color:="e81010",Border:=5){
		TrayTip,截图提示,鼠标划选进行截图!,,1
		this.Click:={},this.Pos:=[]
		this.CreateScreenTemplate()
		#InstallMouseHook
		CoordMode,Mouse,Screen
		this.SetSystemCursor("IDC_Cross")
		KeyWait,LButton,D
		MouseGetPos,xpos_init,ypos_init
		Loop
		{
			if GetKeyState("LButton","P"){
				MouseGetPos,xpos,ypos,id
				if Abs(xpos-xpos_init)&&Abs(ypos-ypos_init){
					this.Draw(xpos_init,ypos_init,Abs(xpos-xpos_init),Abs(ypos-ypos_init),Color,Border)
					this.Click.copy.1:=xpos_init+this.Click.copy.1,this.Click.copy.2:=ypos_init+this.Click.copy.2
					this.Click.save.1:=xpos_init+this.Click.save.1,this.Click.save.2:=ypos_init+this.Click.save.2
				}
			}Else if GetKeyState("RButton","P"){
				this.__Delete()
				Break
			}Else if !GetKeyState("LButton","P") {
				this.RestoreCursors()
				DllCall("DestroyWindow", "ptr", this.Template)
				this.MCallback := RegisterCallback("OutlineMouseHookProc",,3)
				this.mhk:=this.SetWindowsHookEx(WH_MOUSE:= 7, this.MCallback, 0, DllCall("GetCurrentThreadId"))
				Break
			}
		}
	}

	__Delete(){
		this.UnhookWindowsHookEx(this.mhk)
		DllCall("CoUninitialize")
		DllCall("GlobalFree", "Ptr", this.MCallback)
		this.RestoreCursors()
		DllCall("DestroyWindow", "ptr", this.Template)
		DllCall("DestroyWindow", "ptr", this.HWND)
		this.MCallback:="",this.mhk:=0
	}

	SetWindowsHookEx(idHook, lpfn, hMod, dwthreadId) {
		return DllCall("SetWindowsHookEx", "Int", idHook, "Ptr", lpfn, "Ptr", hMod, "UInt", dwthreadId)
	}

	UnhookWindowsHookEx(hhk) {
		return DllCall("UnhookWindowsHookEx", "Ptr", hhk)
	}

	GetLastError() {
		return DllCall("GetLastError")
	}

	SaveToClipboard(){
		this.__Delete()
		if pBitmap:=this.ShotFromScreen() {
			this.SaveBitmapToClipboard(pBitmap)
			DllCall("gdiplus\GdipDisposeImage", "UPtr", pBitmap),this.Pos=""
		}
	}

	SaveToFile(){
		this.__Delete()
		if pBitmap:=this.ShotFromScreen() {
			Gui,+OwnDialogs
			FileSelectFolder, filepath, , 3,选择一个目录保存图片文件
			if (filepath<>""){
				this.SaveBitmapToFile(pBitmap,filepath "\" A_Now ".png")
				DllCall("gdiplus\GdipDisposeImage", "UPtr", pBitmap)
			}
		}
		this.UnhookWindowsHookEx(this.mhk)

	}

	Draw(xpos:="",ypos:="",width:="",height:="",Color:="e81010",Border:=5){
		this.Click:={},this.Pos:=[]
		if (xpos=""||ypos=""||width=""||height=""){
			Return
		}
		if !DllCall("GetModuleHandle", "str", "gdiplus", "UPtr")
			DllCall("LoadLibrary", "str", "gdiplus")
		VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
		DllCall("gdiplus\GdiplusStartup", "UPtr*", CSTToken, "UPtr", &si, "UPtr", 0)
		If !CSTToken {
			MsgBox, 48, gdiplus error!, Gdiplus加载失败!
			Return
		}
		Gui, Outline: -Caption +E0x8080088 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +hwndhOutline
		Gui, Outline: Show, NA
		this.HWND:=hOutline,hdc2 := DllCall("GetDC", "UPtr", 0),VarSetCapacity(bi, 40, 0)
		NumPut(40, bi, 0, "uint"),NumPut(width+Border*2, bi, 4, "uint")
		NumPut(height+Border*2, bi, 8, "uint"),NumPut(1, bi, 12, "ushort")
		NumPut(32, bi, 14, "ushort"),NumPut(0, bi, 16, "uInt")
		hbm := DllCall("CreateDIBSection", "UPtr", hdc2, "UPtr", &bi	 ; BITMAPINFO
			, "uint", 0, "UPtr*", 0, "UPtr", 0, "uint", 0, "UPtr")
		DllCall("ReleaseDC", "UPtr", 0, "UPtr", hdc2), hdc := DllCall("CreateCompatibleDC", "UPtr", 0)
		obm := DllCall("SelectObject", "UPtr", hdc, "UPtr", hbm)
		DllCall("gdiplus\GdipCreateFromHDC", "UPtr", hdc, "UPtr*", G)
		DllCall("gdiplus\GdipSetSmoothingMode", "UPtr", G, "int", 2)
		, DllCall("gdiplus\GdipCreateSolidFill", "UInt", "0x" SubStr("00" Color, -7), "UPtr*", pBrush)
		this.FillRoundedRectangle(G, pBrush, 0, 0, Width+Border*2, Height+Border*2, 0)
		DllCall("gdiplus\GdipCreatePen1", "UInt", "0x" SubStr("ff" Color, -7), "float", Border, "int", Unit, "UPtr*", pPen)
		, this.DrawRoundedRectangle(G, pPen, 0, 0, Width+Border*2, Height+Border*2, 0)
		this.Geticobase64list(),DllCall("gdiplus\GdipCreateSolidFill", "UInt", 0xeeffffff, "UPtr*", pBrush)
		this.FillRoundedRectangle(G, pBrush, width+Border*2-86, height+Border*2-40, 84, 38, 0)
		DllCall("gdiplus\GdipDrawImageRectRect", "UPtr", G, "UPtr", this.icon.save, "float", width+Border*2-82, "float", height+Border*2-36
			, "float", 32, "float", 32, "float", 0, "float", 0, "float", 64, "float", 64, "int", 2
			, "UPtr", 0, "UPtr", 0, "UPtr", 0)
		DllCall("gdiplus\GdipDrawImageRectRect", "UPtr", G, "UPtr", this.icon.copy, "float", width+Border*2-36, "float", height+Border*2-36
			, "float", 32, "float", 32, "float", 0, "float", 0, "float", 64, "float", 64, "int", 2
			, "UPtr", 0, "UPtr", 0, "UPtr", 0)
		DllCall("gdiplus\GdipCreatePen1", "UInt", "0x" SubStr("ff" Color, -7), "float", Border/3, "int", 2, "UPtr*", pPen)
		, this.DrawRoundedRectangle(G, pPen, width+Border*2-86, height+Border*2-40, 86, 40, 0)
		DllCall("gdiplus\GdipDrawLine", "UPtr", G, "UPtr", pPen
			, "float", width+Border*2-41, "float", height+Border*2-40
			, "float", width+Border*2-41, "float", height+Border*2)
		this.UpdateLayeredWindow(this.HWND, hdc, xpos-Border, ypos-Border, Width+Border*2, Height+Border*2), DllCall("gdiplus\GdipDeletePen", "UPtr", pPen)
		DllCall("gdiplus\GdipDeleteGraphics", "UPtr", G), DllCall("SelectObject", "UPtr", hdc, "UPtr", obm), DllCall("DeleteObject", "UPtr", hbm)
		, DllCall("DeleteDC", "UPtr", hdc), DllCall("gdiplus\GdipDeleteBrush", "UPtr",pBrush)
		this.Pos:=WinExist("ahk_id " this.HWND)?[xpos,ypos,width,height]:[]
		this.Click.copy:=[width+Border*2-36,height+Border*2-36,32,32],this.Click.save:=[width+Border*2-82,height+Border*2-36,32,32]
	}

	;;创建一个不可移动的透明窗口限制其它操作
	CreateScreenTemplate(){
		if !DllCall("GetModuleHandle", "str", "gdiplus", "UPtr")
			DllCall("LoadLibrary", "str", "gdiplus")
		VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
		DllCall("gdiplus\GdiplusStartup", "UPtr*", CSTToken, "UPtr", &si, "UPtr", 0)
		If !CSTToken
		{
			MsgBox, 48, gdiplus error!, Gdiplus加载失败!
			Return
		}
		Gui, Template: -Caption +E0x8080088 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +hwndhScreenTemplate
		Gui, Template: Show, NA
		hdc2 := hdc ? hdc : DllCall("GetDC", "UPtr", 0)
		VarSetCapacity(bi, 40, 0),NumPut(40, bi, 0, "uint")
		NumPut(A_ScreenWidth, bi, 4, "uint"),NumPut(A_ScreenHeight, bi, 8, "uint")
		NumPut(1, bi, 12, "ushort"),NumPut(32, bi, 14, "ushort")
		NumPut(0, bi, 16, "uInt")
		hbm := DllCall("CreateDIBSection", "UPtr", hdc2, "UPtr", &bi, "uint", 0
			, "UPtr*", 0, "UPtr", 0, "uint", 0, "UPtr")
		hdc := DllCall("CreateCompatibleDC", "UPtr", 0)
		obm := DllCall("SelectObject", "UPtr", hdc, "UPtr", hbm), DllCall("gdiplus\GdipCreateFromHDC", "UPtr", hdc, "UPtr*", G)
		DllCall("gdiplus\GdipSetSmoothingMode", "UPtr", G, "int", 2)
		DllCall("gdiplus\GdipCreateSolidFill", "UInt", 0x21000000, "UPtr*", pBrush)
		DllCall("gdiplus\GdipCreateRegion", "UInt*", Region)
		if DllCall("gdiplus\GdipGetClip", "UPtr", G, "UInt", Region)
			Return
		DllCall("gdiplus\GdipSetClipRect", "UPtr", G, "float", 0, "float", 0, "float", 0, "float", 0, "int", 4)
		DllCall("gdiplus\GdipSetClipRect", "UPtr", G, "float", A_ScreenWidth, "float", 0, "float", 0, "float", 0, "int", 4)
		DllCall("gdiplus\GdipSetClipRect", "UPtr", G, "float", 0, "float", A_ScreenHeight, "float", 0, "float", 0, "int", 4)
		DllCall("gdiplus\GdipSetClipRect", "UPtr", G, "float", A_ScreenWidth, "float", A_ScreenHeight, "float", 0, "float", 0, "int", 4)
		_E := DllCall("gdiplus\GdipFillRectangle", "UPtr", G, "UPtr", pBrush
			, "float", 0, "float", 0, "float", A_ScreenWidth, "float", A_ScreenHeight)
		DllCall("gdiplus\GdipSetClipRegion", "UPtr", G, "UPtr", Region, "int", 0)
		DllCall("gdiplus\GdipSetClipRect", "UPtr", G, "float", 0, "float", 0, "float", A_ScreenWidth, "float", A_ScreenHeight, "int", 4)
		DllCall("gdiplus\GdipSetClipRect", "UPtr", G, "float", 0, "float", 0, "float", A_ScreenWidth, "float", A_ScreenHeight, "int", 4)
		DllCall("gdiplus\GdipFillEllipse", "UPtr", G, "UPtr", pBrush, "float", 0, "float", 0, "float", 0, "float", 0)
		DllCall("gdiplus\GdipFillEllipse", "UPtr", G, "UPtr", pBrush, "float", A_ScreenWidth, "float", 0, "float", 0, "float", 0)
		DllCall("gdiplus\GdipFillEllipse", "UPtr", G, "UPtr", pBrush, "float", 0, "float", A_ScreenHeight, "float", 0, "float", 0)
		DllCall("gdiplus\GdipFillEllipse", "UPtr", G, "UPtr", pBrush, "float", A_ScreenWidth, "float", A_ScreenHeight, "float", 0, "float", 0)
		DllCall("gdiplus\GdipSetClipRegion", "UPtr", G, "UPtr", Region, "int", 0)
		DllCall("gdiplus\GdipDeleteRegion", "UPtr", Region)
		VarSetCapacity(pt, 8), NumPut(0, pt, 0, "UInt"), NumPut(0, pt, 4, "UInt")
		DllCall("UpdateLayeredWindow", "UPtr", hScreenTemplate, "UPtr", 0
			, "UPtr", &pt, "int64*", A_ScreenWidth|A_ScreenHeight<<32, "UPtr", hdc
			, "int64*", 0, "uint", 0, "UInt*", 255<<16|1<<24, "uint", 2)
		DllCall("gdiplus\GdipDeleteGraphics", "UPtr", G), DllCall("SelectObject", "UPtr", hdc, "UPtr", obm)
		DllCall("DeleteObject", "UPtr", hbm), DllCall("GetDC", "UPtr", hdc), DllCall("gdiplus\GdipDeleteBrush", "UPtr", pBrush)
		this.Template:=hScreenTemplate
		Return hScreenTemplate
	}

	Geticobase64list(){
		Static Base64_copy:="iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNS"
			. "R0IArs4c6QAAAqpJREFUeF7tmz9rlEEQxn/3DVKm0CKNVmljoQFT2AgB"
			. "U8fCgARTpDDYpFI7IQSC6ZIigkJAi6BgEwQDITZaRSwFCz+DIiqGgbuw"
			. "We9y++/e2+FmmxSZnd159pl5Z2fnWoz4aI24/RgAxoAyCLwA5suoStZy"
			. "ADwG5G/wKOECj4CHwSsOVlCMn4lZogQA74HrMYsOWDbKpijhHhs3ADwG"
			. "RPthJiPkANwRdahRwoEMEAAkLjQxxPUMAGPAgF1AaLYCzDbB6XPW2AX2"
			. "gFeOTCMuUFOUfwYsNA3AvyGfvLu8n+g0wgADwGNAVKqZyR45YTfNroIB"
			. "AkDUhSMDBP+eYQB4l52hxABjgLmAxQALgv5XYByYy4j2f4GtLvNVfAUm"
			. "geMM4ztTPwJXgd+OLhUAPAduFwBAVDwA1rUBcAfYKQTAFCBM6AwVDJDN"
			. "LgGLwK8EIK4Ah+2Tf+3NVwNAgt1BUwwAuwzZbdCuwyrqATfatbqfQaHt"
			. "f6E/wFPgi8avwE3gbaLh/rQJ4Ju2PEBK1bcKAeC/Kqn4DAr99wsBcBH4"
			. "ro0Bst/pdgz4kQiExIBN4KvGGJBoc9A0FS4QZEmikAFgqbClwjpS4fvA"
			. "PeAS8DnS36Wk9glYA15q/ArcBbYjje4lLjXBD9ryACmHSVmsxBAmbWgD"
			. "4DLwDriQicARcE2jC8iexzLvA/IuINVlf3TLA3wZv0kzqvMtRNhvkBjm"
			. "42gIyUJsOtUTImwAeLDXzIDoJk1tDJA3Sfdd0t2/VJPcFroQdwn6xUhN"
			. "LhDdDt8PBY0MKNqkVTsAUhF2G6+rYUA/ZpX6f782uex1UhiQvWiGgioY"
			. "kLH/7KlDAeBNBZ3iHeRWgSfZMDoKQlxAxOXVZrnkwgm6pFNcEh334SRB"
			. "zdkpoQBkL1SrAgOg1pNpal8jz4ATg6QNUOViD+cAAAAASUVORK5CYII="

		Static Base64_save:="iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IA"
			. "rs4c6QAAAxBJREFUeF7tm83LT0EUxz/PH2AhKztZsGCFlRUbiaJEKYryVkSx"
			. "s8JGVhRR3jceSmwohcLGgrCjLGwopdjYsEKn7i2ueb8zd+b3uzP19CzuvJzv"
			. "Z86ZO3fO/GYYeZkZuX4qgOoBZgLHgUXA/E61E8CzDPCeKsZ8DJwMtcUUAr8N"
			. "na42AJgLLAs06BegEtl2p7NpF3AtZEwdAJn5YwEAtgK3Qgz5q43M6Ebgh6If"
			. "06SsBx74jq0DcBfY5AlgDvDd1wBN/XPAIU8A34C1wCsfG3QAxA1XeQJYCTz3"
			. "GdxQ9w2w3BOAVH8LrAM+utoxbQBE9xNAwuGnC4RpBCC6bwLbxgxAtJ8Bjtgg"
			. "TKsHtLqPAqdMEKYdgGjfDVzVQRgDANG+AbivgjAWAF+azdWLLoSxABDd8u0i"
			. "W/h/SgWgWRwmdSdoWvCTe8A84Kvtvev4/AqwJ2ArnBVA+8q57ChSV+1ls5VV"
			. "wTR9DdqGTe4BrQELgRU2azTP5TzgjqHtRAAI1O7UrBgAciQmhyZDlp3A9R4D"
			. "Rg2BHnZka1oBxNwIZZvGHgNXD6geEPFbQDwxV3JEFwU7AHlT6ErUENgOzPaI"
			. "x1RNzwIHNZ1HBVBqUlWO8nWZpQog5iJYPSBVEPfst4ZAzjVA6JvyiSGTK19/"
			. "Em7d/5+BS4oOs3mA6fUTItyljQDY16mYDUCf73QXsbo63cU4G4DTwOE+SgLa"
			. "FuUBYv+C5i9Ai3eTT8CHktYAbwWJGmQLgUR6vLutAHLuA7ynK0GD6gG5PECO"
			. "yDcDSxLMqqpLuQ0mCZTu0Xw2D7AlU1NwEQhLS9kJ3ga2pFBp6PO1IgWXzQNE"
			. "vFxQlM3QEOUd8BC4V4oHDCHaZYxsHuBi3BB1BgMgq724YWlFrsTp7idEPRTN"
			. "kR22wZb153yzFqnqRgXQDpDjVyM6ELbTqCQAbLNS0nMvABeBvSVZH8EW1QGK"
			. "9mdz+5t4ijBuMV0cAC50rTElOG643rkvRqLeEMljSj7zv2LL8KwBFgNyB3AS"
			. "i/yO6D3wSGe8DcAkivayuQLwwjWFlUfvAX8AMZT1QR6Q4msAAAAASUVORK5C"
			. "YII="
		this.icon:={}
		this.icon.copy:=this.BitmapFromBase64(Base64_copy)
		this.icon.save:=this.BitmapFromBase64(Base64_save)
	}

	ShotFromScreen(Screen:=""){
		if !IsObject(Screen)&&!IsObject(this.Pos){
			Return False
		}Else{
			if objlength(Screen) {
				if ((Screen[1]+Screen[2]+Screen[3]+Screen[4])<=0||(Screen[1]+Screen[2]+Screen[3]+Screen[4])=""){
					this.Pos:=[0,0,A_ScreenWidth,A_ScreenHeight]
				}Else{
					this.Pos:=Screen
				}
			}
		}
		chdc := DllCall("CreateCompatibleDC", "UPtr", 0)
		hdc2 := chdc ? chdc : DllCall("GetDC", "UPtr", 0)
		VarSetCapacity(bi, 40, 0)
		NumPut(40, bi, 0, "uint"),NumPut(this.Pos[3], bi, 4, "uint")
		NumPut(this.Pos[4], bi, 8, "uint"),NumPut(1, bi, 12, "ushort")
		NumPut(32, bi, 14, "ushort"),NumPut(0, bi, 16, "uInt")
		hbm := DllCall("CreateDIBSection", "UPtr", hdc2, "UPtr", &bi	 ; BITMAPINFO
			, "uint", 0, "UPtr*", 0, "UPtr", 0, "uint", 0, "UPtr")
		obm := DllCall("SelectObject", "UPtr", chdc, "UPtr", hbm), hhdc := hhdc ? hhdc : DllCall("GetDC", "UPtr", 0)
		DllCall("gdi32\BitBlt", "UPtr", chdc, "int", 0, "int", 0, "int", this.Pos[3], "int", this.Pos[4]
			, "UPtr", hhdc, "int", this.Pos[1], "int", this.Pos[2], "uint", 0x00CC0020)
		DllCall("ReleaseDC", "UPtr", 0, "UPtr", hhdc)

		DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "UPtr", hbm, "UPtr", 0, "UPtr*", pBitmap)
		DllCall("SelectObject", "UPtr", chdc, "UPtr", obm), DllCall("DeleteObject", "UPtr", hbm), DllCall("DeleteDC", "UPtr", hhdc), DllCall("DeleteDC", "UPtr", chdc)

		Return pBitmap
	}

	BitmapFromBase64(ByRef Base64) {
		Static Ptr := "UPtr"
		pBitmap := 0
		DecLen := 0

		; calculate the length of the buffer needed
		if !(DllCall("crypt32\CryptStringToBinary", Ptr, &Base64, "UInt", 0, "UInt", 0x01, Ptr, 0, "UIntP", DecLen, Ptr, 0, Ptr, 0))
			return -1

		VarSetCapacity(Dec, DecLen, 0)

		; decode the Base64 encoded string
		if !(DllCall("crypt32\CryptStringToBinary", Ptr, &Base64, "UInt", 0, "UInt", 0x01, Ptr, &Dec, "UIntP", DecLen, Ptr, 0, Ptr, 0))
			return -2

		; create a memory stream
		if !(pStream := DllCall("shlwapi\SHCreateMemStream", Ptr, &Dec, "UInt", DecLen, "UPtr"))
			return -3
		DllCall("gdiplus\GdipCreateBitmapFromStreamICM", "UPtr", pStream, "PtrP", pBitmap)
		ObjRelease(pStream)

		return pBitmap
	}

	SaveBitmapToFile(pBitmap, sOutput, Quality:=75, toBase64orStream:=0) {
		Static Ptr := "UPtr"
		nCount := 0
		nSize := 0
		pStream := 0
		hData := 0
		_p := 0

		SplitPath sOutput,,, Extension
		If !RegExMatch(Extension, "^(?i:BMP|DIB|RLE|JPG|JPEG|JPE|JFIF|GIF|TIF|TIFF|PNG)$")
			Return -1

		Extension := "." Extension
		DllCall("gdiplus\GdipGetImageEncodersSize", "uint*", nCount, "uint*", nSize)
		VarSetCapacity(ci, nSize)
		DllCall("gdiplus\GdipGetImageEncoders", "uint", nCount, "uint", nSize, Ptr, &ci)
		If !(nCount && nSize)
			Return -2

		If (A_IsUnicode)
		{
			StrGet_Name := "StrGet"
			N := (A_AhkVersion < 2) ? nCount : "nCount"
			Loop %N%
			{
				sString := %StrGet_Name%(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
			}
		} Else
		{
			N := (A_AhkVersion < 2) ? nCount : "nCount"
			Loop %N%
			{
				Location := NumGet(ci, 76*(A_Index-1)+44)
				nSize := DllCall("WideCharToMultiByte", "uint", 0, "uint", 0, "uint", Location, "int", -1, "uint", 0, "int",  0, "uint", 0, "uint", 0)
				VarSetCapacity(sString, nSize)
				DllCall("WideCharToMultiByte", "uint", 0, "uint", 0, "uint", Location, "int", -1, "str", sString, "int", nSize, "uint", 0, "uint", 0)
				If !InStr(sString, "*" Extension)
					Continue

				pCodec := &ci+76*(A_Index-1)
				Break
			}
		}

		If !pCodec
			Return -3

		If (Quality!=75)
		{
			Quality := (Quality < 0) ? 0 : (Quality > 100) ? 100 : Quality
			If (quality>95 && toBase64=1)
				Quality := 95

			If RegExMatch(Extension, "^\.(?i:JPG|JPEG|JPE|JFIF)$")
			{
				DllCall("gdiplus\GdipGetEncoderParameterListSize", Ptr, pBitmap, Ptr, pCodec, "uint*", nSize)
				VarSetCapacity(EncoderParameters, nSize, 0)
				DllCall("gdiplus\GdipGetEncoderParameterList", Ptr, pBitmap, Ptr, pCodec, "uint", nSize, Ptr, &EncoderParameters)
				nCount := NumGet(EncoderParameters, "UInt")
				N := (A_AhkVersion < 2) ? nCount : "nCount"
				Loop %N%
				{
					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 (toBase64orStream=1 || toBase64orStream=2)
		{
			; part of the function extracted from ImagePut by iseahound
			; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=76301&sid=bfb7c648736849c3c53f08ea6b0b1309
			DllCall("ole32\CreateStreamOnHGlobal", "ptr",0, "int",true, "ptr*",pStream)
			gdipLastError := DllCall("gdiplus\GdipSaveImageToStream", "ptr",pBitmap, "ptr",pStream, "ptr",pCodec, "uint", _p ? _p : 0)
			If gdipLastError
				Return -6

			If (toBase64orStream=2)
				Return pStream

			DllCall("ole32\GetHGlobalFromStream", "ptr",pStream, "uint*",hData)
			pData := DllCall("GlobalLock", "ptr",hData, "ptr")
			nSize := DllCall("GlobalSize", "uint",pData)

			VarSetCapacity(bin, nSize, 0)
			DllCall("RtlMoveMemory", "ptr",&bin, "ptr",pData, "uptr",nSize)
			DllCall("GlobalUnlock", "ptr",hData)
			ObjRelease(pStream)
			DllCall("GlobalFree", "ptr",hData)

			; Using CryptBinaryToStringA saves about 2MB in memory.
			DllCall("Crypt32.dll\CryptBinaryToStringA", "ptr",&bin, "uint",nSize, "uint",0x40000001, "ptr",0, "uint*",base64Length)
			VarSetCapacity(base64, base64Length, 0)
			_E := DllCall("Crypt32.dll\CryptBinaryToStringA", "ptr",&bin, "uint",nSize, "uint",0x40000001, "ptr",&base64, "uint*",base64Length)
			If !_E
				Return -7

			VarSetCapacity(bin, 0)
			Return StrGet(&base64, base64Length, "CP0")
		}

		_E := DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, "WStr", sOutput, Ptr, pCodec, "uint", _p ? _p : 0)
		gdipLastError := _E
		Return _E ? -5 : 0
	}

	FillRoundedRectangle(pGraphics, pBrush, x, y, w, h, r) {
		Region := this.GetClipRegion(pGraphics)
		this.SetClipRect(pGraphics, x-r, y-r, 2*r, 2*r, 4)
		this.SetClipRect(pGraphics, x+w-r, y-r, 2*r, 2*r, 4)
		this.SetClipRect(pGraphics, x-r, y+h-r, 2*r, 2*r, 4)
		this.SetClipRect(pGraphics, x+w-r, y+h-r, 2*r, 2*r, 4)
		_E := DllCall("gdiplus\GdipFillRectangle"
			, "UPtr", pGraphics
			, "UPtr", pBrush
			, "float", x, "float", y
			, "float", w, "float", h)
		DllCall("gdiplus\GdipSetClipRegion", "UPtr", pGraphics, "UPtr", Region, "int", 0)
		this.SetClipRect(pGraphics, x-(2*r), y+r, w+(4*r), h-(2*r), 4)
		this.SetClipRect(pGraphics, x+r, y-(2*r), w-(2*r), h+(4*r), 4)
		this.FillEllipse(pGraphics, pBrush, x, y, 2*r, 2*r)
		this.FillEllipse(pGraphics, pBrush, x+w-(2*r), y, 2*r, 2*r)
		this.FillEllipse(pGraphics, pBrush, x, y+h-(2*r), 2*r, 2*r)
		this.FillEllipse(pGraphics, pBrush, x+w-(2*r), y+h-(2*r), 2*r, 2*r)
		DllCall("gdiplus\GdipSetClipRegion", "UPtr", pGraphics, "UPtr", Region, "int", 0)
		DllCall("gdiplus\GdipDeleteRegion", "UPtr", Region)
		return _E
	}

	GetClipRegion(pGraphics) {
		 DllCall("gdiplus\GdipCreateRegion", "UInt*", Region)
		E := DllCall("gdiplus\GdipGetClip", "UPtr", pGraphics, "UInt", Region)
		If E
			return -1
		return Region
	}

	FillEllipse(pGraphics, pBrush, x, y, w, h) {
		If (!pGraphics || !pBrush || !w || !h)
			Return 2

		Return DllCall("gdiplus\GdipFillEllipse", "UPtr", pGraphics, "UPtr", pBrush, "float", x, "float", y, "float", w, "float", h)
	}

	DrawRoundedRectangle(pGraphics, pPen, x, y, w, h, r) {
		If (!pGraphics || !pPen || !w || !h)
			Return 2

		this.SetClipRect(pGraphics, x-r, y-r, 2*r, 2*r, 4)
		this.SetClipRect(pGraphics, x+w-r, y-r, 2*r, 2*r, 4)
		this.SetClipRect(pGraphics, x-r, y+h-r, 2*r, 2*r, 4)
		this.SetClipRect(pGraphics, x+w-r, y+h-r, 2*r, 2*r, 4)
		_E := DllCall("gdiplus\GdipDrawRectangle", "UPtr", pGraphics, "UPtr", pPen, "float", x, "float", y, "float", w, "float", h)
		DllCall("gdiplus\GdipResetClip", "UPtr", pGraphics)
		this.SetClipRect(pGraphics, x-(2*r), y+r, w+(4*r), h-(2*r), 4)
		this.SetClipRect(pGraphics, x+r, y-(2*r), w-(2*r), h+(4*r), 4)
		this.DrawEllipse(pGraphics, pPen, x, y, 2*r, 2*r)
		this.DrawEllipse(pGraphics, pPen, x+w-(2*r), y, 2*r, 2*r)
		this.DrawEllipse(pGraphics, pPen, x, y+h-(2*r), 2*r, 2*r)
		this.DrawEllipse(pGraphics, pPen, x+w-(2*r), y+h-(2*r), 2*r, 2*r)
		DllCall("gdiplus\GdipResetClip", "UPtr", pGraphics)
		return _E
	}

	DrawEllipse(pGraphics, pPen, x, y, w, h) {
		If (!pGraphics || !pPen || !w || !h)
			Return 2

		Return DllCall("gdiplus\GdipDrawEllipse", "UPtr", pGraphics, "UPtr", pPen, "float", x, "float", y, "float", w, "float", h)
	}

	SetClipRect(pGraphics, x, y, w, h, CombineMode:=0) {
	; CombineMode options:
	; Replace = 0
	; Intersect = 1
	; Union = 2
	; Xor = 3
	; Exclude = 4
	; Complement = 5

		return DllCall("gdiplus\GdipSetClipRect", "UPtr", pGraphics, "float", x, "float", y, "float", w, "float", h, "int", CombineMode)
	}

	CreateHBITMAPFromBitmap(pBitmap, Background:=0xffffffff) {
		; background should be zero, to not alter alpha channel of the image
		hBitmap := 0
		If !pBitmap
		{
			gdipLastError := 2
			Return
		}

		gdipLastError := DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "UPtr", pBitmap, "UPtr*", hBitmap, "int", Background)
		return hBitmap
	}

	UpdateLayeredWindow(hwnd, hdc, x:="", y:="", w:="", h:="", Alpha:=255) {
		Static Ptr := "UPtr"
		if ((x != "") && (y != ""))
			VarSetCapacity(pt, 8), NumPut(x, pt, 0, "UInt"), NumPut(y, pt, 4, "UInt")

		if (w = "") || (h = "")
			this.GetWindowRect(hwnd, W, H)

		return DllCall("UpdateLayeredWindow"
			, Ptr, hwnd
			, Ptr, 0
			, Ptr, ((x = "") && (y = "")) ? 0 : &pt
			, "int64*", w|h<<32
			, Ptr, hdc
			, "int64*", 0
			, "uint", 0
			, "UInt*", Alpha<<16|1<<24
			, "uint", 2)
	}

	GetWindowRect(hwnd, ByRef W, ByRef H) {
		; function by GeekDude: https://gist.github.com/G33kDude/5b7ba418e685e52c3e6507e5c6972959
		; W10 compatible function to find a window's visible boundaries
		; modified by Marius Șucanto return an array
		If !hwnd
			Return

		size := VarSetCapacity(rect, 16, 0)
		er := DllCall("dwmapi\DwmGetWindowAttribute"
			, "UPtr", hWnd  ; HWND  hwnd
			, "UInt", 9	  ; DWORD dwAttribute (DWMWA_EXTENDED_FRAME_BOUNDS)
			, "UPtr", &rect ; PVOID pvAttribute
			, "UInt", size  ; DWORD cbAttribute
			, "UInt")		 ; HRESULT

		If er
			DllCall("GetWindowRect", "UPtr", hwnd, "UPtr", &rect, "UInt")

		r := []
		r.x1 := NumGet(rect, 0, "Int"), r.y1 := NumGet(rect, 4, "Int")
		r.x2 := NumGet(rect, 8, "Int"), r.y2 := NumGet(rect, 12, "Int")
		r.w := Abs(max(r.x1, r.x2) - min(r.x1, r.x2))
		r.h := Abs(max(r.y1, r.y2) - min(r.y1, r.y2))
		W := r.w
		H := r.h
		; ToolTip, % r.w " --- " r.h , , , 2
		Return r
	}

	SaveBitmapToClipboard(pBitmap, hBitmap:=0) {
		off1 := A_PtrSize = 8 ? 52 : 44,off2 := A_PtrSize = 8 ? 32 : 24
		pid := DllCall("GetCurrentProcessId","uint")
		hwnd := WinExist("ahk_pid " . pid)
		r1 := DllCall("OpenClipboard", "UPtr", hwnd)
		If !r1
			Return -1
		If !hBitmap {
			If pBitmap
				DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "UPtr", pBitmap, "UPtr*", hBitmap, "int", 0)
		}
		If !hBitmap {
			DllCall("CloseClipboard")
			Return -3
		}
		r2 := DllCall("EmptyClipboard")
		If !r2 {
			DllCall("DeleteObject", "UPtr", hBitmap)
			DllCall("CloseClipboard")
			Return -2
		}
		DllCall("GetObject", "UPtr", hBitmap, "int", VarSetCapacity(oi, A_PtrSize = 8 ? 104 : 84, 0), "UPtr", &oi)
		hdib := DllCall("GlobalAlloc", "uint", 2, "UPtr", 40+NumGet(oi, off1, "UInt"), "UPtr")
		pdib := DllCall("GlobalLock", "UPtr", hdib, "UPtr")
		DllCall("RtlMoveMemory", "UPtr", pdib, "UPtr", &oi+off2, "UPtr", 40)
		DllCall("RtlMoveMemory", "UPtr", pdib+40, "UPtr", NumGet(oi, off2 - A_PtrSize, "UPtr"), "UPtr", NumGet(oi, off1, "UInt"))
		DllCall("GlobalUnlock", "UPtr", hdib)
		DllCall("DeleteObject", "UPtr", hBitmap)
		r3 := DllCall("SetClipboardData", "uint", 8, "UPtr", hdib) ; CF_DIB = 8
		DllCall("CloseClipboard")
		DllCall("GlobalFree", "UPtr", hdib)
		E := r3 ? 0 : -4	 ; 0 - success
		Return E
	}

	RestoreCursors()
	{
		Static SPI_SETCURSORS := 0x57
		DllCall( "SystemParametersInfo", UInt,SPI_SETCURSORS, UInt,0, UInt,0, UInt,0 )
	}

	/*
		Cursor鼠标状态类型:
			IDC_ARROW	常规箭头形
			IDC_IBEAM	"工"字形文本插入
			IDC_WAIT	沙漏形
			IDC_CROSS	十字形精确定位
			IDC_UPARROW	上箭头
			IDC_SIZE	隐藏指针
			IDC_ICON	使用指定光标文件
			IDC_SIZENWSE	左上角右下角大小调整
			IDC_SIZENESW	左下角右上角大小调整
			IDC_SIZEWE	水平调整
			IDC_SIZENS	垂直调整
			IDC_SIZEALL	选中并移动
			IDC_NO		不可用
			IDC_HAND	小手形状
			IDC_APPSTARTING	系统忙
			IDC_HELP	帮助
	*/
	SetSystemCursor( Cursor = "", cx = 0, cy = 0 )
	{
		BlankCursor := 0, SystemCursor := 0, FileCursor := 0 ; init
		SystemCursors = 32512IDC_ARROW,32513IDC_IBEAM,32514IDC_WAIT,32515IDC_CROSS
		,32516IDC_UPARROW,32640IDC_SIZE,32641IDC_ICON,32642IDC_SIZENWSE
		,32643IDC_SIZENESW,32644IDC_SIZEWE,32645IDC_SIZENS,32646IDC_SIZEALL
		,32648IDC_NO,32649IDC_HAND,32650IDC_APPSTARTING,32651IDC_HELP
		If Cursor = ; empty, so create blank cursor 
		{
			VarSetCapacity( AndMask, 32*4, 0xFF ), VarSetCapacity( XorMask, 32*4, 0 )
			BlankCursor = 1 ; flag for later
		}
		Else If SubStr( Cursor,1,4 ) = "IDC_" ; load system cursor
		{
			Loop, Parse, SystemCursors, `,
			{
				CursorName := SubStr( A_Loopfield, 6, 15 ) ; get the cursor name, no trailing space with substr
				CursorID := SubStr( A_Loopfield, 1, 5 ) ; get the cursor id
				SystemCursor = 1
				If ( CursorName = Cursor )
				{
					CursorHandle := DllCall( "LoadCursor", Uint,0, Int,CursorID )
					Break
				}
			}
			If CursorHandle = ; invalid cursor name given
			{
				Msgbox,, SetCursor, Error: Invalid cursor name
				CursorHandle = Error
			}
		}
		Else If FileExist( Cursor )
		{
			SplitPath, Cursor,,, Ext ; auto-detect type
			If Ext = ico 
				uType := 0x1
			Else If Ext in cur,ani
				uType := 0x2
			Else ; invalid file ext
			{
				Msgbox,, SetCursor, Error: Invalid file type
				CursorHandle = Error
			}
			FileCursor = 1
		}
		Else
		{
			Msgbox,, SetCursor, Error: Invalid file path or cursor name
			CursorHandle = Error ; raise for later
		}
		If CursorHandle != Error 
		{
			Loop, Parse, SystemCursors, `,
			{
				If BlankCursor = 1 
				{
					Type = BlankCursor
					%Type%%A_Index% := DllCall( "CreateCursor"
					, Uint,0, Int,0, Int,0, Int,32, Int,32, Uint,&AndMask, Uint,&XorMask )
					CursorHandle := DllCall( "CopyImage", Uint,%Type%%A_Index%, Uint,0x2, Int,0, Int,0, Int,0 )
					DllCall( "SetSystemCursor", Uint,CursorHandle, Int,SubStr( A_Loopfield, 1, 5 ) )
				}
				Else If SystemCursor = 1
				{
					Type = SystemCursor
					CursorHandle := DllCall( "LoadCursor", Uint,0, Int,CursorID )
					%Type%%A_Index% := DllCall( "CopyImage"
					, Uint,CursorHandle, Uint,0x2, Int,cx, Int,cy, Uint,0 )
					CursorHandle := DllCall( "CopyImage", Uint,%Type%%A_Index%, Uint,0x2, Int,0, Int,0, Int,0 )
					DllCall( "SetSystemCursor", Uint,CursorHandle, Int,SubStr( A_Loopfield, 1, 5 ) )
				}
				Else If FileCursor = 1
				{
					Type = FileCursor
					%Type%%A_Index% := DllCall( "LoadImageA"
					, UInt,0, Str,Cursor, UInt,uType, Int,cx, Int,cy, UInt,0x10 ) 
					DllCall( "SetSystemCursor", Uint,%Type%%A_Index%, Int,SubStr( A_Loopfield, 1, 5 ) )
				}			 
			}
		}
	}
}

OutlineMouseHookProc(code, wParam, lParam) {
	Global HighlightOutline
	if(code == 0 or code == 3) {
		if (wParam=0x201){
			CoordMode,Mouse,Screen
			MouseGetPos,xpos,ypos
			if (xpos>HighlightOutline.Click.copy.1&&xpos-HighlightOutline.Click.copy.1<HighlightOutline.Click.copy.3&&ypos>HighlightOutline.Click.copy.2&&ypos-HighlightOutline.Click.copy.2<HighlightOutline.Click.copy.4){
				HighlightOutline.__Delete()
				HighlightOutline.SaveToClipboard()
				TrayTip,截图提示,截图已发送到剪切板!,,1
			}else if (xpos>HighlightOutline.Click.save.1&&xpos-HighlightOutline.Click.save.1<HighlightOutline.Click.save.3&&ypos>HighlightOutline.Click.save.2&&ypos-HighlightOutline.Click.save.2<HighlightOutline.Click.save.4){
				HighlightOutline.__Delete()
				HighlightOutline.SaveToFile()
				TrayTip,保存提示,截图已保存!,,1
			}
		}else if (wParam=0x204){
			HighlightOutline.__Delete()
		}
	} else {
		return CallNextHookEx(0, code, wParam, lParam)
	}
}

CallNextHookEx(hhk, nCode, wParam, lParam) {
	return DllCall("CallNextHookEx", "Ptr", hhk, "Int", nCode, "Ptr", wParam, "Ptr", lParam)
}

给TA捐赠
共{{data.count}}人
人已捐赠
其他

电脑软件安装流程 2022.03.19

2022-3-19 14:13:12

其他

聚合搜索的小工具

2022-3-19 19:33:41

9 条回复 A文章作者 M管理员
  1. AHK中文社区
    1河许人给您打赏了¥2
  2. dbgba
    dbgba给您打赏了¥2
  3. oeasy

    老表威武

    • 蜜獾哥

      老表很伤!很苦!?

  4. oeasy

    老表可以搞成按住win+鼠标左键拖动截图

    • Tmz

      关键代码都给出来了自己调试调试应该就能实现了吧、

  5. doge

    学习学习

  6. 乌咪

    学习

  7. Tmz

    大佬厉害呀、

个人中心
购物车
优惠劵
有新私信 私信列表
搜索