获取光标的特征码-feiyue

一个很不错的学习dllcall的例子。

#NoEnv 
#Persistent
SetTimer, GetCursor, 50
return

GetCursor:
t:=QPC()
Shape := GetCursorShape()
ToolTip, % "特征码:" Shape . "`n用时:" . QPC()-t . "ms"
return

Esc:: ExitApp

QPC()  ; <==> A_TickCount
{
  static f, c:=DllCall("QueryPerformanceFrequency", "Int*",f)
  return (!DllCall("QueryPerformanceCounter","Int64*",c))*0+(c/f)*1000
}

GetCursorShape()  ; 获取光标特征码 by nnrxin,FeiYue改进
{
  static Ptr:=(A_PtrSize ? "Ptr":"UInt"), PtrSize:=(A_PtrSize=8 ? 8:4)
  VarSetCapacity(CursorInfo, 40, 0)         ; 创建 光标信息 结构(申请空间大一点没关系)
  NumPut(16+PtrSize, CursorInfo, 0, "int")  ; 写入 结构 的大小cbSize(必须准确)
  DllCall("GetCursorInfo", Ptr,&CursorInfo) ; 获取光标信息填入结构
  bShow   :=NumGet(CursorInfo, 4, "int")    ; 读取光标状态 flags字段
  hCursor :=NumGet(CursorInfo, 8, Ptr)      ; 读取光标句柄
  if (!bShow)
    return 0
  VarSetCapacity(IconInfo, 40, 0)             ; 创建 图标信息 结构(申请空间大一点没关系)
  DllCall("GetIconInfo", Ptr,hCursor, Ptr,&IconInfo)  ;获取图标信息填入结构
  hBMMask :=NumGet(IconInfo, 8+PtrSize, Ptr)
  hBMColor:=NumGet(IconInfo, 8+PtrSize*2, Ptr)
  MaskCode:=ColorCode:=0, size:=32*32
  VarSetCapacity(lpvMaskBits, size//8, 0)     ; 创造 数组-掩码图信息,每个字节含8个掩码位
  DllCall("GetBitmapBits", Ptr,hBMMask, "int",size//8, Ptr,&lpvMaskBits)
  Loop, % size//8
    MaskCode += NumGet(lpvMaskBits, A_Index-1, "UChar")
  if (hBMColor)
  {
    VarSetCapacity(lpvColorBits, size*4, 0)  ; 创造 数组-彩色图信息,每个彩色位占4个字节
    DllCall("GetBitmapBits", Ptr,hBMColor, "int",size*4, Ptr,&lpvColorBits)
    Loop, % size  ; 只读取彩色位中的绿色分量
      ColorCode += NumGet(lpvColorBits, A_Index*4-3, "UChar")
  }
  DllCall("DeleteObject", Ptr,hBMMask)   ; *清理掩码图
  DllCall("DeleteObject", Ptr,hBMColor)  ; *清理彩色图
  return MaskCode . ColorCode  ;输出特征码
}

;

大白的V2版本

Persistent()
SetTimer GetCursor, 50

GetCursor() {
	t := QPC()
	Shape := GetCursorShape()
	ToolTip "特征码:" Shape . "`n用时:" . QPC() - t . "ms"
}

Esc::ExitApp
QPC() {	; <==> A_TickCount
	static f := 0, c := (DllCall("QueryPerformanceFrequency", "Int*", &f), f /= 1000)
	return (DllCall("QueryPerformanceCounter", "Int64*", &c), c / f)
}

GetCursorShape() {	; 获取光标特征码 by nnrxin,FeiYue改进
	CursorInfo := Buffer(40, 0)	; 创建 光标信息 结构(申请空间大一点没关系)
	NumPut("int", 16 + A_PtrSize, CursorInfo, 0)	; 写入 结构 的大小cbSize(必须准确)
	DllCall("GetCursorInfo", "Ptr", CursorInfo)	; 获取光标信息填入结构
	bShow := NumGet(CursorInfo, 4, "int")	; 读取光标状态 flags字段
	hCursor := NumGet(CursorInfo, 8, "Ptr")	; 读取光标句柄
	if (!bShow)
		return 0
	IconInfo := Buffer(40, 0)	; 创建 图标信息 结构(申请空间大一点没关系)
	DllCall("GetIconInfo", "Ptr", hCursor, "Ptr", IconInfo)	;获取图标信息填入结构
	hBMMask := NumGet(IconInfo, 8 + A_PtrSize, "Ptr")
	hBMColor := NumGet(IconInfo, 8 + A_PtrSize * 2, "Ptr")
	MaskCode := ColorCode := 0, size := 32 * 32
	lpvMaskBits := Buffer(size // 8, 0)	; 创造 数组-掩码图信息,每个字节含8个掩码位
	DllCall("GetBitmapBits", "Ptr", hBMMask, "int", size // 8, "Ptr", lpvMaskBits)
	Loop size // 8
		MaskCode += NumGet(lpvMaskBits, A_Index - 1, "UChar")
	if (hBMColor) {
		lpvColorBits := Buffer(size * 4, 0)	; 创造 数组-彩色图信息,每个彩色位占4个字节
		DllCall("GetBitmapBits", "Ptr", hBMColor, "int", size * 4, "Ptr", lpvColorBits)
		Loop size	; 只读取彩色位中的绿色分量
			ColorCode += NumGet(lpvColorBits, A_Index * 4 - 3, "UChar")
		DllCall("DeleteObject", "Ptr", hBMColor)	; *清理彩色图
	}
	DllCall("DeleteObject", "Ptr", hBMMask)	; *清理掩码图
	return MaskCode . ColorCode	;输出特征码
}

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

热键控制的进阶用法

2021-5-21 14:58:48

其他教程

输出调试信息到控制台-feiyue

2021-5-25 16:34:33

4 条回复 A文章作者 M管理员
  1. autokey

    学习了

  2. ccb1234

    感谢干货分享

  3. ogib

    thanks

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