Как задать папку для сохранения скриншотов? Topic is solved

Помощь в написании скриптов
marusa122
Posts: 135
Joined: 22 Mar 2023, 07:48

Как задать папку для сохранения скриншотов?

21 Apr 2023, 01:54

Здравствуйте. Есть скрипт:

Code: Select all

LWin:
Send, #{PrintScreen}
Return
По умолчанию он сохраняет сделанные скриншоты в папку Снимки экрана.
Вопрос: можно ли сделать так, чтобы скрипт сохранял скриншоты, сделанные с его помощью, в какую-нибудь другую папку? Например, D:\Рабочая папка\Изображения. А скриншоты, сделанные просто с помощью Win+PrtSc, когда скрипт не был запущен, продолжили сохраняться в папку Снимки экрана.
mcl
Posts: 361
Joined: 04 May 2018, 16:35

Re: Как задать папку для сохранения скриншотов?  Topic is solved

21 Apr 2023, 17:26

marusa122 wrote: По умолчанию он сохраняет сделанные скриншоты в папку Снимки экрана.
Это встроенная функция Windows 10. На моей Windows 7 такой скрипт будет помещать скриншот не в файл, а в буфер обмена.

marusa122 wrote: Вопрос: можно ли сделать так, чтобы скрипт сохранял скриншоты, сделанные с его помощью, в какую-нибудь другую папку?
Напрямую – нет. Но есть несколько вариантов:

1. Очевидный. После нажатия скрипт ждёт пару секунд, затем лезет в папку с общими скриншотами и перекладывает оттуда в нужное место самый свежий. Примерно так:

Code: Select all

LWin::
	Send #{PrintScreen}
	Sleep 2000
	
	maxFileTime := 0
	maxFileName := ""
	Loop, Files, C:\Users\%A_UserName%\Pictures\Screenshots\*.png
	{
		FileGetTime, iFileTime, %A_LoopFileLongPath%
		If (iFileTime > maxFileTime) {
			maxFileTime := iFileTime
			maxFileName := A_LoopFileLongPath
		}
	}
	
	If (maxFileName != "")
		FileMove, %maxFileName%, C:\myfolder
	
	Return
Из минусов – скорость (две секунды ожидания + перебор всех скриншотов в папке); возможны осечки, если часто вызывать этот хоткей, или если система задумается над скриншотом дольше чем на две секунды.

2. Простой. Вместо нажатия запускать стороннюю программу для снятия скриншотов, например NirCmd

Code: Select all

LWin::
RunWait, nircmd.exe savescreenshot C:\myfolder\scr~$currdate.MM_dd_yyyy$-~$currtime.HH_mm_ss$.png,, Hide
Return
Из минусов — придётся разбираться со сторонней программой и таскать её со скриптом.

3. Магический. Использовать в скрипте сторонние функции, например, вот эти, собранные из заклинаний чародея SKAN:
Осторожно, чёрная магия
Из минусов: если оно не работает — у вас нет ни единого шанса это починить.
marusa122
Posts: 135
Joined: 22 Mar 2023, 07:48

Re: Как задать папку для сохранения скриншотов?

21 Apr 2023, 17:42

mcl wrote:
21 Apr 2023, 17:26
Это встроенная функция Windows 10. На моей Windows 7 такой скрипт будет помещать скриншот не в файл, а в буфер обмена.
Вопрос не по теме: а реально ли настроить Windows 7 или XP так, чтобы в них эта функция тоже работала?..
mcl
Posts: 361
Joined: 04 May 2018, 16:35

Re: Как задать папку для сохранения скриншотов?

22 Apr 2023, 00:32

marusa122 wrote: реально ли настроить Windows 7 или XP так, чтобы в них эта функция тоже работала?..
Если бы WinXP можно было настроить как Win10, зачем была бы нужна Win10?
Можно использовать второй или третий способ — они действуют в обход системной функции.
marusa122
Posts: 135
Joined: 22 Mar 2023, 07:48

Re: Как задать папку для сохранения скриншотов?

22 Apr 2023, 02:15

mcl wrote:
21 Apr 2023, 17:26
В коде ниже три функции. Их нужно добавить в ваш скрипт и вызывать по хоткею MakeScreenShot("C:\MyFolder\MyFile.png").
Можно для особо одаренных - как задавать место сохранения скриншотов? Я попробовала делать скриншоты с его помощью, но скрипт сохраняет их в той же папке, где лежит сам.
marusa122
Posts: 135
Joined: 22 Mar 2023, 07:48

Re: Как задать папку для сохранения скриншотов?

22 Apr 2023, 03:16

Всё, вопрос снят. Методом тыка изменила скрипт:

Code: Select all

#NoEnv
#SingleInstance Force

LWin::
; Original by SKAN on D293 @ bit.ly/2krOIc9
MakeScreenshot(filename := "Screenshot.png") 
{
    count := 0
    Loop {
        count += 1
        filename := "D:\Рабочая папка\Изображения\Screenshot(" . count . ").png"
        if !FileExist(filename) {
            break
        }
    }
	X:=0,Y:=0,W:=A_ScreenWidth,H:=A_ScreenHeight
	VarSetCapacity(BITMAPINFO, 40, 0)
	NumPut(32, NumPut(1, NumPut(H, NumPut(W, NumPut(40,BITMAPINFO,"Int"),"Int"),"Int"),"Short"),"Short")
	
	hBM := DllCall("Gdi32.dll\CreateDIBSection", "Ptr",0, "Ptr",&BITMAPINFO, "Int",0, "PtrP",pBits := 0, "Ptr",0, "Int",0, "Ptr")
	sDC := DllCall("User32.dll\GetDC", "Ptr", 0, "Ptr")
	mDC := DllCall("Gdi32.dll\CreateCompatibleDC", "Ptr", 0, "Ptr")
	DllCall("Gdi32.dll\SelectObject", "Ptr",mDC, "Ptr",hBM)
	DllCall("Gdi32.dll\BitBlt", "Ptr",mDC, "Int",0, "Int",0, "Int",W, "Int",H, "Ptr",sDC, "Int",X, "Int",Y, "Int",0x40CC0020)
	
	GDIP("Startup")
	SavePicture(hBM, filename)
	GDIP("Shutdown")
	
	DllCall("Gdi32.dll\DeleteDC", "Ptr",mDC)
	DllCall("User32.dll\ReleaseDC", "Ptr", 0, "Ptr",sDC)
	DllCall("Gdi32.dll\DeleteObject", "Ptr",hBM)
}

; By SKAN on D293 @ bit.ly/2krOIc9
GDIP(C:="Startup") {                                      
	Static SI:=Chr(!(VarSetCapacity(Si,24,0)>>16)), pToken:=0, hMod:=0, Res:=0, AOK:=0
	If (AOK := (C="Startup" and pToken=0) Or (C<>"Startup" and pToken<>0))  {
	If (C="Startup") {
		hMod := DllCall("LoadLibrary", "Str","gdiplus.dll", "Ptr")
		Res  := DllCall("gdiplus\GdiplusStartup", "PtrP",pToken, "Ptr",&SI, "UInt",0)
	} Else { 
		Res  := DllCall("gdiplus\GdiplusShutdown", "Ptr",pToken)
		DllCall("FreeLibrary", "Ptr",hMod),   hMod:=0,   pToken:=0
	}}  
	Return (AOK ? !Res : Res:=0)    
}

; By SKAN on D293 @ bit.ly/2krOIc9
SavePicture(hBM, sFile) {
	Local V,  pBM := VarSetCapacity(V,16,0)>>8,  Ext := LTrim(SubStr(sFile,-3),"."),  E := [0,0,0,0]
	Local Enc := 0x557CF400 | Round({"bmp":0, "jpg":1,"jpeg":1,"gif":2,"tif":5,"tiff":5,"png":6}[Ext])
	E[1] := DllCall("gdi32\GetObjectType", "Ptr",hBM ) <> 7
	E[2] := E[1] ? 0 : DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Ptr",hBM, "UInt",0, "PtrP",pBM)
	NumPut(0x2EF31EF8,NumPut(0x0000739A,NumPut(0x11D31A04,NumPut(Enc+0,V,"UInt"),"UInt"),"UInt"),"UInt")
	E[3] := pBM ? DllCall("gdiplus\GdipSaveImageToFile", "Ptr",pBM, "WStr",sFile, "Ptr",&V, "UInt",0) : 1
	E[4] := pBM ? DllCall("gdiplus\GdipDisposeImage", "Ptr",pBM) : 1
	Return E[1] ? 0 : E[2] ? -1 : E[3] ? -2 : E[4] ? -3 : 1  
}
Теперь все работает отлично. Скрипт делает скриншоты с нужными названиями (а не обновляет содержимое файла "Screenshot.png") и сохраняет их там, где нужно.
mcl, спасибо за ликбез!

Return to “Помощь”

Who is online

Users browsing this forum: No registered users and 15 guests