1

Тема: AutoHotkey: сохранение скриншота экрана в файл

Скрипт сохраняет скриншот экрана в корне диска C: в виде bmp-файла по клавише F12.

F12::
;работаем со скрытыми окнами
DetectHiddenWindows, On
;делаем снимок экрана
Send, {PRINTSCREEN} ; снимок всего экрана (PrtSc)
;Send, !{PRINTSCREEN} ; снимок активного окна (Alt + PrtSc)
;создаём пустой файл
FileAppend,, C:\PrScr.bmp
;открываем пустой файл в скрытом окне Paint
Run, mspaint C:\PrScr.bmp,, Hide
;ждём запуска Paint
WinWait, PrScr.bmp - Paint
;команда меню "Правка" - "Вставить"
PostMessage, 0x111, 57637, 0, , PrScr.bmp - Paint
;команда меню "Файл" - "Сохранить"
PostMessage, 0x111, 57603, 0, , PrScr.bmp - Paint
;команда меню "Файл" - "Выход"
PostMessage, 0x111, 57665, 0, , PrScr.bmp - Paint
;ждём завершения работы Paint
WinWaitClose, PrScr.bmp - Paint
Предложения в русском языке начинаются с большой буквы и заканчиваются точкой.
В названии ветки всегда должен быть указан язык программирования или среда исполнения скрипта, если это возможно.

2 (изменено: teadrinker, 2009-07-30 21:20:40)

Re: AutoHotkey: сохранение скриншота экрана в файл

Следующий скрипт даёт возможность сохранить в файл скриншот произвольно выбранной области экрана. Управление через контекстное меню главного окна.
Перед запуском убедитесь, что Ваша версия AHK не ниже, чем 1.0.48. Если Ваша ОС старше, чем Windows XP, Вам потребуется скачать и поместить в директорию скрипта gdiplus.dll.
Пред началом работы прочитайте Help (F1).

    #NoEnv
    #UseHook
    OnExit, Exit
    SetWinDelay, 0
    SetBatchLines, -1
    CoordMode, Mouse

    Menu, Tray, Icon, Shell32.dll, 95

    Ini_ReadSect("Color", "Red", Red_, "FF", "Green", Green_, "C7", "Blue", Blue_, "00")
    Ini_ReadSect("Transparent", "Trans", Trans, 130)
    Ini_ReadSect("Extension", "ext", ext, "bmp")
    Ini_ReadSect("Out Directory", "OutDirectory", OutDirectory, A_ScriptDir)
    Ini_ReadSect("Resize Pointers", "ResizePointers", ResizePointers, "Cursors")
    Ini_ReadSect("Quality JPEG", "Quality", Quality, 100)

    Menu, Tray, NoStandard
    Menu, Tray, Add, Hide                  Pause, Pause
    Menu, Tray, Add
    Menu, Tray, Add, Help                  F1, Help
    Menu, Tray, Add
    Menu, Tray, Add, Exit                   Esc, Exit

    Menu, ResizePointers, Add, Cursors, ResizePointers
    Menu, ResizePointers, Add, Markers, ResizePointers
    Menu, ResizePointers, Check, %ResizePointers%

    Menu, OutDirectory, Add, % 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
    Menu, Extensions, Check, %ext%

    Menu, MainMenu, Add, % "Color – Transparent  ", Settings
    Menu, MainMenu, Add
    Menu, MainMenu, Add, Resize Pointers, :ResizePointers
    Menu, MainMenu, Add, Out Directory, :OutDirectory
    Menu, MainMenu, Add, Extension, :Extensions
    Menu, MainMenu, Add
    Menu, MainMenu, Add, Save                              PrintScreen, PrintScreen
    Menu, MainMenu, Add, Hide                               Pause, Pause
    Menu, MainMenu, Add
    Menu, MainMenu, Add, Help                               F1, Help
    Menu, MainMenu, Add
    Menu, MainMenu, Add, Exit                                Esc, GuiClose

    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 hwndText" a_index "ID " Location%a_index%

    Gosub, MarkerColor
    Control_Colors(ID, "RCB", 0, 0)

    Loop 7
        SetCursor("IDC_HAND", "Static" a_index)

    Gui, Show, h200 w200, ScreenСatcher

    OnMessage(0x201, "WM_LBUTTONDOWN")
    OnMessage(0x203, "WM_LBUTTONDBLCLK")
    OnMessage(0x204, "WM_RBUTTONDOWN")

    Hotkey, LButton, WinResize, Off
    Melt(ID, Trans, 1), GuiVisible := 1
    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

GuiContextMenu:
    RestoreCursors()
    Menu, MainMenu, Show
    Return

QualityOK:
    Menu, Extensions, UnCheck, %ext%
    Menu, Extensions, Check, % (ext := "jpg")
    Return

SetQuality:
    Old_Quality := Quality
    Menu, Extensions, UnCheck, %ext%
    Menu, Extensions, Check, % (ext := "jpg")
    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%
    Return

OutDirectory:
    Old_OutDirectory := OutDirectory
    Gosub, Pause
    FileSelectFolder, OutDir, *%OutDirectory%, 3, Select Out Directory:
    OutDirectory := OutDir ? OutDir : OutDirectory
    if (OutDirectory != Old_OutDirectory)
        Menu, OutDirectory, Rename, %Old_OutDirectory%, %OutDirectory%
    if !GuiVisible
        Gosub, Pause
    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

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
        Control_Colors(Text%a_index%ID, "Set", 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
    WinSet, Transparent, 0
    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.`n
`n                                        Работа с программой.`n`n     После запуска ф
айла на экране появляется полупрозрачное окно, которое можно перемещать левой кнопкой м
ыши и менять его размеры.`n`n     Чтобы получить скриншот области экрана, разместите ок
но точно над ней и кликните дважды в пределах окна или нажмите PrintScreen. Изображени
е будет помещено в буфер обмена и записано в файл
, который появится в выбранной папке (по умолчанию – в папке скрипта).`n     Чтобы полу
чить скриншот всего экрана, скройте окно программы нажатием средне
й кнопки мыши и нажмите клавишу PrintScreen.`n     Для получения скриншота активного ок
на нажмите Alt + PrintScreen.`n`n     Управление программой осуществляется через контек
стное меню главного окна (клик правой кнопкой мыши в пределах окна) и меню иконки програ
ммы в трее (клик правой кнопкой мыши на иконке программы в трее).`n
`n                                          Контекстное меню.`n`nColor – Transparent.`nУ
становки цвета и прозрачности окна.`n`nResize Pointers.`nВыбор индикатора, отображаемог
о при изменении размеров окна: модифицированный курсор мыши, либо цветные маркеры.`n`nOu
t Directory.`nПри выбо
ре этого пункта появляется подменю с названием текущей папки, в которую будут помещатьс
я файлы скриншотов. Для смены папки кликните это подменю.`n`nExtension.`nВыбор расширени
я файлов, в которые будут записываться скриншоты. При выборе JPG открывается подменю с д
вумя пунктами. 1-ый – текущее значение качества (степени сжатия) JPEG, кликните его, есл
и оно Вас устраивает. 2-ой – Change Quality – смена качества JPEG.`n`nSave.`nСохранит
ь в файл скриншот области экрана под окном программы.`n`nHide.`nСпрятать окно программы
.`n`n                                          Меню иконки в трее.`n`nHide.`nСпрятать ок
но программы.`n`nShow.`nПоказать окно программы.`n
`n                                            Горячие клавиши.`n`nP
ause, а также щелчок средней кнопкой мыши – скрыть/показать окно.`nScrollLock – вернут
ь окно в центр экрана.`nPrintScreen – если окно скрипта скрыто, скриншот всего экрана, е
сли видимо – скриншот области экрана, лежащей непосредственно под окном.`nAlt + PrintScr
een – скриншот активного окна.`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
    Melt(ID5, 255, 1, 40)
    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:
    Melt(ID5, 255, 0, 40)
    Gui, 5:Destroy
    Return

Exit:
    While (idx := a_index + 2) < 6
        IfWinExist, % "ahk_id" ID%idx%
            Gosub, %idx%GuiClose
    if GuiVisible
    {
        Melt(ID, Trans, 0)
        Gui, Destroy
    }
    Ini_WriteSect("Color", "Red", Red_, "Green", Green_, "Blue", Blue_)
    Ini_WriteSect("Transparent", "Trans", Trans)
    Ini_WriteSect("Extension", "ext", ext)
    Ini_WriteSect("Out Directory", "OutDirectory", OutDirectory)
    Ini_WriteSect("Resize Pointers", "ResizePointers", ResizePointers)
    Ini_WriteSect("Quality JPEG", "Quality", Quality)

    RestoreCursors()
    ExitApp

#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
PrintScreen::
    IfWinExist, ahk_id %ID%
    {
        WinGetPos, X, Y, W, H, ahk_id %ID%
        Melt(ID, Trans, 0, 50)
        Rect := X "," Y "," X + W "," Y + H
    }
    Else
    {
        Send, {PrintScreen}
        Goto, ~!PrintScreen
    }
    IfNotExist, % OutDirectory
        OutDirectory := A_ScriptDir
    CaptureScreen(Rect, 0, Quality)
    CaptureScreen(Rect, OutDirectory "\" A_Year  A_MM  A_DD "-" A_Hour A_Min A_Sec "." ext, Quality)
    Melt(ID, Trans, 1, 50)
    Return

~!PrintScreen::
    IfNotExist, % OutDirectory
        OutDirectory := A_ScriptDir
    Convert("", OutDirectory "\" A_Year  A_MM  A_DD "-" A_Hour A_Min A_Sec "." ext, Quality)
    Return

MButton::
Pause::
    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

Esc::
GuiClose:
    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, PrintScreen
}

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" _Blue _Green _Red
}

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 "\" SubStr(A_ScriptName, 1, -3) "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 "\" SubStr(A_ScriptName, 1, -3) "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}
}

CaptureScreen(aRect, sFile, nQuality)
{
    StringSplit, rt, aRect, `,, %A_Space%%A_Tab%
    nL := rt1
    nT := rt2
    nW := rt3 - rt1
    nH := rt4 - rt2

    mDC := DllCall("CreateCompatibleDC", "Uint", 0)
    hBM := CreateDIBSection(mDC, nW, nH)
    oBM := DllCall("SelectObject", "Uint", mDC, "Uint", hBM)
    hDC := DllCall("GetDC", "Uint", 0)
    DllCall("BitBlt", "Uint", mDC, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", hDC, "int"
                                                                , nL, "int", nT, "Uint", 0x40000000 | 0x00CC0020)
    DllCall("ReleaseDC", "Uint", 0, "Uint", hDC)
    DllCall("SelectObject", "Uint", mDC, "Uint", oBM)
    DllCall("DeleteDC", "Uint", mDC)
    If    sFile = 0
        SetClipboardData(hBM)
    Else
        Convert(hBM, sFile, nQuality), DllCall("DeleteObject", "Uint", hBM)
}

CreateDIBSection(hDC, nW, nH, bpp = 32, ByRef pBits = "")
{
    NumPut(VarSetCapacity(bi, 40, 0), bi)
    NumPut(nW, bi, 4)
    NumPut(nH, bi, 8)
    NumPut(bpp, NumPut(1, bi, 12, "UShort"), 0, "Ushort")
    NumPut(0,  bi,16)
    Return    DllCall("gdi32\CreateDIBSection", "Uint", hDC, "Uint", &bi, "Uint", 0
                                                                            , "UintP", pBits, "Uint", 0, "Uint", 0)
}

Convert(sFileFr = "", sFileTo = "", nQuality = "")
{
    SplitPath, sFileTo, , sDirTo, sExtTo, sNameTo

    If Not    hGdiPlus := DllCall("LoadLibrary", "str", "gdiplus.dll")
        Return    sFileFr+0 ? SaveHBITMAPToFile(sFileFr, sDirTo . "\" . sNameTo . ".bmp") : ""
    VarSetCapacity(si, 16, 0), si := Chr(1)
    DllCall("gdiplus\GdiplusStartup", "UintP", pToken, "Uint", &si, "Uint", 0)

    If    !sFileFr
    {
        DllCall("OpenClipboard", "Uint", 0)
        If     DllCall("IsClipboardFormatAvailable", "Uint", 2)
                                                            && (hBM:=DllCall("GetClipboardData", "Uint", 2))
        DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Uint", hBM, "Uint", 0, "UintP", pImage)
        DllCall("CloseClipboard")
    }
    Else If    sFileFr Is Integer
        DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Uint", sFileFr, "Uint", 0, "UintP", pImage)
    Else    DllCall("gdiplus\GdipLoadImageFromFile"
                                                    , "Uint", Unicode4Ansi(wFileFr,sFileFr), "UintP", pImage)

    DllCall("gdiplus\GdipGetImageEncodersSize", "UintP", nCount, "UintP", nSize)
    VarSetCapacity(ci,nSize,0)
    DllCall("gdiplus\GdipGetImageEncoders", "Uint", nCount, "Uint", nSize, "Uint", &ci)
    Loop, %    nCount
        If    InStr(Ansi4Unicode(NumGet(ci,76*(A_Index-1)+44)), "." . sExtTo)
        {
            pCodec := &ci+76*(A_Index-1)
            Break
        }
    If    InStr(".JPG.JPEG.JPE.JFIF", "." . sExtTo) && nQuality<>"" && pImage && pCodec
    {
        DllCall("gdiplus\GdipGetEncoderParameterListSize", "Uint", pImage
                                                                                        , "Uint", pCodec, "UintP", nSize)
        VarSetCapacity(pi,nSize,0)
        DllCall("gdiplus\GdipGetEncoderParameterList", "Uint", pImage, "Uint", pCodec, "Uint"
                                                                                                        , nSize, "Uint", &pi)
        Loop, %    NumGet(pi)
            If    NumGet(pi,28*(A_Index-1)+20)=1 && NumGet(pi,28*(A_Index-1)+24)=6
            {
                pParam := &pi+28*(A_Index-1)
                NumPut(nQuality,NumGet(NumPut(4,NumPut(1,pParam+0)+20)))
                Break
            }
    }

    If    pImage
        pCodec ? DllCall("gdiplus\GdipSaveImageToFile", "Uint", pImage
            , "Uint", Unicode4Ansi(wFileTo,sFileTo), "Uint", pCodec
            , "Uint", pParam) : DllCall("gdiplus\GdipCreateHBITMAPFromBitmap"
            , "Uint", pImage, "UintP", hBitmap
            , "Uint", 0) . SetClipboardData(hBitmap)
            , DllCall("gdiplus\GdipDisposeImage", "Uint", pImage)

    DllCall("gdiplus\GdiplusShutdown" , "Uint", pToken)
    DllCall("FreeLibrary", "Uint", hGdiPlus)
}

SaveHBITMAPToFile(hBitmap, sFile)
{
    DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi)
    hFile:=    DllCall("CreateFile", "Uint", &sFile, "Uint", 0x40000000, "Uint", 0
                                                                        , "Uint", 0, "Uint", 2, "Uint", 0, "Uint", 0)
    DllCall("WriteFile", "Uint", hFile, "int64P", 0x4D42|14+40+NumGet(oi,44)<<16
                                                                                    , "Uint", 6, "UintP", 0, "Uint", 0)
    DllCall("WriteFile", "Uint", hFile, "int64P", 54<<32, "Uint", 8, "UintP", 0, "Uint", 0)
    DllCall("WriteFile", "Uint", hFile, "Uint", &oi+24, "Uint", 40, "UintP", 0, "Uint", 0)
    DllCall("WriteFile", "Uint", hFile, "Uint", NumGet(oi,20)
                                                                    , "Uint", NumGet(oi,44), "UintP", 0, "Uint", 0)
    DllCall("CloseHandle", "Uint", hFile)
}

SetClipboardData(hBitmap)
{
    DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi)
    hDIB :=    DllCall("GlobalAlloc", "Uint", 2, "Uint", 40+NumGet(oi,44))
    pDIB :=    DllCall("GlobalLock", "Uint", hDIB)
    DllCall("RtlMoveMemory", "Uint", pDIB, "Uint", &oi+24, "Uint", 40)
    DllCall("RtlMoveMemory", "Uint", pDIB+40, "Uint", NumGet(oi,20), "Uint", NumGet(oi,44))
    DllCall("GlobalUnlock", "Uint", hDIB)
    DllCall("DeleteObject", "Uint", hBitmap)
    DllCall("OpenClipboard", "Uint", 0)
    DllCall("EmptyClipboard")
    DllCall("SetClipboardData", "Uint", 8, "Uint", hDIB)
    DllCall("CloseClipboard")
}

Unicode4Ansi(ByRef wString, sString)
{
    nSize := DllCall("MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &sString
                                                                                    , "int", -1, "Uint", 0, "int", 0)
    VarSetCapacity(wString, nSize * 2)
    DllCall("MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &sString, "int", -1
                                                                                    , "Uint", &wString, "int", nSize)
    Return    &wString
}

Ansi4Unicode(pString)
{
    nSize := DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "Uint", pString
                                                        , "int", -1, "Uint", 0, "int",  0, "Uint", 0, "Uint", 0)
    VarSetCapacity(sString, nSize)
    DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "Uint", pString
                                            , "int", -1, "str", sString, "int", nSize, "Uint", 0, "Uint", 0)
    Return    sString
}

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%, UInt)
        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%, Uint)
    DllCall( "SetSystemCursor", Uint, CursorHandle, Int, IDC_ARROW)
}

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


Control_Colors(Hwnd, Msg, wParam, lParam = 0)
{
    Thread, Priority, 2147483647

    If !(Hwnd+0) {
        GuiControlGet, nHwnd, Hwnd, %Hwnd%
        Hwnd := nhwnd
   }

   Static OldWinProc := ""          ; origin Windowprocedure
   Static NewWinProc := ""          ; new Windowprocedure
   Static SetValue := "Set"         ; take over Values
   Static Register := "RCB"         ; RegisterCallBack
   Static ValueList := ""           ; Values

   If (A_EventInfo <> NewWinProc) {
      If (Msg = SetValue) {
         If (RegExMatch(ValueList, "m)^" . (Hwnd +0) . "\|")) {
            ValueList := RegExReplace(ValueList
                                     , "m)^" . (Hwnd + 0) . "\|.*$"
                                     , (Hwnd + 0) . "|"
                                     . (wParam + 0) . "|"
                                     . (lParam + 0))
         } Else {
            ValueList .= (Hwnd + 0) . "|"
                      .  (wParam + 0) . "|"
                      .  (lParam + 0) .  "`r`n"
         }
         Return
      }
      If (Msg = Register) {
         If (NewWinProc = "") {
            NewWinProc := RegisterCallback("Control_Colors","",4)
            OldWinProc := DllCall("SetWindowLong"
                                 , UInt, Hwnd
                                 , Int, -4
                                 , Int, NewWinProc
                                 , UInt)
         }
         Return
      }
      Return
   }
   ; 0x0133 : WM_CTLCOLOREDIT
   ; 0x0138 : WM_CTLCOLORSTATIC
   If (Msg = 0x0133 Or Msg = 0x0135 Or Msg = 0x0138) {
      If (RegExMatch(ValueList, "m)^"
                     . (lParam + 0) . "\|(?P<BG>\d+)\|(?P<TX>\d+)$"
                     , C)) {
         DllCall("SetTextColor", UInt, wParam, UInt, CTX)
         DllCall("SetBkColor", UInt, wParam, UInt, CBG)
         Return, DllCall("CreateSolidBrush", UInt, CBG)
      }
   }
   Return DllCall("CallWindowProcA"
                  , UInt, OldWinProc
                  , UInt, Hwnd
                  , UInt, Msg
                  , UInt, wParam
                  , UInt, lParam)
}

Функции CaptureScreen(), SetCursor(), SetSystemCursor() и Control_Colors() взяты с оф. форума и приспособлены для данного скрипта.
Функции Ini_WriteSect(), Ini_ReadSect(), Trans() и GotoLineUp() написаны для общего случая и предназначены для использования через библиотеку.
Если кто-нибудь захочет задать вопрос по работе скрипта или сообщить о замеченных багах — прошу писать в эту тему.

Post's attachments

ScreenCatcher.zip 235.92 kb, 640 downloads since 2009-07-26 

You don't have the permssions to download the attachments of this post.
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3 (изменено: teadrinker, 2010-11-18 21:46:52)

Re: AutoHotkey: сохранение скриншота экрана в файл

Новая версия предыдущего скрипта.
Добавлено:
Возможность работы под AHK_Lw. При этом скрипт должен быть соханён в формате UTF-8.
Возможность запуска при загрузке системы, при этом окно скрипта изначально будет скрыто.
Возможность делать скриншоты чаще, чем раз в секунду.
Возможность включения в скриншот курсора.

Назначение горячих клавиш по сравнению с предыдущей версией изменено, читайте Help (F1 после запуска). Все горячие клавиши находятся в конце скрипта, можно менять.

   #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%, UInt)
      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%, Uint)
   DllCall("SetSystemCursor", Uint, 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, "uint*", pBrush)
   DllCall("gdiplus\GdipCreateBitmapFromScan0", Int, w
      , Int, h, Int, 0, Int, 0x26200A, UInt, 0, "uint*", pBitmap)
   DllCall("gdiplus\GdipGetImageGraphicsContext", UInt, pBitmap, "uint*", G)
   DllCall("gdiplus\GdipFillRectangle"
      , UInt, G, Int, pBrush, "float", 0, "float", 0, "float", w, "float", h)
   DllCall("gdiplus\GdipCreateHBITMAPFromBitmap"
      , UInt, pBitmap, "uint*", hBitmap, Int, 0xffffffff)
   SendMessage, STM_SETIMAGE := 0x172, 0x0, hBitmap,, ahk_id %hwnd%
   DllCall("DeleteObject", UInt, ErrorLevel)
   DllCall("gdiplus\GdipDeleteBrush", UInt, pBrush)
   DllCall("gdiplus\GdipDeleteGraphics", UInt, G)
   DllCall("gdiplus\GdipDisposeImage", UInt, pBitmap)
   DllCall("DeleteObject", UInt, 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", UInt, 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", UInt, 0)
   VarSetCapacity(bi, 40, 0)
   NumPut(w, bi, 4), NumPut(h, bi, 8), NumPut(40, bi, 0), NumPut(1, bi, 12, "ushort")
   NumPut(0, bi, 16), NumPut(32, bi, 14, "ushort")
   hbm := DllCall("CreateDIBSection"
      , UInt , chdc, UInt , &bi, UInt , 0, "uint*", 0, UInt , 0, UInt , 0)
   obm := DllCall("SelectObject", UInt, chdc, UInt, hbm)
   hhdc := DllCall("GetDC", UInt, 0)
   DllCall("gdi32\BitBlt", UInt, chdc, Int, 0, Int, 0, Int, w, Int, h
      , UInt, hhdc, Int, x, Int, y, UInt, Raster)
   DllCall("ReleaseDC", UInt, 0, UInt, hhdc)
   if Cursor
      CaptureCursor(chdc, x, y)
   DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", UInt, hbm, UInt, 0, "uint*", pBitmap)
   DllCall("SelectObject", UInt, chdc, UInt, obm)
   DllCall("DeleteObject", UInt, hbm)
   DllCall("DeleteDC", UInt, hhdc)
   DllCall("DeleteDC", UInt, chdc)
   return pBitmap
}

CaptureCursor(hDC, nL, nT)
{
   VarSetCapacity(mi, 20, 0), mi := Chr(20)
   DllCall("GetCursorInfo", UInt, &mi)
   bShow   := NumGet(mi, 4)
   hCursor := NumGet(mi, 8)
   xCursor := NumGet(mi,12)
   yCursor := NumGet(mi,16)

   If   bShow && hCursor:=DllCall("CopyIcon", UInt, hCursor)
   {
   VarSetCapacity(ni, 20, 0)
   DllCall("GetIconInfo", UInt, hCursor, UInt, &ni)
   bIcon    := NumGet(ni, 0)
   xHotspot := NumGet(ni, 4)
   yHotspot := NumGet(ni, 8)
   hBMMask  := NumGet(ni,12)
   hBMColor := NumGet(ni,16)

   DllCall("DrawIcon", UInt, hDC, Int, xCursor - xHotspot - nL
      , Int, yCursor - yHotspot - nT, UInt, hCursor)
   DllCall("DestroyIcon", UInt, hCursor)
   If   hBMMask
      DllCall("DeleteObject", UInt, hBMMask)
   If   hBMColor
      DllCall("DeleteObject", UInt, hBMColor)
   }
}

SetBitmapToClipboard(pBitmap)
{
   DllCall("gdiplus\GdipCreateHBITMAPFromBitmap"
      , UInt, pBitmap, "uint*", hBitmap, Int, 0xffffffff)
   DllCall("GetObject", UInt, hBitmap, Int, VarSetCapacity(oi, 84, 0), UInt, &oi)
   hdib := DllCall("GlobalAlloc", UInt, 2, UInt, 40+NumGet(oi, 44))
   pdib := DllCall("GlobalLock", UInt, hdib)
   DllCall("RtlMoveMemory", UInt, pdib, UInt, &oi+24, UInt, 40)
   DllCall("RtlMoveMemory", UInt, pdib+40, UInt, NumGet(oi, 20), UInt, NumGet(oi, 44))
   DllCall("GlobalUnlock", UInt, hdib)
   DllCall("OpenClipboard", UInt, 0)
   DllCall("EmptyClipboard")
   DllCall("SetClipboardData", UInt, 8, UInt, hdib)
   DllCall("CloseClipboard")
}

SaveBitmapToFile(pBitmap, sOutput, Quality=75)
{
   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, UInt, &ci)
   if !(nCount && nSize)
      return -2

   Loop, %nCount%
   {
      Location := NumGet(ci, 76*(A_Index-1)+44)
      if !A_IsUnicode
      {
         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
      }
      else
      {
         nSize := DllCall("WideCharToMultiByte", UInt, 0, UInt, 0
            , UInt, Location, Int, -1, UInt, 0, Int,  0, UInt, 0, UInt, 0)
         sString := ""
         Loop, %nSize%
            sString .= Chr(NumGet(Location+0, 2*(A_Index-1), "char"))
         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"
            , UInt, pBitmap, UInt, pCodec, "uint*", nSize)
         VarSetCapacity(EncoderParameters, nSize, 0)
         DllCall("gdiplus\GdipGetEncoderParameterList", UInt, pBitmap
            , UInt, pCodec, UInt, nSize, UInt, &EncoderParameters)
         Loop, % NumGet(EncoderParameters)      ;%
         {
            if (NumGet(EncoderParameters, (28*(A_Index-1))+20) = 1)
               && (NumGet(EncoderParameters, (28*(A_Index-1))+24) = 6)
            {
               p := (28*(A_Index-1))+&EncoderParameters
               NumPut(Quality, NumGet(NumPut(4, NumPut(1, p+0)+20)))
               break
            }
         }
      }
   }

   if !A_IsUnicode
   {
      nSize := DllCall("MultiByteToWideChar"
         , UInt, 0, UInt, 0, UInt, &sOutput, Int, -1, UInt, 0, Int, 0)
      VarSetCapacity(wOutput, nSize*2)
      DllCall("MultiByteToWideChar"
         , UInt, 0, UInt, 0, UInt, &sOutput, Int, -1, UInt, &wOutput, Int, nSize)
      VarSetCapacity(wOutput, -1)
      if !VarSetCapacity(wOutput)
         return -4
      E := DllCall("gdiplus\GdipSaveImageToFile"
         , UInt, pBitmap, UInt, &wOutput, UInt, pCodec, UInt, p ? p : 0)
   }
   else
      E := DllCall("gdiplus\GdipSaveImageToFile"
         , UInt, pBitmap, UInt, &sOutput, UInt, 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", "uint*", pToken, UInt, &si, UInt, 0)
   return pToken
}

GdipShutdown(pToken)
{
   DllCall("gdiplus\GdiplusShutdown", UInt, pToken)
   if hModule := DllCall("GetModuleHandle", Str, "gdiplus")
      DllCall("FreeLibrary", UInt, 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

Если кто-нибудь захочет задать вопрос по работе скрипта или сообщить о замеченных багах — прошу писать в эту тему.
В архиве скрипт, иконка и скомпилированный файл.

Post's attachments

ScreenCatcher.zip 240.11 kb, 360 downloads since 2010-11-18 

You don't have the permssions to download the attachments of this post.
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder