Новая версия предыдущего скрипта.
Добавлено:
Возможность работы под AHK_Lw. При этом скрипт должен быть соханён в формате UTF-8.
Возможность запуска при загрузке системы, при этом окно скрипта изначально будет скрыто.
Возможность делать скриншоты чаще, чем раз в секунду.
Возможность включения в скриншот курсора.
Назначение горячих клавиш по сравнению с предыдущей версией изменено, читайте Help (F1 после запуска). Все горячие клавиши находятся в конце скрипта, можно менять.
#Requires AutoHotkey v1
#NoEnv
#UseHook
OnExit, Exit
SetWinDelay, 0
SetBatchLines, -1
SetTitleMatchMode, 3
CoordMode, Mouse
icoPath = %A_ScriptDir%\ScreenCatcher.ico
if (FileExist(icoPath) && !A_IsCompiled)
Menu, Tray, Icon, % icoPath
If !pToken := GdipStart()
{
MsgBox, 48, Ошибка GDI+!
, Убедитесь в наличии gdiplus.dll в вашей системе!
ExitApp
}
Ini_ReadSect("Color-Transparent", "Red", Red_, "FF"
, "Green", Green_, "C7"
, "Blue", Blue_, "00"
, "Transparent", Trans, 130)
Ini_ReadSect("Settings", "Output", Output, "File"
, "Out Directory", OutDirectory, A_ScriptDir
, "Extension", ext, "bmp"
, "Capture Cursor", CaptureCursor, 0
, "High Speed", HighSpeed, 0
, "Resize Pointers", ResizePointers, "Cursors"
, "Quality JPEG", Quality, 100)
Menu, Tray, NoStandard
Menu, Tray, Add, Hide Pause, Pause
Menu, Tray, Add
Menu, Tray, Add, Help F1, Help
if !A_IsCompiled
{
Menu, Tray, Add
Menu, Tray, Add, Reload, Reload
Menu, Tray, Add, Edit, Edit
}
Menu, Tray, Add
Menu, Tray, Add, Exit, ExitApp
Menu, ResizePointers, Add, Cursors, ResizePointers
Menu, ResizePointers, Add, Markers, ResizePointers
Menu, ResizePointers, Check, %ResizePointers%
Menu, OutDirectory, Add, % OutDirectory, OutDirectory
Menu, OutDirectory, Add, Change OutDirectory, OutDirectory
Menu, Quality, Add, Quality = %Quality%`%, QualityOK
Menu, Quality, Add, Change Quality, SetQuality
Menu, Extensions, Add, JPG, :Quality
Menu, Extensions, Add, BMP, Extensions
Menu, Extensions, Add, TIF, Extensions
Menu, Extensions, Add, GIF, Extensions
Menu, Extensions, Add, PNG, Extensions
if Output = File
Menu, Extensions, Check, %ext%
Menu, Output, Add, Clipboard, OutClip
Menu, Output, Add, File, :Extensions
Menu, Output, Check, % Output
Menu, MainMenu, Add, % "Color – Transparent ", Settings
Menu, MainMenu, Add
Menu, MainMenu, Add, Resize Pointers, :ResizePointers
Menu, MainMenu, Add, Out Directory, :OutDirectory
Menu, MainMenu, Add, Output, :Output
Menu, MainMenu, Add
Menu, MainMenu, Add, Capture Cursor, CaptureCursor
if CaptureCursor
Menu, MainMenu, Check, Capture Cursor
Menu, MainMenu, Add, High Speed, HighSpeed
if HighSpeed
Menu, MainMenu, Check, High Speed
Menu, MainMenu, Add, Run on Windows Startup, Startup
FileGetShortcut, % A_Startup "\" RegExReplace(A_ScriptName, "(.*)\..*", "$1.lnk")
, OutTarget,, OutArgs
if (OutTarget = A_ScriptFullPath && OutArgs = 1)
{
Menu, MainMenu, Check, Run on Windows Startup
Startup = 1
}
Menu, MainMenu, Add
Menu, MainMenu, Add, Save F12, AreaScreenshot
Menu, MainMenu, Add, Hide Pause, HideShow
Menu, MainMenu, Add
Menu, MainMenu, Add, Help F1, Help
Menu, MainMenu, Add
Menu, MainMenu, Add, Exit, ExitApp
Gui, +LastFound -Caption +AlwaysOnTop +Owner
WinGet, ID
WinSet, Transparent, 0
Gui, Color, % Red_ Green_ Blue_
Locations = x190 y190|x0 y190|x0 y0|x190 y0|x190 y95|x95 y190|x0 y95|x95 y0
StringSplit, Location, Locations,|
Loop 8
Gui, Add, Text, % "w10 h10 Hidden +0xE hwndText" a_index "ID " Location%a_index%
Gosub, MarkerColor
Loop 7
SetCursor("IDC_HAND", "Static" a_index)
if 1 = 1
{
Gui, Show, h200 w200 Hide, ScreenСatcher
GuiVisible := 0
Menu, Tray, Rename, Hide Pause, Show Pause
}
Else
{
Gui, Show, h200 w200, ScreenСatcher
Melt(ID, Trans, 1), GuiVisible := 1
}
OnMessage(0x201, "WM_LBUTTONDOWN")
OnMessage(0x203, "WM_LBUTTONDBLCLK")
OnMessage(0x204, "WM_RBUTTONDOWN")
Hotkey, LButton, WinResize, Off
SetTimer, %ResizePointers%, 50
Return
Cursors:
S = 10
MouseGetPos, X_M, Y_M, ID_Win
if (ID_Win = ID3) || (ID_Win = ID4)
{
RestoreCursors()
Hotkey, LButton, Off
Return
}
WinGetPos, X, Y, W, H, ahk_id %ID%
XW := X + W, YH := Y + H
if ((X_M <= XW) && (X_M > XW - 2*S) && (Y_M <= YH) && (Y_M > YH - S))
|| ((X_M <= XW) && (X_M > XW - S) && (Y_M <= YH) && (Y_M > YH - 2*S))
Var = 1
else if ((X_M < X + 2*S) && (X_M >= X) && (Y_M <= YH) && (Y_M > YH - S))
|| ((X_M < X + S) && (X_M >= X) && (Y_M <= YH) && (Y_M > YH - 2*S))
Var = 2
else if ((X_M < X + 2*S) && (X_M >= X) && (Y_M < Y + S) && (Y_M >= Y))
|| ((X_M < X + S) && (X_M >= X) && (Y_M < Y + 2*S) && (Y_M >= Y))
Var = 3
else if ((X_M <= XW ) && (X_M > XW - 2*S) && (Y_M < Y + S) && (Y_M >= Y))
|| ((X_M <= XW ) && (X_M > XW - S) && (Y_M < Y + 2*S) && (Y_M >= Y))
Var = 4
else if (X_M <= XW) && (X_M > XW - S) && (Y_M <= YH - S) && (Y_M >= Y + S)
Var = 5
else if (X_M <= XW - S) && (X_M >= X + S) && (Y_M <= YH) && (Y_M > YH - S)
Var = 6
else if (X_M < X + S) && (X_M >= X) && (Y_M <= YH - S) && (Y_M >= Y + S)
Var = 7
else if (X_M <= XW - S) && (X_M >= X + S) && (Y_M < Y + S) && (Y_M >= Y)
Var = 8
else
Var =
if Var
{
Hotkey, LButton, On
if ((Var = 1) || (Var = 3)) && (Cursor != "IDC_SIZENWSE")
RestoreCursors(), SetSystemCursor("IDC_SIZENWSE"), Cursor := "IDC_SIZENWSE"
if ((Var = 2) || (Var = 4)) && (Cursor != "IDC_SIZENESW")
RestoreCursors(), SetSystemCursor("IDC_SIZENESW"), Cursor := "IDC_SIZENESW"
if ((Var = 5) || (Var = 7)) && (Cursor != "IDC_SIZEWE")
RestoreCursors(), SetSystemCursor("IDC_SIZEWE"), Cursor := "IDC_SIZEWE"
if ((Var = 6) || (Var = 8)) && (Cursor != "IDC_SIZENS")
RestoreCursors(), SetSystemCursor("IDC_SIZENS"), Cursor := "IDC_SIZENS"
}
else
{
Hotkey, LButton, Off
RestoreCursors(), Cursor := ""
}
Return
Markers:
MouseGetPos, X_M, Y_M, ID_Win
if (ID_Win = ID3) || (ID_Win = ID4)
{
Hotkey, LButton, Off
Loop 8
GuiControl, Hide, Static%a_index%
Return
}
WinGetPos, X, Y, W, H, ahk_id %ID%
XW := X + W, YH := Y + H
if (X_M <= XW + 20) && (X_M >= XW - 10) && (Y_M <= YH + 20) && (Y_M >= YH - 10)
Var = 1
else if (X_M <= X + 10) && (X_M >= X - 20) && (Y_M <= YH + 20) && (Y_M >= YH - 10)
Var = 2
else if (X_M <= X + 10) && (X_M >= X - 20) && (Y_M <= Y + 10) && (Y_M >= Y - 20)
Var = 3
else if (X_M <= XW + 20) && (X_M >= XW - 10) && (Y_M <= Y + 10) && (Y_M >= Y - 20)
Var = 4
else if (X_M <= XW + 20) && (X_M >= XW - 10) && (Y_M < YH - 10) && (Y_M > Y + 10)
Var = 5
else if (X_M < XW - 10) && (X_M > X + 10) && (Y_M <= YH + 20) && (Y_M >= YH - 10)
Var = 6
else if (X_M <= X + 10) && (X_M >= X - 20) && (Y_M < YH - 10) && (Y_M > Y + 10)
Var = 7
else if (X_M < XW - 10) && (X_M > X + 10) && (Y_M <= Y + 10) && (Y_M >= Y - 20)
Var = 8
else Var =
if Var
{
Hotkey, LButton, On
GuiControl, Show, Static%Var%
Loop 8
if (a_index != Var)
GuiControl, Hide, Static%a_index%
}
else
{
Hotkey, LButton, Off
Loop 8
GuiControl, Hide, Static%a_index%
}
Return
WinResize:
SetTimer, %ResizePointers%, Off
X_M_Old := X_M, Y_M_Old := Y_M
While GetKeyState("LButton", "P")
{
MouseGetPos, X_M, Y_M
dX := X_M - X_M_Old, dY := Y_M - Y_M_Old
IfEqual, Var, 1, WinMove, ahk_id %ID%,,,, W + dX, H + dY
IfEqual, Var, 2, WinMove, ahk_id %ID%,, X + dX,, W - dX, H + dY
IfEqual, Var, 3, WinMove, ahk_id %ID%,, X + dX, Y + dY, W - dX, H - dY
IfEqual, Var, 4, WinMove, ahk_id %ID%,,, Y + dY, W + dX, H - dY
IfEqual, Var, 5, WinMove, ahk_id %ID%,,,, W + dX
IfEqual, Var, 6, WinMove, ahk_id %ID%,,,,, H + dY
IfEqual, Var, 7, WinMove, ahk_id %ID%,, X + dX,, W - dX
IfEqual, Var, 8, WinMove, ahk_id %ID%,,, Y + dY,, H - dY
Sleep, 10
}
SetTimer, %ResizePointers%, On
Return
GuiSize:
GuiControl, Move, Static1, % "x" A_GuiWidth - 10 "y" A_GuiHeight - 10
GuiControl, Move, Static2, % "x0 y" A_GuiHeight - 10
GuiControl, Move, Static3, % "x0 y0"
GuiControl, Move, Static4, % "x" A_GuiWidth - 10 "y0"
GuiControl, Move, Static5, % "x" A_GuiWidth - 10 "y" (A_GuiHeight - 10)/2
GuiControl, Move, Static6, % "x" (A_GuiWidth - 10)/2 "y" A_GuiHeight - 10
GuiControl, Move, Static7, % "x0 y" (A_GuiHeight - 10)/2
GuiControl, Move, Static8, % "x" (A_GuiWidth - 10)/2 "y0"
Return
GuiClose:
Gosub, HideShow
Return
GuiEscape:
Gosub, HideShow
Return
GuiContextMenu:
RestoreCursors()
Menu, MainMenu, Show
Return
QualityOK:
Menu, Extensions, UnCheck, %ext%
Menu, Extensions, Check, % (ext := "jpg")
CheckOutput:
Menu, Output, UnCheck, Clipboard
Menu, Output, Check, File
Output = File
Return
SetQuality:
Old_Quality := Quality
Menu, Extensions, UnCheck, %ext%
Menu, Extensions, Check, % (ext := "jpg")
Gosub, CheckOutput
IfWinExist, ahk_id %ID4%
Goto, 4GuiClose
Gui, 4:+owner1 +LastFound
WinGet, ID4
WinSet, Transparent, 0
Gui, 4:Color, CCC8C0
Gui, 4:Font, s9, Arial
Gui, 4:Add, Text, x11 y17 w29 cBlue, Quality:
Gui, 4:Add, Slider, vQSlider gQualitySet x58 y15 w182 h25 ToolTip AltSubmit, % Quality
Gui, 4:Add, Button, gQOk x80 y50 w90 h23, OK
XQ := X_M - 260 < 0 ? 0 : X_M - 260, YQ := Y_M - 105 < 0 ? 0 : Y_M - 105
Gui, 4:Show, x%XQ% y%YQ% w250 h85, Quality of JPEG
Melt(ID4, 255, 1)
Return
QualitySet:
Quality := QSlider
Return
QOk:
WinClose, ahk_id %ID4%
Return
4GuiClose:
if (Quality != Old_Quality)
Menu, Quality, Rename, Quality = %Old_Quality%`%, Quality = %Quality%`%
Melt(ID4, 255, 0)
Gui, 4:Destroy
Return
Extensions:
Menu, Extensions, UnCheck, %ext%
StringLower, ext, A_ThisMenuItem
Menu, Extensions, Check, %ext%
Gosub, CheckOutput
Return
OutClip:
Menu, Output, UnCheck, File
Menu, Extensions, UnCheck, %ext%
Menu, Output, Check, Clipboard
Output = Clipboard
Return
OutDirectory:
if A_ThisMenuItem = Change OutDirectory
{
Old_OutDirectory := OutDirectory
Gosub, HideShow
FileSelectFolder, OutDir, *%OutDirectory%, 3, Select Out Directory:
OutDirectory := OutDir ? OutDir : OutDirectory
if (OutDirectory != Old_OutDirectory)
Menu, OutDirectory, Rename, %Old_OutDirectory%, %OutDirectory%
if !GuiVisible
Gosub, HideShow
}
Else
Run, % OutDirectory
Return
ResizePointers:
Menu, ResizePointers, UnCheck, %ResizePointers%
SetTimer, %ResizePointers%, Off
ResizePointers := A_ThisMenuItem
Menu, ResizePointers, Check, %ResizePointers%
Loop 8
GuiControl, Hide, Static%a_index%
SetTimer, %ResizePointers%, 50
RestoreCursors()
Return
CaptureCursor:
CaptureCursor := !CaptureCursor
Menu, MainMenu, % CaptureCursor ? "Check" : "UnCheck", Capture Cursor
Return
HighSpeed:
HighSpeed := !HighSpeed
Menu, MainMenu, % HighSpeed ? "Check" : "UnCheck", High Speed
Return
Startup:
if Startup := !Startup
{
FileCreateShortcut, % A_ScriptFullPath
, % A_Startup "\" RegExReplace(A_ScriptName, "(.*)\..*", "$1.lnk")
, % A_ScriptDir, 1
Menu, MainMenu, Check, Run on Windows Startup
}
Else
{
FileDelete, % A_Startup "\" RegExReplace(A_ScriptName, "(.*)\..*", "$1.lnk")
Menu, MainMenu, UnCheck, Run on Windows Startup
}
Return
Settings:
IfWinExist, ahk_id %ID3%
Goto, 3GuiClose
Gui, 3:+owner1 +LastFound
WinGet, ID3
WinSet, Transparent, 0
Gui, 3:Color, CCC8C0
Gui, 3:Font, s9, Arial
Gui, 3:Add, Text, x11 y17 w29 cRed, Red
Gui, 3:Add, Text, x10 y47 w30 cGreen, Green
Gui, 3:Add, Text, x11 y77 w29 cBlue, Blue
Gui, 3:Add, Text, x10 y107 w30 cWhite, Trans
Options = x43 w197 h20 Range0-255 ToolTip AltSubmit
Gui, 3:Add, Slider, vRed gColorSet %Options% y15, 0x%Red_%
Gui, 3:Add, Slider, vGreen gColorSet %Options% y45, 0x%Green_%
Gui, 3:Add, Slider, vBlue gColorSet %Options% y75, 0x%Blue_%
Gui, 3:Add, Slider, vTrans gTransSet %Options% y105, % Trans
Gui, 3:Add, Button, g3GuiClose x80 y140 w90 h23, OK
WinGetPos, X, Y, W, H, ahk_id %ID%
3Gui_Y := (Y + H + 15 + 180 <= A_ScreenHeight) ? Y + H + 15 : Y - 180 - 35
3Gui_Y := (3Gui_Y < 0) ? 0 : 3Gui_Y
3Gui_X := (X+(W-250)/2+250 > A_ScreenWidth) ? A_ScreenWidth - 250 : X + (W-256)/2
3Gui_X := (3Gui_X < 0) ? 0 : 3Gui_X
GuiControl, 3:Focus, Static1
Gui, 3:Show, x%3Gui_X% y%3Gui_Y% w250 h180, Color – Transparent
Melt(ID3, 255, 1)
Return
ColorSet:
%A_GuiControl%_ := SubStr("00" . Trans(%A_GuiControl%, 10, 16), -1)
Gui, 1:Color, % Red_ Green_ Blue_
MarkerColor:
MarkerColor := InvertColor(Red_, Green_, Blue_)
Loop 8
SetColorToControl(Text%a_index%ID, MarkerColor)
Return
TransSet:
WinSet, Transparent, % Trans, ahk_id %ID%
Return
3GuiClose:
Melt(ID3, 255, 0)
Gui, 3:Destroy
Return
Help:
IfWinExist, ahk_id %ID5%
Goto, 5GuiClose
if ((X < 540) && (Y < 590)) && GuiVisible
{
DetectHiddenWindows On
Melt(ID, Trans, 0)
WinMove, ahk_id %ID%,, 540
Melt(ID, Trans, 1)
}
Gui, 5:Default
Gui, +LastFound +Resize
WinGet, ID5
Gui, Color, White
Gui, Add, Text, x0 y0 w515 h550 -Background
Gui, Add, Text, x4 y4 w507 h73 +0x6
Gui, Font, s10 bold, Arial
Gui, Add, Text, x9 y11 BackgroundTrans, Содержание:
Gui, Font, s9 norm underline
Gui, Add, Text, gPass x30 y32 cBlue BackgroundTrans, Работа с программой
Gui, Add, Text, gPass xp yp+16 cBlue BackgroundTrans, Контекстное меню
Gui, Add, Text, gPass x200 y32 cBlue BackgroundTrans, Меню иконки в трее
Gui, Add, Text, gPass xp yp+16 cBlue BackgroundTrans, Горячие клавиши
Gui, Font, s10 norm
HelpText =
(Join
Программа «ScreenСatcher» создана для получения скриншотов экрана или его областе
й и сохранения их в файлы с расширениями jpg, bmp, tif, gif, png.`r`n
`r`n Работа с программой.`r`n`r`n После запу
ска файла на экране появляется полупрозрачное окно, которое можно перемещать левой кнопко
й мыши и менять его размеры.`r`n`r`n Чтобы получить скриншот области экрана, размести
те окно точно над ней и кликните дважды в пределах окна или нажмите F12. В зависимос
ти от установок, доступных через меню, изображение будет помещено либо в буфер обмена
, либо записано в файл, который появится в папке вывода (по умолчанию – в папке скрипта)
. Перед получением скриншота окно программы можно скрыть, если оно мешает, нажатием клав
иши Pause или средней кнопки мыши. В этом случае программа сработает при нажатии F12.
`r`n Чтобы получить скриншот всего экрана, скройте окно программы и нажмите PrintScre
en.`r`n Для получения скриншота активного окна нажмите Shift + PrintScreen
.`r`n`r`n Управление программой осуществляется горячими клавишами, через контекстно
е меню главного окна (клик правой кнопкой мыши в пределах окна) и меню иконки программ
ы в трее (клик правой кнопкой мыши на иконке программы в трее)
.`r`n`r`n Контекстное меню.`r`n`r`nColo
r – Transparent.`r`nУстановки цвета и прозрачности окна.`r`n`r`nResize Pointers.`r`nВыбо
р индикатора, отображаемого при изменении размеров окна: модифицированный курсор мыши, либ
о цветные маркеры.`r`n`r`nOut Directory.`r`nПри выборе этого пункта появляется подменю с н
азванием текущей папки, в которую будут помещаться файлы скриншотов. Для смены папки кликн
ите это подменю.`r`n`r`nOutput.`r`nПри выборе подменю Clipboard скриншот будет записыватьс
я в буфер обмена. File — выбор расширения файлов, в которые будут записываться скриншоты
. При выборе JPG открывается подменю с двумя пунктами. 1-ый – текущее значение качества (с
тепени сжатия) JPEG, кликните его, если оно Вас устраивает. 2-ой – Change Quality – смен
а качества JPEG.`r`n`r`nCapture Cursor.`r`nПри установке галочки в этот пункт меню в скрин
шот будет включен курсор.`r`n`r`nHigh Speed.`r`nЕсли преполагается делать скриншоты чаще
, чем раз в секунду, поставьте галочку в этот пункт меню. При выборе High Speed перед пол
учением скришота лучше скрыть окно скрипта. В этом режиме к названию файла бу
дут добавляться милисекунды.`r`n`r`nRun on Windows Startup.`r`nПри выборе этого пункта созд
аётся ярлык программы в папке автозагрузки текущего пользователя, и при следующей загрузк
е программа запустится автоматически, окно её первоначально будет скрыто. При снятии галочк
и с этого пункта ярлык удаляется.`r`n`r`nSave.`r`nПолучить скриншот области экрана под окно
м программы.`r`n`r`nHide.`r`nСпрятать окно программы
.`r`n`r`n Меню иконки в трее.`r`n`r`nHide.`r`nСп
рятать окно программы.`n`nShow.`nПоказать окно программы.`r`n
`r`n Горячие клавиши.`n`nMButton (средняя к
нопка мыши) — скрыть окно.`nCtrl + MButton — скрыть/показать окно.`nPause – скрыть/показат
ь окно.`nScrollLock – показать окно в центре экрана.`nF12 – скриншот области экрана, лежаще
й непосредственно под окном программы.`nPrintScreen — скриншот всего экрана.`nShift + Print
Screen – скриншот активного окна.`nEsc – закрытие окон установок и справки, если открыты, и
ли скрытие главного окна.`nЕсли открыто окно установок, щелчок ЛКМ по названию слайдер
а – установка в левую крайнюю позицию, ПКМ – в правую крайнюю.`nF1 – вызов справки.
)
Gui, Add, Edit, x3 y81 w509 h466 ReadOnly hwndEditID, % HelpText
GuiControl, Focus, Static1
Gui, Show, x0 y0 w515 h550, ScreenСatcher Help
Return
Reload:
Reload
Return
Edit:
Edit
Return
Pass:
SendMessage, EM_LINEFROMCHAR := 201, InStr(HelpText, A_GuiControl) - 1,,, ahk_id %EditID%
GotoLineUp(ErrorLevel + 1, EditID)
SendInput, {Home}+{Right 3}
Return
5GuiSize:
GuiControl, Move, Static1, w%A_GuiWidth% h%A_GuiHeight%
GuiControl, Move, Static2, % "w" A_GuiWidth - 8
GuiControl, MoveDraw, Edit1, % "w" A_GuiWidth - 6 "h" A_GuiHeight - 84
Return
5GuiClose:
Gui, 5:Destroy
Return
Exit:
GdipShutdown(pToken)
While (idx := a_index + 2) < 6
IfWinExist, % "ahk_id" ID%idx%
Gosub, %idx%GuiClose
if GuiVisible
{
Melt(ID, Trans, 0)
Gui, Destroy
}
RestoreCursors()
Ini_WriteSect("Color-Transparent", "Red", Red_
, "Green", Green_
, "Blue", Blue_
, "Transparent", Trans)
Ini_WriteSect("Settings", "Output", Output
, "Out Directory", OutDirectory
, "Extension", ext
, "Capture Cursor", CaptureCursor
, "High Speed", HighSpeed
, "Resize Pointers", ResizePointers
, "Quality JPEG", Quality)
ExitApp:
ExitApp
Melt(hWnd, Trans, Appear, N = 20)
{
WinShow, ahk_id %hWnd%
While A_Index * N < Trans
{
WinSet, Transparent, % Appear ? A_Index * N : Trans - A_Index * N, ahk_id %hWnd%
Sleep, 10
}
if Appear
WinSet, Transparent, % Trans, ahk_id %hWnd%
Else
WinHide, ahk_id %hWnd%
}
WM_LBUTTONDBLCLK()
{
if A_Gui = 1
Gosub, AreaScreenshot
}
WM_LBUTTONDOWN()
{
WM_NCLBUTTONDOWN := 0xA1, HTCAPTION := 2
if (A_Gui = 1) && (!Var || GetKeyState("Alt"))
PostMessage, WM_NCLBUTTONDOWN, HTCAPTION
if A_Gui = 3
SetValue1(0)
if A_Gui = 4
SetValue2(0)
}
WM_RBUTTONDOWN()
{
if A_Gui = 3
SetValue1(255)
if A_Gui = 4
SetValue2(255)
}
SetValue1(Pos)
{
local Control, Text
MouseGetPos,,,, Control
if !InStr(Control, "Static")
Return
GuiControl, 3:, % "msctls_trackbar32" SubStr(Control, 7), % Pos
Gui, 3:Submit, NoHide
GuiControlGet, Text, 3:, % Control
%Text%_ := SubStr("00" . Trans(%Text%, 10, 16), -1)
Gui, 1:Color, % Red_ Green_ Blue_
Gosub, MarkerColor
Gosub, TransSet
}
SetValue2(Pos)
{
local Control
MouseGetPos,,,, Control
if !InStr(Control, "Static")
Return
GuiControl, 4:, msctls_trackbar321, % Pos
Gui, 4:Submit, NoHide
Quality := QSlider
}
InvertColor(Red, Green, Blue)
{
_Red := SubStr("00" . Trans(Trans(Red, 16, 10) ^ 255, 10, 16), -1)
_Green := SubStr("00" . Trans(Trans(Green, 16, 10) ^ 255, 10, 16), -1)
_Blue := SubStr("00" . Trans(Trans(Blue, 16, 10) ^ 255, 10, 16), -1)
Return "0x" _Red _Green _Blue
}
Ini_WriteSect(Section, Key1, Value1, Key2 = "", Value2 = ""
, Key3 = "", Value3 = "", Key4 = "", Value4 = "", Key5 = "", Value5 = ""
, Key6 = "", Value6 = "", Key7 = "", Value7 = "", Key8 = "", Value8 = ""
, Key9 = "", Value9 = "", Key10 = "", Value10 = "")
{
; Пишет секцию ini-файла в директории скрипта, за раз не более 10-ти ключей
FileName := A_ScriptDir "\" RegExReplace(A_ScriptName, "(.*)\..*", "$1.ini")
While Key%a_index%
IniWrite, % Value%a_index%, % FileName, % Section, % Key%a_index%
}
Ini_ReadSect(Section, Key1, ByRef var1, Default1 = "", Key2 = "", ByRef var2 = "", Default2 = ""
, Key3 = "", ByRef var3 = "", Default3 = "", Key4 = "", ByRef var4 = "", Default4 = ""
, Key5 = "", ByRef var5 = "", Default5 = "", Key6 = "", ByRef var6 = "", Default6 = ""
, Key7 = "", ByRef var7 = "", Default7 = "", Key8 = "", ByRef var8 = "", Default8 = ""
, Key9 = "", ByRef var9 = "", Default9 = "", Key10 = "", ByRef var10 = "", Default10 = "")
{
; Читает секцию ini-файла в директории скрипта, за раз не более 10-ти ключей
FileName := A_ScriptDir "\" RegExReplace(A_ScriptName, "(.*)\..*", "$1.ini")
While Key%a_index%
IniRead, var%a_index%, % FileName, % Section, % Key%a_index%, % Default%a_index%
}
Trans(Number, N, K)
{
; Переводит число Number из системы счисления N в систему счисления K. Number должно
; быть написано без префикса, и, если содержит буквенные символы, в кавычках.
; Возвращает значение без префикса.
if N = 10
Return Trans_Dec(Number, K)
if K = 10
Return Trans_ToDec(Number, N)
Else
Return Trans_Dec(Trans_ToDec(Number, N), K)
}
Trans_Dec(Number, K)
{
if K = 16
{
SetFormat, integer, hex
TransNumber := SubStr(Number + 0, 3)
SetFormat, integer, dec
Return TransNumber
}
if (Number < K)
Return Number < 10 ? Number : Chr(Asc("A") + Number - 10)
Mod := Mod(Number,K) < 10 ? Mod(Number,K) : Chr(Asc("A") + Mod(Number,K) - 10)
Return Trans_Dec(Floor(Number/K),K) . Mod
}
Trans_ToDec(Number, N)
{
if N = 16
{
SetFormat, integer, d
Number := "0x" . Number
Return Number + 0
}
StringCaseSense on
if StrLen(Number) = 1
{
if Number between a and z
Number := Asc(Number) - Asc("a") + 10
if Number between A and Z
Number := Asc(Number) - Asc("A") + 10
Return Number
}
SubString := SubStr(Number,1,1)
if SubString between a and z
SubString := Asc(SubString) - Asc("a") + 10
if SubString between A and Z
SubString := Asc(SubString) - Asc("A") + 10
Return SubString*N**(StrLen(Number)-1) + Trans_ToDec(SubStr(Number,2),N)
}
GotoLineUp(N, Hwnd_Edit)
{
; Осуществляет переход к строке с номером N в контроле Edit, строка, если
; возможно, становится первой видимой
EM_LINEINDEX := 0xBB, EM_SETSEL := 0xB1, EM_SCROLLCARET := 0xB7
EM_GETFIRSTVISIBLELINE := 0xCE, EM_LINESCROLL := 0xB6
SendMessage, EM_LINEINDEX, N - 1,,, ahk_id %Hwnd_Edit%
SendMessage, EM_SETSEL, Errorlevel, Errorlevel,, ahk_id %Hwnd_Edit%
SendMessage, EM_SCROLLCARET,,,, ahk_id %Hwnd_Edit%
SendMessage, EM_GETFIRSTVISIBLELINE,,,, ahk_id %Hwnd_Edit%
SendMessage, EM_LINESCROLL,, N - 1 - Errorlevel,, ahk_id %Hwnd_Edit%
ControlFocus,, ahk_id %Hwnd_Edit%
SendInput, {End}
}
SetCursor(pShape, pCtrl="")
{
return SetCursor_(pShape, pCtrl, 0)
}
SetCursor_(wparam, lparam, msg)
{
global ID, ID3, ID5
static WM_SETCURSOR = 0x20, WM_MOUSEMOVE = 0x200
static IDC_HAND = 32649, IDC_ARROW = 32512
static hover, cursor, ctrls = "`n", init
if !init
init := 1, OnMessage(WM_SETCURSOR, "SetCursor_"), OnMessage(WM_MOUSEMOVE, "SetCursor_")
if A_Gui =
{
cursor := DllCall("LoadCursor", UInt, 0, Int, %WPARAM%, ptr)
ctrls .= lparam "=" cursor "`n"
}
If (msg = WM_SETCURSOR)
ifEqual, hover, 1, return 1
if (msg = WM_MOUSEMOVE)
{
MouseGetPos,,, ID_Win, Control
if (ID_Win = ID)
Return
If j := InStr(ctrls, "`n" Control "=")
{
if (ID_Win = ID5) && (SubStr(Control, 7) < 4)
{
DllCall("SetCursor", UInt, IDC_ARROW), hover := ""
Return
}
hover := true
j += 2 + StrLen(Control)
j := SubStr(ctrls, j, InStr(ctrls, "`n", 0, j) - j + 1)
DllCall("SetCursor", UInt, j)
}
else DllCall("SetCursor", UInt, IDC_ARROW), hover := ""
}
}
SetSystemCursor(IDC)
{
IDC_SIZENWSE = 32642
IDC_SIZENESW = 32643
IDC_SIZEWE = 32644
IDC_SIZENS = 32645
IDC_ARROW = 32512
CursorHandle := DllCall( "LoadCursor", Uint, 0, Int, %IDC%, ptr)
DllCall("SetSystemCursor", ptr, CursorHandle, Int, IDC_ARROW)
}
RestoreCursors()
{
SPI_SETCURSORS = 0x57
DllCall("SystemParametersInfo", UInt, SPI_SETCURSORS, UInt, 0, UInt, 0, UInt, 0 )
}
SetColorToControl(hwnd, Color)
{
WinGetPos,,, w, h, ahk_id %hwnd%
sColor := 0xFF000000|Color
DllCall("gdiplus\GdipCreateSolidFill", Int, sColor, "ptr*", pBrush)
DllCall("gdiplus\GdipCreateBitmapFromScan0", Int, w
, Int, h, Int, 0, Int, 0x26200A, UInt, 0, "ptr*", pBitmap)
DllCall("gdiplus\GdipGetImageGraphicsContext", ptr, pBitmap, "ptr*", G)
DllCall("gdiplus\GdipFillRectangle"
, ptr, G, ptr, pBrush, "float", 0, "float", 0, "float", w, "float", h)
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap"
, ptr, pBitmap, "ptr*", hBitmap, Int, 0xffffffff)
SendMessage, STM_SETIMAGE := 0x172, 0x0, hBitmap,, ahk_id %hwnd%
DllCall("DeleteObject", ptr, ErrorLevel)
DllCall("gdiplus\GdipDeleteBrush", ptr, pBrush)
DllCall("gdiplus\GdipDeleteGraphics", ptr, G)
DllCall("gdiplus\GdipDisposeImage", ptr, pBitmap)
DllCall("DeleteObject", ptr, hBitmap)
}
CaptureScreen(aRect, sFile, nQuality, Cursor)
{
pBitmap := BitmapFromScreen(aRect, Cursor, 0x40000000 | 0x00CC0020)
If sFile = 0
SetBitmapToClipboard(pBitmap)
Else
SaveBitmapToFile(pBitmap, sFile, nQuality)
DllCall("gdiplus\GdipDisposeImage", ptr, pBitmap)
}
BitmapFromScreen(Screen, Cursor, Raster="")
{
if (Screen = 0)
{
Sysget, x, 76
Sysget, y, 77
Sysget, w, 78
Sysget, h, 79
}
else
{
StringSplit, S, Screen, |
x := S1, y := S2, w := S3, h := S4
}
chdc := DllCall("CreateCompatibleDC", ptr, 0, ptr)
VarSetCapacity(bi, 40, 0)
NumPut(40, bi, 0), NumPut(w, bi, 4), NumPut(h, bi, 8)
NumPut(1, bi, 12, "ushort"), NumPut(32, bi, 14, "ushort")
hbm := DllCall("CreateDIBSection"
, ptr , chdc, ptr , &bi, UInt , 0, "ptr*", 0, UInt , 0, UInt , 0, ptr)
obm := DllCall("SelectObject", ptr, chdc, ptr, hbm, ptr)
hhdc := DllCall("GetDC", ptr, 0, ptr)
DllCall("gdi32\BitBlt", ptr, chdc, Int, 0, Int, 0, Int, w, Int, h
, ptr, hhdc, Int, x, Int, y, UInt, Raster)
DllCall("ReleaseDC", ptr, 0, ptr, hhdc)
if Cursor
CaptureCursor(chdc, x, y)
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", ptr, hbm, UInt, 0, "ptr*", pBitmap)
DllCall("SelectObject", ptr, chdc, ptr, obm)
DllCall("DeleteObject", ptr, hbm)
DllCall("DeleteDC", ptr, hhdc)
DllCall("DeleteDC", ptr, chdc)
return pBitmap
}
CaptureCursor(hDC, nL, nT)
{
VarSetCapacity(mi, 16 + A_PtrSize, 0)
NumPut(16 + A_PtrSize, mi)
DllCall("GetCursorInfo", ptr, &mi)
bShow := NumGet(mi, 4, "UInt")
hCursor := NumGet(mi, 8)
xCursor := NumGet(mi, 8 + A_PtrSize, "UInt")
yCursor := NumGet(mi, 12 + A_PtrSize, "UInt")
If bShow && hCursor:=DllCall("CopyIcon", ptr, hCursor, ptr)
{
VarSetCapacity(ni, 8 + A_PtrSize * 3, 0)
DllCall("GetIconInfo", ptr, hCursor, ptr, &ni)
bIcon := NumGet(ni, 0, "UInt")
xHotspot := NumGet(ni, 4, "UInt")
yHotspot := NumGet(ni, 8, "UInt")
hBMMask := NumGet(ni, 8 + A_PtrSize)
hBMColor := NumGet(ni, 8 + A_PtrSize * 2)
DllCall("DrawIcon", ptr, hDC, Int, xCursor - xHotspot - nL
, Int, yCursor - yHotspot - nT, ptr, hCursor)
DllCall("DestroyIcon", ptr, hCursor)
If hBMMask
DllCall("DeleteObject", ptr, hBMMask)
If hBMColor
DllCall("DeleteObject", ptr, hBMColor)
}
}
SetBitmapToClipboard(pBitmap) {
; modified by Marius Șucan to have this function report errors
Static Ptr := "UPtr"
off1 := A_PtrSize = 8 ? 52 : 44
off2 := A_PtrSize = 8 ? 32 : 24
pid := DllCall("GetCurrentProcessId","uint")
hwnd := WinExist("ahk_pid " . pid)
r1 := DllCall("OpenClipboard", Ptr, hwnd)
If !r1
Return -1
hBitmap := CreateHBITMAPFromBitmap(pBitmap, 0)
If !hBitmap
{
DllCall("CloseClipboard")
Return -3
}
r2 := DllCall("EmptyClipboard")
If !r2
{
DllCall("DeleteObject", ptr, hBitmap)
DllCall("CloseClipboard")
Return -2
}
DllCall("GetObject", Ptr, hBitmap, "int", VarSetCapacity(oi, A_PtrSize = 8 ? 104 : 84, 0), Ptr, &oi)
hdib := DllCall("GlobalAlloc", "uint", 2, Ptr, 40+NumGet(oi, off1, "UInt"), Ptr)
pdib := DllCall("GlobalLock", Ptr, hdib, Ptr)
DllCall("RtlMoveMemory", Ptr, pdib, Ptr, &oi+off2, Ptr, 40)
DllCall("RtlMoveMemory", Ptr, pdib+40, Ptr, NumGet(oi, off2 - A_PtrSize, Ptr), Ptr, NumGet(oi, off1, "UInt"))
DllCall("GlobalUnlock", Ptr, hdib)
DllCall("DeleteObject", ptr, hBitmap)
r3 := DllCall("SetClipboardData", "uint", 8, Ptr, hdib) ; CF_DIB = 8
DllCall("CloseClipboard")
DllCall("GlobalFree", Ptr, hdib)
E := r3 ? 0 : -4 ; 0 - success
Return E
}
CreateHBITMAPFromBitmap(pBitmap, Background:=0xffffffff) {
; background should be zero, to not alter alpha channel of the image
hBitmap := 0
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "UPtr", pBitmap, "UPtr*", hBitmap, "int", Background)
return hBitmap
}
SaveBitmapToFile(pBitmap, sOutput, Quality=75)
{
Ptr := A_PtrSize ? "UPtr" : "UInt"
SplitPath, sOutput,,, Extension
if Extension not in 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"
Loop, %nCount%
{
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 {
Loop, %nCount%
{
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 Extension in .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)
Loop, % NumGet(EncoderParameters, "UInt") ;%
{
elem := (24+(A_PtrSize ? A_PtrSize : 4))*(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 (!A_IsUnicode)
{
nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sOutput, "int", -1, Ptr, 0, "int", 0)
VarSetCapacity(wOutput, nSize*2)
DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sOutput, "int", -1, Ptr, &wOutput, "int", nSize)
VarSetCapacity(wOutput, -1)
if !VarSetCapacity(wOutput)
return -4
E := DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, Ptr, &wOutput, Ptr, pCodec, "uint", p ? p : 0)
}
else
E := DllCall("gdiplus\GdipSaveImageToFile", Ptr, pBitmap, Ptr, &sOutput, Ptr, pCodec, "uint", p ? p : 0)
return E ? -5 : 0
}
GdipStart()
{
if !DllCall("GetModuleHandle", Str, "gdiplus")
DllCall("LoadLibrary", Str, "gdiplus")
VarSetCapacity(si, 16, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", "ptr*", pToken, ptr, &si, UInt, 0)
return pToken
}
GdipShutdown(pToken)
{
DllCall("gdiplus\GdiplusShutdown", ptr, pToken)
if hModule := DllCall("GetModuleHandle", Str, "gdiplus")
DllCall("FreeLibrary", ptr, hModule)
return 0
}
#IfWinExist ScreenСatcher ahk_class AutoHotkeyGUI
MButton:: Goto, HideShow
#IfWinActive ScreenСatcher ahk_class AutoHotkeyGUI
F1:: Goto, Help
#IfWinActive ScreenСatcher Help ahk_class AutoHotkeyGUI
F1:: Goto, Help
~WheelUp::
~WheelDown::
GuiControl, 5:Focus, Edit1
Return
#IfWinExist Color – Transparent ahk_class AutoHotkeyGUI
Esc:: Goto, 3GuiClose
#IfWinExist Quality of JPEG ahk_class AutoHotkeyGUI
Esc:: Goto, 4GuiClose
#IfWinExist ScreenСatcher Help ahk_class AutoHotkeyGUI
Esc:: Goto, 5GuiClose
#IfWinExist
F12:: ; Скриншот области под окном скрипта
AreaScreenshot:
Critical
OutFileName := A_Year A_MM A_DD "-" A_Hour A_Min A_Sec (HighSpeed ? "-" A_MSec : "")
IfWinExist, ahk_id %ID%
{
Vis = 1
WinGetPos, X, Y, W, H, ahk_id %ID%
Melt(ID, Trans, 0, 50)
}
Else
{
Vis = 0
DetectHiddenWindows, On
WinGetPos, X, Y, W, H, ahk_id %ID%
}
Rect := X "|" Y "|" W "|" H
IfNotExist, % OutDirectory
OutDirectory := A_ScriptDir
if Output = File
CaptureScreen(Rect, OutDirectory "\" OutFileName "." ext, Quality, CaptureCursor)
Else
CaptureScreen(Rect, 0, Quality, CaptureCursor)
if Vis = 1
Melt(ID, Trans, 1, 50)
Return
PrintScreen:: ; Скриншот всего экрана
Critical
OutFileName := A_Year A_MM A_DD "-" A_Hour A_Min A_Sec (HighSpeed ? "-" A_MSec : "")
if Output = File
CaptureScreen(0, OutDirectory "\" OutFileName "." ext, Quality, CaptureCursor)
Else
CaptureScreen(0, 0, Quality, CaptureCursor)
Return
+PrintScreen:: ; Shift + PrintScreen — Скриншот активного окна
Critical
OutFileName := A_Year A_MM A_DD "-" A_Hour A_Min A_Sec (HighSpeed ? "-" A_MSec : "")
WinGetPos, X, Y, W, H, A
Rect := X "|" Y "|" W "|" H
if Output = File
CaptureScreen(Rect, OutDirectory "\" OutFileName "." ext, Quality, CaptureCursor)
Else
CaptureScreen(Rect, 0, Quality, CaptureCursor)
Return
^MButton:: ; Ctrl + MButton — показать/скыть окно
Pause::
HideShow:
Melt(ID, Trans, GuiVisible := !GuiVisible)
if GuiVisible
Menu, Tray, Rename, Show Pause, Hide Pause
Else
Menu, Tray, Rename, Hide Pause, Show Pause
Return
ScrollLock:: ; показать окно в центре экрана
if GuiVisible
Melt(ID, Trans, 0)
Else
Menu, Tray, Rename, Show Pause, Hide Pause
Gui, Show, % "x" A_ScreenWidth/2 - 100 "y" A_ScreenHeight/2 - 118 "w200 h200"
Melt(ID, 130, 1), Trans := 130, GuiVisible := 1
GuiControl, 3:, Trans, 130
Return
Если кто-нибудь захочет задать вопрос по работе скрипта или сообщить о замеченных багах — прошу писать в эту тему.
В архиве скрипт, иконка и скомпилированный файл.