-
Notifications
You must be signed in to change notification settings - Fork 72
/
Copy pathCompareCursor.ahk
227 lines (203 loc) · 7.31 KB
/
CompareCursor.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/*
#SingleInstance Force
^\::ExitApp
;capturing current mouse cursor and save to "testCursor.bmp"
F11::
CaptureCursor("testCursor.bmp")
return
;compare to testCursor.bmp and current mouse cursor
F12::
loop
{
ToolTip, % IsMatchCursor("testCursor.bmp")? "match" : "unmatch"
Sleep, 100
}
return
*/
;---------------------------------------------------------------
; CaptureCursor and IsMatchCursor
;---------------------------------------------------------------
;captureTo: "clipboard"=save to clipboard , "bitmap_handle"=return current cursor bitmap handle.
;return: 0=fail , 1=success
CaptureCursor(captureTo="clipboard", cursorSize=32){
VarSetCapacity(CURSORINFO, A_PtrSize=8? 24:20, 0)
VarSetCapacity(ICONINFO, A_PtrSize=8? 32:20, 0)
NumPut(A_PtrSize=8? 24:20, CURSORINFO, 0,"UInt")
DllCall("GetCursorInfo", "UPTR", &CURSORINFO)
hCursor := NumGet(CURSORINFO, 8, "UPtr")
flags := NumGet(CURSORINFO, 4, "UInt")
if !hCursor or !flags
return 0
hCursor := DllCall("CopyIcon", "UPTR", hCursor)
DllCall("GetIconInfo", "UPTR", hCursor, "UPTR", &ICONINFO)
mDC := DllCall("CreateCompatibleDC", "UPTR", 0, "UPTR")
hBM := CreateDIBSection(mDC, cursorSize, cursorSize)
oBM := DllCall("SelectObject", "UPTR", mDC, "UPTR", hBM, "UPTR")
DllCall("DrawIcon", "UPTR", mDC, "int",0, "int",0, "UPTR", hCursor)
DllCall("SelectObject", "UPTR", mDC, "UPTR", oBM)
DllCall("DeleteDC", "UPTR", mDC)
DllCall("DestroyIcon", "UPTR", hCursor)
If hbmMask := NumGet(ICONINFO, A_PtrSize=8? 16:12, "UPtr")
DllCall("DeleteObject", "UPTR", hbmMask)
If hbmColor := NumGet(ICONINFO, A_PtrSize=8? 24:16, "UPtr")
DllCall("DeleteObject", "UPTR", hbmColor)
if captureTo=bitmap_handle
return hBM
If captureTo=clipboard
SetClipboardData(hBM)
else
SaveHBITMAPToFile(hBM, captureTo)
DllCall("DeleteObject", "UPTR", hBM)
return 1
}
;compare cursor bmp file to current mouse cursor.
; 1 : cursor image match
; 0 : cursor image unmatch
; ""; hide mouse cursor or can't get cursor handle.
IsMatchCursor(bmpCursorFile){
if !hCursorBmp := CaptureCursor("bitmap_handle", bmpSize:=32)
return ""
hSourceBmp := LoadBMP(bmpCursorFile)
return !CompareBitmap(hSourceBmp, hCursorBmp, bmpSize)
}
;---------------------------------------------------------------
; Sub function
;---------------------------------------------------------------
;this function takes two bitmaps and compares the first 32x32 pixel square on them
;hBM1 and hBM2: bitmap handle
;return: 0=match, 1=unmatch
CompareBitmap(hBM1, hBM2, size=32){
x=0
mDC1 := DllCall("CreateCompatibleDC", "Uint", 0) ;create DC compatible with screen
mDC2 := DllCall("CreateCompatibleDC", "Uint", 0)
oBM1 := DllCall("SelectObject", "UPTR", mDC1, "UPTR", hBM1) ;put the object in the device context
oBM2 := DllCall("SelectObject", "UPTR", mDC2, "UPTR", hBM2)
while x < size
{
y=0
while y < size
{
color1 := DllCall("GetPixel", "UPTR", mDC1, "int", x, "int",y) ;get the RGB of pixel (x, y)
color2 := DllCall("GetPixel", "UPTR", mDC2, "int", x, "int",y)
if color1 <> %color2% ;if colors are different, didn't match
return 1
y+=1
}
x+=1
}
DllCall("SelectObject", "UPTR", mDC1, "UPTR", oBM1) ;put the original contents back in DC
DllCall("SelectObject", "UPTR", mDC2, "UPTR", oBM2)
DllCall("DeleteDC", "UPTR", mDC1) ;delete DC (prevent memory leak)
DllCall("DeleteDC", "UPTR", mDC2)
DllCall("DeleteObject", "UPTR", hBM1) ;delete the images in memory
DllCall("DeleteObject", "UPTR", hBM2)
return 0 ;0 return if match
}
CreateDIBSection(hDC, nW, nH, bpp = 32, ByRef pBits = ""){
VarSetCapacity(BITMAPINFO, 44, 0)
NumPut(44, BITMAPINFO, 0,"UInt")
NumPut(nW, BITMAPINFO, 4,"Int")
NumPut(nH, BITMAPINFO, 8,"Int")
NumPut(1, BITMAPINFO, 12,"UShort")
NumPut(bpp, BITMAPINFO, 14,"UShort")
Return DllCall("gdi32\CreateDIBSection", "UPTR", hDC, "UPTR", &BITMAPINFO, "Uint", 0, "UPTR", pBits, "Uint", 0, "Uint", 0)
}
SetClipboardData(hBitmap){
VarSetCapacity(DIBSECTION, A_PtrSize=8? 104:84, 0)
NumPut(40, DIBSECTION, A_PtrSize=8? 32:24,"UInt") ;dsBmih.biSize
DllCall("GetObject", "UPTR", hBitmap, "int", A_PtrSize=8? 104:84, "UPTR", &DIBSECTION)
biSizeImage := NumGet(DIBSECTION, A_PtrSize=8? 52:44, "UInt")
hDIB := DllCall("GlobalAlloc", "Uint", 2, "Uint", 40+biSizeImage)
pDIB := DllCall("GlobalLock", "UPTR", hDIB)
DllCall("RtlMoveMemory", "UPTR", pDIB, "UPTR", &DIBSECTION + (A_PtrSize=8? 32:24), "Uint", 40)
DllCall("RtlMoveMemory", "UPTR", pDIB+40, "Uint", NumGet(DIBSECTION, A_PtrSize=8? 24:20, "UPtr"), "Uint", biSizeImage)
DllCall("GlobalUnlock", "UPTR", hDIB)
DllCall("DeleteObject", "UPTR", hBitmap)
DllCall("OpenClipboard", "Uint", 0)
DllCall("EmptyClipboard")
DllCall("SetClipboardData", "Uint", 8, "UPTR", hDIB)
DllCall("CloseClipboard")
}
LoadBMP(bmpFile){
bmpFile := GetValidFilePath(bmpFile)
hBmp := DllCall("LoadImage","Uint", 0, "str", bmpFile, "Uint", 0, "int", 32, "int",32, "Uint", 0x00000010) ;load the image from file
return hBmp
}
SaveHBITMAPToFile(hBitmap, sFile){
sFile := GetValidFilePath(sFile)
VarSetCapacity(DIBSECTION, A_PtrSize=8? 104:84, 0)
NumPut(40, DIBSECTION, A_PtrSize=8? 32:24,"UInt") ;dsBmih.biSize
DllCall("GetObject", "UPTR", hBitmap, "int", A_PtrSize=8? 104:84, "UPTR", &DIBSECTION)
hFile:= DllCall("CreateFile", "UPTR", &sFile, "Uint", 0x40000000, "Uint", 0, "Uint", 0, "Uint", 2, "Uint", 0, "Uint", 0)
DllCall("WriteFile", "UPTR", hFile, "int64P", 0x4D42|14+40+(biSizeImage:=NumGet(DIBSECTION, A_PtrSize=8? 52:44, "UInt"))<<16, "Uint", 6, "UintP", 0, "Uint", 0)
DllCall("WriteFile", "UPTR", hFile, "int64P", 54<<32, "Uint", 8, "UintP", 0, "Uint", 0)
DllCall("WriteFile", "UPTR", hFile, "UPTR", &DIBSECTION + (A_PtrSize=8? 32:24), "Uint", 40, "UintP", 0, "Uint", 0)
DllCall("WriteFile", "UPTR", hFile, "Uint", NumGet(DIBSECTION, A_PtrSize=8? 24:20, "UPtr"), "Uint", biSizeImage, "UintP", 0, "Uint", 0)
DllCall("CloseHandle", "UPTR", hFile)
}
GetValidFilePath(filename){
SplitPath, filename, , sDir, sExt, sName
IfNotInString, sDir, :
sDir = %A_ScriptDir%\%sDir%
filename = %sDir%\%sName%.%sExt%
StringReplace, filename, filename, \\, \, All
return filename
}
;---------------------------------------------------------------
; Struct List
;---------------------------------------------------------------
/*
typedef struct {
DWORD cbSize;
DWORD flags;
HCURSOR hCursor;
POINT ptScreenPos;
} CURSORINFO, *PCURSORINFO, *LPCURSORINFO;
typedef struct _ICONINFO {
BOOL fIcon;
DWORD xHotspot;
DWORD yHotspot;
HBITMAP hbmMask;
HBITMAP hbmColor;
} ICONINFO, *PICONINFO;
typedef struct tagDIBSECTION {
BITMAP dsBm;
BITMAPINFOHEADER dsBmih;
DWORD dsBitfields[3];
HANDLE dshSection;
DWORD dsOffset;
} DIBSECTION, *PDIBSECTION;
typedef struct tagBITMAPINFOHEADER {
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
typedef struct tagBITMAP {
LONG bmType;
LONG bmWidth;
LONG bmHeight;
LONG bmWidthBytes;
WORD bmPlanes;
WORD bmBitsPixel;
LPVOID bmBits;
} BITMAP, *PBITMAP;
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
*/