-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTakeScreenshots.ahk
More file actions
198 lines (163 loc) · 5.73 KB
/
Copy pathTakeScreenshots.ahk
File metadata and controls
198 lines (163 loc) · 5.73 KB
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
; AutoHotkey v1.1.x
; F9 to start the capture run. Esc to abort.
; Captures the entire virtual screen (all monitors) every waitMs ms for totalMs ms, simulating a click before each capture.
#NoEnv
#SingleInstance, Force
SetBatchLines, -1
SetWorkingDir, %A_ScriptDir%
CoordMode, Mouse, Screen
global __gdipToken := 0
global __gdipModule := 0
F9::
{
; Configuration
waitMs := 2000 ; wait between click and screenshot
nPages := 1300 ; number of pages to capture
totalMs := nPages * waitMs ; total duration
outDir := A_ScriptDir . "\Screenshots"
FileCreateDir, %outDir%
if (!GDIp_Startup())
{
MsgBox, 16, Error, Failed to initialize GDI+ (gdiplus.dll).`n`nMake sure gdiplus.dll is available on this system.
return
}
start := A_TickCount
end := start + totalMs
i := 0
TrayTip, AutoHotkey, Starting 200-second click + screenshot capture..., 2, 1
while (A_TickCount < end)
{
; Left mouse click at current cursor position
Click
; Wait waitMs ms before the screenshot
Sleep, %waitMs%
; Build unique filename
i++
FormatTime, ts, , yyyyMMdd_HHmmss
fn := outDir . "\shot_" . Format("{:04}", i) . "_" . ts . ".png"
; Capture the entire virtual screen (all monitors) to file
if (!CaptureScreenToFile(fn))
{
; Optional: notify on failure and continue
; Tooltip, Failed to save screenshot #%i% to %fn%, 800, 600
}
}
GDIp_Shutdown()
TrayTip, AutoHotkey, Done. Saved %i% screenshots to:`n%outDir%, 5, 1
return
}
Esc::
GDIp_Shutdown()
ExitApp
; ---------------------------
; GDI+ helpers and screenshot
; ---------------------------
GDIp_Startup()
{
global __gdipToken, __gdipModule
if (__gdipToken) ; already started
return true
; Explicitly load gdiplus.dll
if (!__gdipModule)
{
__gdipModule := DllCall("LoadLibrary", "Str", "gdiplus.dll", "Ptr")
if (!__gdipModule)
return false
}
; GdiplusStartupInput structure
; Size: 16 bytes on 32-bit, 24 bytes on 64-bit
VarSetCapacity(si, A_PtrSize=8?24:16, 0)
; IMPORTANT: Set GdiplusVersion = 1
NumPut(1, si, 0, "UInt")
status := DllCall("gdiplus\GdiplusStartup", "PtrP", token, "Ptr", &si, "Ptr", 0, "UInt")
if (status != 0 || !token)
{
; If startup fails, free the module we loaded
if (__gdipModule)
{
DllCall("FreeLibrary", "Ptr", __gdipModule)
__gdipModule := 0
}
return false
}
__gdipToken := token
return true
}
GDIp_Shutdown()
{
global __gdipToken, __gdipModule
if (__gdipToken)
{
DllCall("gdiplus\GdiplusShutdown", "Ptr", __gdipToken)
__gdipToken := 0
}
if (__gdipModule)
{
DllCall("FreeLibrary", "Ptr", __gdipModule)
__gdipModule := 0
}
}
; Captures the entire virtual desktop (all monitors) and saves to a PNG file.
CaptureScreenToFile(filePath)
{
; Get virtual screen origin and size (handles multi-monitor and negative coords)
x := DllCall("GetSystemMetrics", "Int", 76, "Int") ; SM_XVIRTUALSCREEN
y := DllCall("GetSystemMetrics", "Int", 77, "Int") ; SM_YVIRTUALSCREEN
w := DllCall("GetSystemMetrics", "Int", 78, "Int") ; SM_CXVIRTUALSCREEN
h := DllCall("GetSystemMetrics", "Int", 79, "Int") ; SM_CYVIRTUALSCREEN
if (w <= 0 || h <= 0)
return false
hdcScreen := DllCall("GetDC", "Ptr", 0, "Ptr")
if (!hdcScreen)
return false
hdcMem := DllCall("gdi32\CreateCompatibleDC", "Ptr", hdcScreen, "Ptr")
if (!hdcMem)
{
DllCall("ReleaseDC", "Ptr", 0, "Ptr", hdcScreen)
return false
}
hbm := DllCall("gdi32\CreateCompatibleBitmap", "Ptr", hdcScreen, "Int", w, "Int", h, "Ptr")
if (!hbm)
{
DllCall("gdi32\DeleteDC", "Ptr", hdcMem)
DllCall("ReleaseDC", "Ptr", 0, "Ptr", hdcScreen)
return false
}
obm := DllCall("gdi32\SelectObject", "Ptr", hdcMem, "Ptr", hbm, "Ptr")
; SRCCOPY = 0x00CC0020
ok := DllCall("gdi32\BitBlt", "Ptr", hdcMem, "Int", 0, "Int", 0, "Int", w, "Int", h
, "Ptr", hdcScreen, "Int", x, "Int", y, "UInt", 0x00CC0020)
; Restore and cleanup DCs
DllCall("gdi32\SelectObject", "Ptr", hdcMem, "Ptr", obm, "Ptr")
DllCall("gdi32\DeleteDC", "Ptr", hdcMem)
DllCall("ReleaseDC", "Ptr", 0, "Ptr", hdcScreen)
if (!ok)
{
DllCall("gdi32\DeleteObject", "Ptr", hbm)
return false
}
; Create a GDI+ Bitmap from HBITMAP
if DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Ptr", hbm, "Ptr", 0, "PtrP", pBitmap)
{
DllCall("gdi32\DeleteObject", "Ptr", hbm)
return false
}
; CLSID for PNG encoder: {557CF406-1A04-11D3-9A73-0000F81EF32E}
VarSetCapacity(clsid, 16, 0)
NumPut(0x557CF406, clsid, 0, "UInt")
NumPut(0x1A04, clsid, 4, "UShort")
NumPut(0x11D3, clsid, 6, "UShort")
NumPut(0x9A, clsid, 8, "UChar")
NumPut(0x73, clsid, 9, "UChar")
NumPut(0x00, clsid, 10, "UChar")
NumPut(0x00, clsid, 11, "UChar")
NumPut(0xF8, clsid, 12, "UChar")
NumPut(0x1E, clsid, 13, "UChar")
NumPut(0xF3, clsid, 14, "UChar")
NumPut(0x2E, clsid, 15, "UChar")
status := DllCall("gdiplus\GdipSaveImageToFile", "Ptr", pBitmap, "WStr", filePath, "Ptr", &clsid, "Ptr", 0)
; Cleanup
DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmap)
DllCall("gdi32\DeleteObject", "Ptr", hbm)
return (status = 0)
}