26

Re: AHK: Скриншот выделенной части экрана поверх всех окон

Без DPIScale тоже самое:

Появляется когда резко отводишь мышь и отпускаешь LButton, а окно выделения ещё не "догнало" курсор.

По вопросам возмездной помощи пишите в личку
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.25.01 (Unicode 32-bit).

27

Re: AHK: Скриншот выделенной части экрана поверх всех окон

Ага, тоже получилось, подумаю.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

28

Re: AHK: Скриншот выделенной части экрана поверх всех окон

Вот так у меня выглядело.

http://i003.radikal.ru/1501/6e/c6575719e382.jpg

29

Re: AHK: Скриншот выделенной части экрана поверх всех окон

serzh82saratov пишет:

Появляется когда резко отводишь мышь и отпускаешь LButton, а окно выделения ещё не "догнало" курсор.

Нужно после KeyWait, LButton добавить SetTimer, EventHandling, Off.

/*
Ctrl + Space — начать выделение (отпустив Ctrl + Space).
Двигать окно со скриншотом левой кнопкой, закрыть — щелчком правой.
*/

CoordMode, Mouse
SetBatchLines, -1
SetWinDelay, 0
OnExit, Exit
oGuiData := []
OnMessage(0x112, "WM_SYSCOMMAND")
OnMessage(0x201, "WM_LBUTTONDOWN")
OnMessage(0x205, "WM_RBUTTONUP")
Return

^Space::CrossHair(CrossHair := 1)

#If CrossHair = 1
LButton::
   MouseGetPos, mouse_x_start, mouse_y_start
   
   Gui, Select:Default
   Gui, -Caption +ToolWindow +LastFound +AlwaysOnTop -DPIScale
   Gui, Color, Grey
   WinSet, Transparent, 150
   
   hHookMouse := DllCall("SetWindowsHookEx"
      , Int, WH_MOUSE_LL := 14
      , Int, RegisterCallback("LowLevelMouseProc", "Fast")
      , Ptr, DllCall("GetModuleHandle", UInt, 0, Ptr)
      , UInt, 0, Ptr)
      
   KeyWait, LButton
   SetTimer, EventHandling, Off
   DllCall("UnhookWindowsHookEx", Ptr, hHookMouse), hHookMouse := ""
   CrossHair(CrossHair := "")
   WinGetPos, X, Y, W, H
   Gui, Destroy
   CreateScreenshotWindow([X, Y, W, H])
   Return
   
Exit:
   (CrossHair && CrossHair())
   (hHookMouse && DllCall("UnhookWindowsHookEx", Ptr, hHookMouse))
   for k, v in oGuiData
      (v != 0 && DllCall("DeleteObject", Ptr, v))
   ExitApp

CrossHair(OnOff = "")
{
   static IDC_CROSS := 32515, SPI_SETCURSORS := 0x57
      , hCursor := DllCall("LoadCursor", Ptr, 0, UInt, IDC_CROSS, Ptr)
      , sys_cursors := [32512,32513,32514,32516,32642,32643,32644,32645,32646,32648,32649,32650]
   
   if !OnOff
      DllCall("SystemParametersInfo", UInt, SPI_SETCURSORS, UInt, 0, UInt, 0, UInt, 0)
   else
      for k, cursor in sys_cursors
         hCopy := DllCall("CopyImage", Ptr, hCursor, UInt, 2, Int, 0, Int, 0, UInt, 0)
         , DllCall("SetSystemCursor", Ptr, hCopy, UInt, cursor)
}
       
LowLevelMouseProc(nCode, wParam, lParam)
{
   static mouse_x, mouse_y, WM_MOUSEMOVE := 0x200
   global mouse_x_start, mouse_y_start

   if (wParam = WM_MOUSEMOVE)  {
      mouse_x := NumGet(lParam + 0, "Int")
      mouse_y := NumGet(lParam + 4, "Int")
      SetTimer, EventHandling, -10
   }
   Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam)

EventHandling:
   x := mouse_x_start < mouse_x ? mouse_x_start : mouse_x
   y := mouse_y_start < mouse_y ? mouse_y_start : mouse_y
   w := Abs(mouse_x - mouse_x_start)
   h := Abs(mouse_y - mouse_y_start)
   Gui, Select:Show, x%x% y%y% w%w% h%h% NA
   Return
}

CreateScreenshotWindow(oCoords)
{
   global oGuiData
   static SS_BITMAP := 0xE
   
   pToken := Gdip_Startup()
   pBitmap := Gdip_BitmapFromScreen(oCoords[1] "|" oCoords[2] "|" oCoords[3] "|" oCoords[4])
   Gdip_GetImageDimensions(pBitmap, W, H)
   hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap)
   Gdip_DisposeImage(pBitmap)
   
   for k, v in oGuiData
      if (v = 0 && IsEmpty := k)
         break
      
   nGui := IsEmpty ? IsEmpty : (k = "" || k = 99) ? 1 : k + 1
   oGuiData[nGui] := hBitmap

   Gui, %nGui%:New
   Gui, %nGui%:Default
   Gui, -Caption +ToolWindow +AlwaysOnTop +LastFound +Border -DPIScale
   Gui, Margin, 0, 0
   Gui, Add, Pic, hwndhPic w%W% h%H% %SS_BITMAP%
   SetImage(hPic, hBitmap)
   Gui, Show, % "x" oCoords[1] - 1 " y" oCoords[2] - 1
   
   Gdip_Shutdown(pToken)
}

WM_LBUTTONDOWN()
{
   if (A_Gui != "Select")
      PostMessage, WM_NCLBUTTONDOWN := 0xA1, HTCAPTION := 2
}

WM_RBUTTONUP()
{
   global oGuiData
   if (A_Gui != "Select")  {
      DllCall("DeleteObject", Ptr, oGuiData[A_Gui])
      oGuiData[A_Gui] := 0
      Gui, %A_Gui%:Destroy
   }
}

WM_SYSCOMMAND(wp)
{
   global oGuiData
   static SC_CLOSE := 0xF060
   if (wp = SC_CLOSE && A_Gui != "Select")
      DllCall("DeleteObject", Ptr, oGuiData[A_Gui]), oGuiData[A_Gui] := 0
}

Для работы скрипта нужна библиотека Gdip.ahk.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

30

Re: AHK: Скриншот выделенной части экрана поверх всех окон

А можно ли добавить увеличение скрина внутри окна по горячей клавише .

31 (изменено: teadrinker, 2017-03-18 08:02:42)

Re: AHK: Скриншот выделенной части экрана поверх всех окон

Так можно менять размер колесом мыши:

/*
Скрипт снимает скриншот выделенной области экрана и показывает его поверх всех окон.
Скрипт также позволяет изменять размеры скриншота при вращении над ним колеса мыши.
Ctrl + Space — начать выделение (отпустив Ctrl + Space).
Двигать окно со скриншотом левой кнопкой, менять размер вращая колесо, закрыть — щелчком правой.

Для работы скрипта необходима библиотека Gdip.ahk
https://www.dropbox.com/s/73vpu9xdzn5ys13/Gdip.ahk?dl=1
*/

CoordMode, Mouse
SetBatchLines, -1
SetWinDelay, 0
OnExit, Exit
global oGuiData := []

OnMessage(0x112, "WM_SYSCOMMAND")
OnMessage(0x201, "WM_LBUTTONDOWN")
OnMessage(0x205, "WM_RBUTTONUP")
Return

Exit:
   (CrossHair && CrossHair())
   (hHookMouse && DllCall("UnhookWindowsHookEx", Ptr, hHookMouse))
   for k, v in oGuiData
      DllCall("DeleteObject", Ptr, v)
   ExitApp

^Space::CrossHair(CrossHair := 1)

#If CrossHair = 1
LButton::
   MouseGetPos, mouse_x_start, mouse_y_start
   
   Gui, Select:Default
   Gui, -Caption +ToolWindow +LastFound +AlwaysOnTop -DPIScale
   Gui, Color, Grey
   WinSet, Transparent, 150
   
   hHookMouse := DllCall("SetWindowsHookEx"
      , Int, WH_MOUSE_LL := 14
      , Int, RegisterCallback("LowLevelMouseProc", "Fast")
      , Ptr, DllCall("GetModuleHandle", UInt, 0, Ptr)
      , UInt, 0, Ptr)
      
   KeyWait, LButton
   SetTimer, EventHandling, Off
   DllCall("UnhookWindowsHookEx", Ptr, hHookMouse), hHookMouse := ""
   CrossHair(CrossHair := "")
   WinGetPos, X, Y, W, H
   Gui, Destroy
   CreateScreenshotWindow(X, Y, W, H)
   Return

#If hGui := ScreenWindowUnderCursor()
WheelDown::
WheelUp:: WM_WHEEL(A_ThisHotkey = "WheelUp" ? 0 : 1, hGui)
   
CrossHair(OnOff = "")
{
   static IDC_CROSS := 32515, SPI_SETCURSORS := 0x57
      , hCursor := DllCall("LoadCursor", Ptr, 0, UInt, IDC_CROSS, Ptr)
      , sys_cursors := [32512,32513,32514,32516,32642,32643,32644,32645,32646,32648,32649,32650]
   
   if !OnOff
      DllCall("SystemParametersInfo", UInt, SPI_SETCURSORS, UInt, 0, UInt, 0, UInt, 0)
   else
      for k, cursor in sys_cursors
         hCopy := DllCall("CopyImage", Ptr, hCursor, UInt, 2, Int, 0, Int, 0, UInt, 0)
         , DllCall("SetSystemCursor", Ptr, hCopy, UInt, cursor)
}
       
LowLevelMouseProc(nCode, wParam, lParam)
{
   static mouse_x, mouse_y, WM_MOUSEMOVE := 0x200
   global mouse_x_start, mouse_y_start

   if (wParam = WM_MOUSEMOVE)  {
      mouse_x := NumGet(lParam + 0, "Int")
      mouse_y := NumGet(lParam + 4, "Int")
      SetTimer, EventHandling, -10
   }
   Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam)

EventHandling:
   x := mouse_x_start < mouse_x ? mouse_x_start : mouse_x
   y := mouse_y_start < mouse_y ? mouse_y_start : mouse_y
   w := Abs(mouse_x - mouse_x_start)
   h := Abs(mouse_y - mouse_y_start)
   Gui, Select:Show, x%x% y%y% w%w% h%h% NA
   Return
}

CreateScreenshotWindow(X, Y, W, H)
{
   static WS_EX_LAYERED := 0x80000
   
   pToken := Gdip_Startup()
   pBitmap := Gdip_BitmapFromScreen( X "|" Y "|" W "|" H )
   
   hbm := CreateDIBSection(W, H)
   hdc := CreateCompatibleDC()
   obm := SelectObject(hdc, hbm)
   G := Gdip_GraphicsFromHDC(hdc)
   Gdip_DrawImage(G, pBitmap, 0, 0, W, H, 0, 0, W, H)
   
   pPen := Gdip_CreatePen(0xFF808080, 2)
   Gdip_DrawRectangle(G, pPen, 1, 1, W - 2, H - 2)
   Gdip_DeletePen(pPen)
   
   for k, v in oGuiData
      if (v = 0 && IsEmpty := 1)
         break
      
   Gui, New, -Caption +E%WS_EX_LAYERED% +LastFound +AlwaysOnTop +ToolWindow +hwndhGui -DPIScale
   Gui, Show, NA
   oGuiData[hGui] := Gdip_CreateHBITMAPFromBitmap(pBitmap)
   UpdateLayeredWindow(hGui, hdc, X, Y, W, H)
   
   SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
   Gdip_DeleteGraphics(G), Gdip_DisposeImage(pBitmap)
   Gdip_Shutdown(pToken)
}

ScreenWindowUnderCursor()
{
   MouseGetPos,,, hGui
   WinGet, PID, Pid, ahk_id %hGui%
   if DllCall("GetCurrentProcessId") = PID
      Return hGui
}

WM_LBUTTONDOWN()
{
   if (A_Gui != "Select")
      PostMessage, WM_NCLBUTTONDOWN := 0xA1, HTCAPTION := 2
}

WM_RBUTTONUP()
{
   if (A_Gui != "Select")  {
      DllCall("DeleteObject", Ptr, oGuiData[A_Gui])
      oGuiData.Delete(A_Gui)
      Gui, %A_Gui%:Destroy
   }
}

WM_SYSCOMMAND(wp)
{
   static SC_CLOSE := 0xF060
   if (wp = SC_CLOSE && A_Gui != "Select")
      DllCall("DeleteObject", Ptr, oGuiData[A_Gui]), oGuiData.Delete(A_Gui)
}

WM_WHEEL(wp, hwnd)
{
   Critical
   pToken := Gdip_Startup()
   pBitmap := Gdip_CreateBitmapFromHBITMAP(oGuiData[hwnd])
   Gdip_GetImageDimensions(pBitmap, WidthBM, HeightBM)
   RatioBM := WidthBM/HeightBM
   SquareBM := WidthBM*HeightBM
   
   WinGetPos, X, Y, W, H, ahk_id %hwnd%
   
   DeltaW := Round(W/(!wp ? 10 : 11))
   DeltaW := wp ? -DeltaW : DeltaW
   ResultW := W + DeltaW
   ResultH := Round(ResultW/RatioBM)
   ResultX := X - Round(DeltaW/2)
   ResultY := Y - Round((ResultH - H)/2)
   SquareWin := ResultW*ResultH
   if (!wp && SquareWin > 13000000) || (wp && SquareWin < 1000 && SquareWin < SquareBM)
      Return, "", Gdip_DisposeImage(pBitmap), Gdip_Shutdown(pToken)

   hbm := CreateDIBSection(ResultW, ResultH)
   hdc := CreateCompatibleDC()
   obm := SelectObject(hdc, hbm)
   G := Gdip_GraphicsFromHDC(hdc)
   
   Gdip_SetInterpolationMode(G, 7)
   Gdip_DrawImage(G, pBitmap, 0, 0, ResultW, ResultH, 0, 0, WidthBM, HeightBM)
   pPen := Gdip_CreatePen(0xFF808080, 2)
   Gdip_DrawRectangle(G, pPen, 1, 1, ResultW - 2, ResultH - 2)
   
   UpdateLayeredWindow(hwnd, hdc, ResultX, ResultY, ResultW, ResultH)

   Gdip_DeletePen(pPen), SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
   Gdip_DeleteGraphics(G), Gdip_DisposeImage(pBitmap), Gdip_Shutdown(pToken)
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

32

Re: AHK: Скриншот выделенной части экрана поверх всех окон

К вопросу о скриншотах - кому-нибудь встречалась задача по созданию скрина свернутого окна приложения без использования внешнего софта (Paint и т.д.), а так же снятия скринов при разлогиненном компьютере (хм, вообще возможно ли такое)? Перелопатил несколько веток на англоязычном форуме, но к сожалению примеры не заработали.

33

Re: AHK: Скриншот выделенной части экрана поверх всех окон

emmetoya пишет:

кому-нибудь встречалась задача по созданию скрина свернутого окна приложения без использования внешнего софта

Встречалась.

emmetoya пишет:

а так же снятия скринов при разлогиненном компьютере

Нет, такая точно не встречалась. smile

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

34

Re: AHK: Скриншот выделенной части экрана поверх всех окон

teadrinker
Удалось снимать скрины со свернутых окон, поделитесь знанием)?

По второму вопросу я некорректно описал задачу - пользователь залогинен на рабочей станции, но система заблокирована.

35

Re: AHK: Скриншот выделенной части экрана поверх всех окон

emmetoya пишет:

Удалось снимать скрины со свернутых окон, поделитесь знанием)?

Со свёрнутых пока никому не удавалось, но можно временно развернуть за экраном.
И просьба, старайтесь не цитировать предыдущий пост целиком, пользуйтесь кнопкой «Ответить» или формой быстрого ответа.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

36 (изменено: Ядрён, 2017-03-16 15:35:53)

Re: AHK: Скриншот выделенной части экрана поверх всех окон

Доброго времени суток . Подскажите пожалуйста как добавить сохранение скриншота выделенной части экрана .

37

Re: AHK: Скриншот выделенной части экрана поверх всех окон

Подскажите в какую сторону хоть смотреть.

38

Re: AHK: Скриншот выделенной части экрана поверх всех окон

Завтра попробую, пока некогда.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

39

Re: AHK: Скриншот выделенной части экрана поверх всех окон

Смотреть нужно в сторону туториалов:
https://autohotkey.com/board/topic/2944 … 45-by-tic/
За сохранение файла отвечает функция: Gdip_SaveBitmapToFile(pBitmap, "File.png").
Соответственно вставьте ее в скрипте teadrinkerа после создания объекта pBitmap и до освобождения его ресурсов Gdip_DisposeImage(pBitmap).

40

Re: AHK: Скриншот выделенной части экрана поверх всех окон

Уважаемый Malcev всё получилось как вы говорили , правда  выделяешь часть экрана и сразу происходит сохраняет . А подскажите пожалуйста как сделать сохранение по горячей клавише.

+ открыть спойлер

Сегодня пол ночи мучился , так и не одолел "сохранение по горячей клавише".

41 (изменено: Malcev, 2017-03-17 15:59:22)

Re: AHK: Скриншот выделенной части экрана поверх всех окон

Нужно объявить глобальными переменные pBitmap и pToken и стереть Gdip_DisposeImage(pBitmap), Gdip_Shutdown(pToken) из конца функции CreateScreenshotWindow(X, Y, W, H).
Вставить  в начало функции:

if pBitmap
   Gdip_DisposeImage(pBitmap)
if pToken
   Gdip_Shutdown(pToken)

И тоже самое вставить в метку OnExit, чтобы при выходе из скрипта тоже подчищалось, хотя я читал, что винда сама должна подчищать.

42 (изменено: Ядрён, 2017-03-18 04:19:10)

Re: AHK: Скриншот выделенной части экрана поверх всех окон

Что то не получается помогите пожалуйста. Как сделать например нажал "F10" скрин сохранился.

43 (изменено: teadrinker, 2017-03-18 08:26:08)

Re: AHK: Скриншот выделенной части экрана поверх всех окон

Ядрён пишет:

Подскажите пожалуйста как добавить сохранение скриншота выделенной части экрана

Если речь идёт о вышеприведённом скрипте, то там можно выделять несколько областей экрана сразу. Как скрипт узнает, какую именно сохранять по горячей клавише? Кроме того, там можно менять размер окна со скриншотом. В каком размере должно сохраняться, в первоначальном, или в текущем?

Malcev пишет:

Нужно объявить глобальными переменные pBitmap и pToken и стереть Gdip_DisposeImage(pBitmap), Gdip_Shutdown(pToken) из конца функции CreateScreenshotWindow(X, Y, W, H).

Нет, ничего такого не нужно. В скрипте есть объект oGuiData с хэндлами hBitmap существующих окон. Скрипт немного подправил.
Вот сохранение по двойному клику:

/*
Скрипт снимает скриншот выделенной области экрана и показывает его поверх всех окон.
Скрипт также позволяет изменять размеры скриншота при вращении над ним колеса мыши.
Ctrl + Space — начать выделение (отпустив Ctrl + Space).
Двигать окно со скриншотом левой кнопкой, менять размер вращая колесо, закрыть — щелчком правой.

Для работы скрипта необходима библиотека Gdip.ahk
https://www.dropbox.com/s/73vpu9xdzn5ys13/Gdip.ahk?dl=1
*/

CoordMode, Mouse
SetBatchLines, -1
SetWinDelay, 0
SetWorkingDir, % A_ScriptDir
OnExit, Exit
global oGuiData := []

OnMessage(0x112, "WM_SYSCOMMAND")
OnMessage(0x201, "WM_LBUTTONDOWN")
OnMessage(0x205, "WM_RBUTTONUP")
OnMessage(0x203, "WM_LBUTTONDBLCLK")
Return

Exit:
   (CrossHair && CrossHair())
   (hHookMouse && DllCall("UnhookWindowsHookEx", Ptr, hHookMouse))
   for k, v in oGuiData
      DllCall("DeleteObject", Ptr, v)
   ExitApp

^Space::CrossHair(CrossHair := 1)

#If CrossHair = 1
LButton::
   MouseGetPos, mouse_x_start, mouse_y_start
   
   Gui, Select:Default
   Gui, -Caption +ToolWindow +LastFound +AlwaysOnTop -DPIScale
   Gui, Color, Grey
   WinSet, Transparent, 150
   
   hHookMouse := DllCall("SetWindowsHookEx"
      , Int, WH_MOUSE_LL := 14
      , Int, RegisterCallback("LowLevelMouseProc", "Fast")
      , Ptr, DllCall("GetModuleHandle", UInt, 0, Ptr)
      , UInt, 0, Ptr)
      
   KeyWait, LButton
   SetTimer, EventHandling, Off
   DllCall("UnhookWindowsHookEx", Ptr, hHookMouse), hHookMouse := ""
   CrossHair(CrossHair := "")
   WinGetPos, X, Y, W, H
   Gui, Destroy
   CreateScreenshotWindow(X, Y, W, H)
   Return

#If hGui := ScreenWindowUnderCursor()
WheelDown::
WheelUp:: WM_WHEEL(A_ThisHotkey = "WheelUp" ? 0 : 1, hGui)
   
CrossHair(OnOff = "")
{
   static IDC_CROSS := 32515, SPI_SETCURSORS := 0x57
      , hCursor := DllCall("LoadCursor", Ptr, 0, UInt, IDC_CROSS, Ptr)
      , sys_cursors := [32512,32513,32514,32516,32642,32643,32644,32645,32646,32648,32649,32650]
   
   if !OnOff
      DllCall("SystemParametersInfo", UInt, SPI_SETCURSORS, UInt, 0, UInt, 0, UInt, 0)
   else
      for k, cursor in sys_cursors
         hCopy := DllCall("CopyImage", Ptr, hCursor, UInt, 2, Int, 0, Int, 0, UInt, 0)
         , DllCall("SetSystemCursor", Ptr, hCopy, UInt, cursor)
}
       
LowLevelMouseProc(nCode, wParam, lParam)
{
   static mouse_x, mouse_y, WM_MOUSEMOVE := 0x200
   global mouse_x_start, mouse_y_start

   if (wParam = WM_MOUSEMOVE)  {
      mouse_x := NumGet(lParam + 0, "Int")
      mouse_y := NumGet(lParam + 4, "Int")
      SetTimer, EventHandling, -10
   }
   Return DllCall("CallNextHookEx", Ptr, 0, Int, nCode, UInt, wParam, UInt, lParam)

EventHandling:
   x := mouse_x_start < mouse_x ? mouse_x_start : mouse_x
   y := mouse_y_start < mouse_y ? mouse_y_start : mouse_y
   w := Abs(mouse_x - mouse_x_start)
   h := Abs(mouse_y - mouse_y_start)
   Gui, Select:Show, x%x% y%y% w%w% h%h% NA
   Return
}

CreateScreenshotWindow(X, Y, W, H)
{
   static WS_EX_LAYERED := 0x80000
   
   pToken := Gdip_Startup()
   pBitmap := Gdip_BitmapFromScreen( X "|" Y "|" W "|" H )
   
   hbm := CreateDIBSection(W, H)
   hdc := CreateCompatibleDC()
   obm := SelectObject(hdc, hbm)
   G := Gdip_GraphicsFromHDC(hdc)
   Gdip_DrawImage(G, pBitmap, 0, 0, W, H, 0, 0, W, H)
   
   pPen := Gdip_CreatePen(0xFF808080, 2)
   Gdip_DrawRectangle(G, pPen, 1, 1, W - 2, H - 2)
   Gdip_DeletePen(pPen)
   
   for k, v in oGuiData
      if (v = 0 && IsEmpty := 1)
         break
      
   Gui, New, -Caption +E%WS_EX_LAYERED% +LastFound +AlwaysOnTop +ToolWindow +hwndhGui -DPIScale
   Gui, Show, NA
   oGuiData[hGui] := Gdip_CreateHBITMAPFromBitmap(pBitmap)
   UpdateLayeredWindow(hGui, hdc, X, Y, W, H)
   
   SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
   Gdip_DeleteGraphics(G), Gdip_DisposeImage(pBitmap)
   Gdip_Shutdown(pToken)
}

ScreenWindowUnderCursor()
{
   MouseGetPos,,, hGui
   WinGet, PID, Pid, ahk_id %hGui%
   if DllCall("GetCurrentProcessId") = PID
      Return hGui
}

WM_LBUTTONDOWN()
{
   if (A_Gui != "Select")
      PostMessage, WM_NCLBUTTONDOWN := 0xA1, HTCAPTION := 2
}

WM_LBUTTONDBLCLK()
{
   pToken := Gdip_Startup()
   pBitmap := Gdip_CreateBitmapFromHBITMAP(oGuiData[A_Gui])
   res := Gdip_SaveBitmapToFile(pBitmap, A_ScriptDir . "\" . A_Now . ".png")
   
   DllCall("DeleteObject", Ptr, oGuiData[A_Gui])
   oGuiData.Delete(A_Gui)
   Gui, %A_Gui%:Destroy
   Gdip_DisposeImage(pBitmap), Gdip_Shutdown(pToken)
   
   if (res = 0)
      MsgBox, Файл успешно создан по адресу:`n%A_ScriptDir%\%A_Now%.png
   else
      MsgBox, Не удалось создать файл. Ошибка: %res%
}

WM_RBUTTONUP()
{
   if (A_Gui != "Select")  {
      DllCall("DeleteObject", Ptr, oGuiData[A_Gui])
      oGuiData.Delete(A_Gui)
      Gui, %A_Gui%:Destroy
   }
}

WM_SYSCOMMAND(wp)
{
   static SC_CLOSE := 0xF060
   if (wp = SC_CLOSE && A_Gui != "Select")
      DllCall("DeleteObject", Ptr, oGuiData[A_Gui]), oGuiData.Delete(A_Gui)
}

WM_WHEEL(wp, hwnd)
{
   Critical
   pToken := Gdip_Startup()
   pBitmap := Gdip_CreateBitmapFromHBITMAP(oGuiData[hwnd])
   Gdip_GetImageDimensions(pBitmap, WidthBM, HeightBM)
   RatioBM := WidthBM/HeightBM
   SquareBM := WidthBM*HeightBM
   
   WinGetPos, X, Y, W, H, ahk_id %hwnd%
   
   DeltaW := Round(W/(!wp ? 10 : 11))
   DeltaW := wp ? -DeltaW : DeltaW
   ResultW := W + DeltaW
   ResultH := Round(ResultW/RatioBM)
   ResultX := X - Round(DeltaW/2)
   ResultY := Y - Round((ResultH - H)/2)
   SquareWin := ResultW*ResultH
   if (!wp && SquareWin > 13000000) || (wp && SquareWin < 1000 && SquareWin < SquareBM)
      Return, "", Gdip_DisposeImage(pBitmap), Gdip_Shutdown(pToken)

   hbm := CreateDIBSection(ResultW, ResultH)
   hdc := CreateCompatibleDC()
   obm := SelectObject(hdc, hbm)
   G := Gdip_GraphicsFromHDC(hdc)
   
   Gdip_SetInterpolationMode(G, 7)
   Gdip_DrawImage(G, pBitmap, 0, 0, ResultW, ResultH, 0, 0, WidthBM, HeightBM)
   pPen := Gdip_CreatePen(0xFF808080, 2)
   Gdip_DrawRectangle(G, pPen, 1, 1, ResultW - 2, ResultH - 2)
   
   UpdateLayeredWindow(hwnd, hdc, ResultX, ResultY, ResultW, ResultH)

   Gdip_DeletePen(pPen), SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
   Gdip_DeleteGraphics(G), Gdip_DisposeImage(pBitmap), Gdip_Shutdown(pToken)
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

44

Re: AHK: Скриншот выделенной части экрана поверх всех окон

Спасибо огромное вам teadrinker то что нужно , всё работает.

45

Re: AHK: Скриншот выделенной части экрана поверх всех окон

А где брать ф-ию Gdip_Startup() ? Без нее скрипт из 43-го поста не работает.

Win10x64, AHK v1.1.25

46

Re: AHK: Скриншот выделенной части экрана поверх всех окон

Там же написано:

Для работы скрипта необходима библиотека Gdip.ahk
https://www.dropbox.com/s/73vpu9xdzn5ys13/Gdip.ahk?dl=1

47

Re: AHK: Скриншот выделенной части экрана поверх всех окон

Доброго времени суток. Решил добавить выборочное сохранение файла , но файл не сохраняется. Подскажите где ошибка.

WM_LBUTTONDBLCLK()
{
   pToken := Gdip_Startup()
   pBitmap := Gdip_CreateBitmapFromHBITMAP(oGuiData[A_Gui])

res := Gdip_SaveBitmapToFile(pBitmap, OutFile "\" A_Now ".png")

 FileSelectFile, res, S3, %OutFile%\%A_Now%.png, Сохранить скриншот, All Files(*.*)

 DllCall("DeleteObject", Ptr, oGuiData[A_Gui])
   oGuiData.Delete(A_Gui)
   Gui, %A_Gui%:Destroy
   Gdip_DisposeImage(pBitmap), Gdip_Shutdown(pToken)

}

48

Re: AHK: Скриншот выделенной части экрана поверх всех окон

А чему переменная OutFile в шестой строке равна?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

49

Re: AHK: Скриншот выделенной части экрана поверх всех окон

Как написано в справке. OutFile: Корневой (начальный) каталог, который предположительно является папкой нижележащего уровня в %A_WorkingDir% в том случае, если абсолютный путь точно не определен. Может я чего то недопонимаю. Но по идее всё ведь должно работать.

50

Re: AHK: Скриншот выделенной части экрана поверх всех окон

А причём тут справка к  FileSelectFile? Я про шестую строку спросил, ещё до неё.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg