ExifMove v1.90增加了对可能生成重复文件的判断,重复文件时,会自动重命名,另可以手工输入目标目录和目标文件格式

; ==============================================================
; 名称: 	ExifMove
; 用途: 	把图片移动到拍照时间目录
; --------------------------------------------------------------
; 作者: 	tmplinshi
; AHK 版本: AHK_L
; 操作系统: >= WIN_XP
; ==============================================================

#NoTrayIcon
#NoEnv
#SingleInstance Force
SetWorkingDir %A_ScriptDir%
SetBatchLines -1
ListLines Off

gui_title := "ExifMove v1.90 by tmplinshi"

arg1 = %1%


; #################################
;		界面
; #################################
;
Gui, +hwndhMainGui
Gui, Color, White

; ///////////////////////////////////
Gui, Font, s12 bold cFF8000
Gui, Add, GroupBox, w550 h80 vbox1, 源文件夹
Gui, Font
Gui, Font, s12
	Gui, Add, Edit, xp+10 yp+25 w420 Section h20 vdir_source gModify_destRoot, % GetDir(arg1)
	Gui, Add, Button, ys h20 gbtn_browseDir_source, ...
	Gui, Font
	Gui, Add, Button, ys h20 gOpenDir vOpen_dir_source, 打开
	Gui, Font, s12

	Gui, Add, Checkbox, xs vRecurse, 包括子文件夹

; ///////////////////////////////////
Gui_Add_Picture("move.png", "x210 Section w24 h24", "hImgArrow")
Gui, Add, Radio, ys+5 gChangePic vIsCopyImg, 复制
Gui, Add, Radio, ys+5 gChangePic vIsMoveImg Checked, 移动

; ///////////////////////////////////
Gui, Font, s12 bold cFF8000
Gui, Add, GroupBox, xm w550 h140 vbox2 , 目标
	Gui, Font
	Gui, Add, Text, xp+10 yp+25 Section c8AAAED, (如果目标根目录为空,则默认与源文件夹相同。)
	Gui, Font, s12

	Gui, Add, Text, xs Section, 根目录:
	Gui, Add, Edit, ys w350 h20 vdir_destRoot, % GetDir(arg1)
	Gui, Add, Button, ys h20 gbtn_browseDir_Dest, ...
	Gui, Font
	Gui, Add, Button, ys h20 gOpenDir vOpen_dir_destRoot, 打开
	Gui, Font, s12

	Gui_Add_BoldText("xs Section cBlack", "输入")
	Gui, Add, Text, x+0, 或选择子目录:
	Gui, Add, ComboBox, x+5 w230 vdir_destSub gUpdateExample HwndHCB1, YYYYMMDD|YYYYMM_DD|YYYY|YYYYMM|YYYYMMDD|YYYY_MM|YYYY_MM_DD|YYYYMM-DD|YYYY-MM|YYYY-MM-DD|ExtYYYYMMDD||ExtYYYYMM_DD|ExtYYYY|ExtYYYYMM|ExtYYYYMMDD|ExtYYYY_MM|ExtYYYY_MM_DD|ExtYYYYMM-DD|ExtYYYY-MM|ExtYYYY-MM-DD
	Gui, Font
	; Gui, Add, Text, ys+8 c8AAAED, 示例:
	Gui, Add, Text, x+5 hp 0x200 c8AAAED vExample_SubDir w155, % __UpdateExample("dir_destSub")
	Gui, Font, s12

	Gui_Add_BoldText("xs Section cBlack", "输入")
	Gui, Add, Text, x+0, 或选择文件名:
	Gui, Add, ComboBox, x+5 w230 vdestName gUpdateExample HwndHCB2, YYYYMMDD_hhmm_FileName.Ext|YYYYMMDDhhmm_FileName.Ext|FileName.Ext||hhmm_FileName.Ext|FileName_YYYYMMDD_hhmm.Ext|FileName_YYYYMMDDhhmm.Ext|FileName.Ext|FileName_hhmm.Ext|FileName_YYYYMMDD.Ext|YYYYMMDD.Ext|YYYYMMDD_FileName.Ext
	Gui, Font
	; Gui, Add, Text, ys+8 c8AAAED, 示例:
	Gui, Add, Text, x+5 hp 0x200 c8AAAED vExample_FileName w155, % __UpdateExample("destName")
	Gui, Font, s12

; ///////////////////////////////////
Gui, Font, s12 bold cFF8000
Gui, Add, GroupBox, xm w550 h197 vbox3, 筛选
Gui, Font
Gui, Font, s12
	Gui, Add, Checkbox, xp+10 yp+25 Section vEnable_DateRange gEnable_DateRange, 日期:
	Gui, Add, DateTime, ys w160 vdate_start
	Gui, Add, Text, ys vtxt_1, 到
	Gui, Add, DateTime, ys w160 vdate_end, 

	Gui, Add, Text, xs Section, 后缀:
	Gui, Add, Checkbox, ys vsearch_jpeg h20 Checked, jpeg
	Gui, Add, Checkbox, ys vsearch_jpg h20 Checked, jpg
	Gui, Add, Checkbox, ys vsearch_tif h20 Checked, tif
	Gui, Add, Checkbox, ys vsearch_png h20 gPrompt, png
	Gui, Add, Checkbox, ys vsearch_gif h20 gPrompt, gif
	Gui, Add, Checkbox, ys vsearch_bmp h20 gPrompt, bmp
	Gui, Add, Checkbox, ys vsearch_ico h20 gPrompt, ico

	GuiControlGet, search_jpeg, Pos
	Gui, Add, Checkbox, xs x%search_jpegX% vEnable_CustomExt gEnable_CustomExt, 自定义后缀:
	Gui, Add, Edit, xp+120 w330 h20 vCustomExt, mp4,mp3,avi,png,gif,bmp,ico,amr,wav,mov

	Gui, Add, Checkbox, xs Section vSearchNoExifFile, 包括无 Exif 文件
	Gui, Font
	Gui, Add, Text, ys+3  xp+155 c8AAAED, (用修改日期代替拍照日期,对mp4,jpg等文件修改日期就是拍摄日期)  ;但本程序使用函数可以更准确地获取系统中的拍摄日期

	Gui, Font
	Gui, Font, s12
    Gui, Add, Text, xs 0x10 w530 h1 ; 横线
    Gui, Add, Text, xs 0x10 w530 h1 ; 横线
	Gui, Add, Text, xs h27 0x200, 过滤:排除
	Gui, Add, DropDownList, x+5 w60 vDX, 小于||大于
	Gui, Add, Edit, x+5 w90 Center hp vMaxSize, 
	Gui, Add, DropDownList, x+5 w50 vDW, KB||MB
	Gui, Add, Text, x+5 hp 0x200, 的文件
	
Gui, Font, s12
; ///////////////////////////////////
Gui, Add, Button, x120 yp+50 w150 Section h40 vbtn_start gbtn_start, 开始
Gui, Add, Button, xp+200 w150 h40 Disabled vbtn_stop gbtn_stop, 停止

; ///////////////////////////////////
Gui, Font
Gui, Add, Progress, xm Section w490 h10 vMyProgress Hidden
Gui, Add, Text, ys-2 w30 h10 vPercent Hidden, 100`%

; ///////////////////////////////////
Gui, Add, StatusBar,, %A_Space%
	SB_SetParts(450)

_dis_en("Enable_DateRange", "date_start txt_1 date_end")
_dis_en("Enable_CustomExt", "CustomExt")


; ------------ 获取三个 GroupBox 的坐标
	GuiControlGet, box1, Pos
	GuiControlGet, box2, Pos
	GuiControlGet, box3, Pos

; ------------ 创建透明遮罩窗口
	Gui, Trans: +ToolWindow  +LastFound +hwndhTrans -Caption +Owner1
	Gui, Trans: Color, 00FF00
	WinSet, Transparent, 50
	WinSet, ExStyle, +0x20     ; 鼠标穿透

	SetTimer, _CoverBox, 100

Gui, Show,, %gui_title%
Return

_CoverBox:
	CoverBox()
Return

Modify_destRoot:
	GuiControlGet, dir_source
	GuiControl,, dir_destRoot, %dir_source%
Return

Prompt:
	GuiControlGet, SearchNoExifFile
	if SearchNoExifFile
		Return

	GuiControlGet, IsChecked,, %A_GuiControl%
	if !IsChecked
		Return

	MsgBox2("是否勾选“包括无 Exif 文件”", "提示", 36)
	IfMsgBox, Yes
		GuiControl,, SearchNoExifFile, 1
Return


OpenDir:
	GuiControlGet, dir_source
	SetWorkingDir %dir_source%

	GuiControlGet, TargetPath,, % SubStr(A_GuiControl, 6)
	TargetPath := Trim(TargetPath, " `t/")
	Run, %TargetPath%,, UseErrorLevel
Return


ChangePic:
	if !hBitmap_copy
	{
		hBitmap_copy := Create_copy_png()
		hBitmap_move := Create_move_png()
	}

	Gui, Submit, NoHide
	SendMessage, 0x172, 0x0, (IsCopyImg ? hBitmap_copy : hBitmap_move),, ahk_id %hImgArrow%
Return

UpdateExample:
	__UpdateExample(A_GuiControl)
Return

Enable_DateRange:
	_dis_en("Enable_DateRange", "date_start txt_1 date_end")
Return

Enable_CustomExt:
	_dis_en("Enable_CustomExt", "CustomExt")
	Goto, Prompt
Return


; #################################
;		...
; #################################
;
btn_browseDir_source:
	FileSelectFolder, Dir, *%A_Desktop%,, 选择源文件夹
	if (Dir = "")
		Return

	GuiControl,, dir_source, % Dir
	GuiControl,, dir_destRoot, % Dir
return

btn_browseDir_dest:
	FileSelectFolder, Dir, *%A_Desktop%,, 选择目标根目录
	if (Dir = "")
		Return

	GuiControl,, dir_destRoot, % Dir
Return

; #################################
;		停止
; #################################
;
btn_stop:
	GuiControl, Disable, btn_stop
	IsStop := True
Return

stop_run:
	GuiControl, Enable, btn_start
	GuiControl, Disable, btn_stop

	GuiControl, Hide, MyProgress
	GuiControl, Hide, Percent
	GuiControl,, MyProgress
	GuiControl,, Percent

	SB_SetText("")
	SB_SetText("", 2)
Return


; #################################
;		开始
; #################################
;
btn_start:
	Gui, Submit, NoHide

	; ------------ 检查【原文件夹】
		if (dir_source = "") {
			MsgBox2("请先设置原文件夹", "提示", 48)
			Return
		}

		If !FileExist(dir_source) {
			MsgBox2("原文件夹不存在,请重新设置", "提示", 48)
			Return
		}

	; ------------ 检查【后缀】
		ExtList := "jpeg|jpg|tif|png|gif|bmp|ico", SearchExt := ""

		Loop, Parse, ExtList, |
			if search_%A_LoopField%
				SearchExt .= A_LoopField ","

		if !( SearchExt := Trim(SearchExt, ",") ) {
			MsgBox2("请先勾选至少一个图片后缀", "提示", 48)
			Return
		}

		if Enable_CustomExt
		{
			CustomExt := RegExReplace(CustomExt, "[, t]+", ",")
			CustomExt := Trim(CustomExt, ",")
			SearchExt .= "," CustomExt
		}

	; ------------ 判断“排除”设置
		MaxSize := RegExReplace(MaxSize, "[^d.]")
		If (MaxSize != "")
			MaxSize := (DW = "KB") ? MaxSize * 1024 : MaxSize * 1024 * 1024

	; ------------ 确认操作
		MsgBox2("确定要" (IsCopyImg ? "复制" : "移动") "吗?", "确认", 36)
		IfMsgBox, No
			Return

	; ------------------------------------------------------------------------------------
	GuiControl, Disabled, btn_start
	GuiControl, Enable, btn_stop
	IsStop := False

	SetWorkingDir %dir_source%

	; ------------ 格式化“开始日期”和“结束日期”
		if Enable_DateRange {
			date_start := SubStr(date_start, 1, 8)
			date_end   := SubStr(date_end, 1, 8)
		}

	; ------------ 目标根目录
		if (dir_destRoot = "")
			dir_destRoot := dir_source

		dir_destRoot := Trim(dir_destRoot, " `t/")

	SB_SetText("正在统计文件数量...")

		FileTotal := 0, FileList := ""

		Loop, %dir_source%*,, %Recurse%
		{
			if IsStop
				Goto, stop_run

			if A_LoopFileExt in %SearchExt%
			{
				If (MaxSize != "") {
					FileGetSize, size, %A_LoopFileFullPath%
					If (size > MaxSize && DX = "大于") || (size  0 	; 超过了最大日期
					Continue
			}
			
			; 获取原文件名
			SplitPath, A_LoopField, SourceFileName,, SourceExt, SourceFileNameNoExt

			; 替换字符
			_SubDir_And_Filename := dir_destSub "" destName
			_SubDir_And_Filename := RegExReplace(_SubDir_And_Filename, "MM", a2)
			_SubDir_And_Filename := RegExReplace(_SubDir_And_Filename, "mm", a5 "00")
			StringReplace, _SubDir_And_Filename, _SubDir_And_Filename, YYYY, %a1%, All
			StringReplace, _SubDir_And_Filename, _SubDir_And_Filename, DD, %a3%, All
			StringReplace, _SubDir_And_Filename, _SubDir_And_Filename, hh, %a4%, All
			StringReplace, _SubDir_And_Filename, _SubDir_And_Filename, Filename, %SourceFileNameNoExt%, All
			StringReplace, _SubDir_And_Filename, _SubDir_And_Filename, Ext, %SourceExt%, All

			; ------------
			_destFile := dir_destRoot "" _SubDir_And_Filename	; 目标文件
			SplitPath, _destFile,, _destDir						; 分解出目标文件夹名称

			; 创建目标文件夹
			IfNotExist, %_destDir%
				FileCreateDir, %_destDir%

			; 重命名重名文件
			_destFile := CheckDupFile(_destFile)

			; 复制/移动文件
			if IsCopyImg
				FileCopy, %A_LoopField%, %_destFile%, 1
			else
				FileMove, %A_LoopField%, %_destFile%, 1

			SuccessCount ++
		}

CancelLoop:
	FileList := ""
	Str_CopyOrMove := IsCopyImg ? "复制" : "移动"
	MsgBox2("已" Str_CopyOrMove " " SuccessCount " 个文件", IsStop ? "处理结果" : "完毕")
	Goto, stop_run
Return


GuiDropFiles:
	Gui, Trans:Cancel

	if (ctrl = "box1")
		Control := "dir_source"
	else if (ctrl = "box2")
		Control := "dir_destRoot"
	else
		Return

	GuiControl,, %Control%, % GetDir(A_GuiEvent)

	; 设置目标根目录
	if (Control = "dir_source")
	{
		GuiControl,, dir_destRoot, % GetDir(A_GuiEvent)
		GuiControl, Enable, Open_dir_source
		GuiControl, Enable, Open_dir_destRoot
	}
	Else
		GuiControl, Enable, Open_dir_destRoot
Return


GuiClose:
ExitApp

; ====================================== 以下是函数 ======================================
GetImgDate(FileName, dateType = "date_exif")		; date_exif=相片拍照日期, date_create=修改日期
{
	static objShell := ComObjCreate("Shell.Application")
	static date_exif := InStr(A_OSVersion, "WIN_7") ? 12 : 25
	static date_create := InStr(A_OSVersion, "WIN_7") ? 3 : 3   ;win7或xp上使用创建日期是4:4 ,修改日期是:3:3
;本来想用创建日期, 但是mp4等文件的修改日期就是拍摄日期,所以上面语句改为3:3
	SplitPath, FileName, sFileName, sFileDir
	objFolder   := objShell.Namespace(sFileDir . "") 
	objFilename := objFolder.Parsename(sFileName)
	iValue      := objFolder.GetDetailsOf(objFilename, %dateType%)

	Return iValue
}

Gui_Add_Picture(file, Options, hWnd)
{
	global
	StringReplace, name, file, ., _, a
	Gui, Add, Picture, 0xE %Options% hWnd%hWnd%
	SendMessage, 0x172, 0x0, % ( Create_%name%() ), , % "ahk_id " %hWnd%
}

MsgBox2(Text, Title = "", Options = "")
{
	gui, +OwnDialogs
	MsgBox, % Options, %Title%, %Text%
}

; _dis_en("send_email", "_smtp _from _pwd _to", "gui2:")
;
_dis_en(checkbox_var, control_list, gui_name = "")
{
    control_list := RegExReplace(control_list, "s+", " ")
    control_list := Trim(control_list)
	
    GuiControlGet, checkbox_value, % gui_name, % checkbox_var
    action := checkbox_value ? "Enable" : "Disable"
    
    Loop, Parse, control_list, %A_Space%
        GuiControl, %gui_name%%action%, % A_LoopField
}

GetFullPathName( SPath ) {
	VarSetCapacity(lPath,260,0), DllCall("GetLongPathName", Str,SPath, Str,lPath, UInt,260 )
	Return lPath
}

GetDir(InPath)
{
	SplitPath, InPath,, OutDir, OutExtension

	if (OutExtension != "lnk")
		Return GetFullPathName(  FileExist(InPath "") ? InPath : OutDir  )

	FileGetShortcut, %InPath%, OutTarget, OutDir
	Return GetFullPathName(  (OutDir = "") ? RegExReplace(OutTarget, "\[^\]*$") : OutDir  )
}

__UpdateExample(ctrl) {
	GuiControlGet, ExampleStr,, %ctrl%

	StringReplace, ExampleStr, ExampleStr, YYYY, %A_YYYY%
	StringReplace, ExampleStr, ExampleStr, DD, %A_DD%
	StringReplace, ExampleStr, ExampleStr, hh, %A_Hour%
	ExampleStr := RegExReplace(ExampleStr, "MM", A_MM)
	ExampleStr := RegExReplace(ExampleStr, "mm", A_Min)

	ExmapleControl := (ctrl = "dir_destSub" ? "Example_SubDir" : "Example_FileName")
	GuiControl,, %ExmapleControl%, %ExampleStr%
	Return ExampleStr
}

Gui_Add_BoldText(Options="", Text="", NewFont="s12", OldFont="s12")
{
	global
	Gui, Font
	Gui, Font, %NewFont% bold
	Gui, Add, Text, %Options%, %Text%
	Gui, Font
	Gui, Font, %OldFont%
}

CheckDupFile(fPath) {
	IfNotExist, % fPath
		Return fPath

	SplitPath, fPath, fName, fDir, fExt, fNameNoExt
	Loop
		IfNotExist, % fDir "" fNameNoExt " (" A_Index+1 ")." fExt
			Return fDir "" fNameNoExt " (" A_Index+1 ")." fExt
}

; -------------- 覆盖鼠标下的控件
	CoverBox() {
		global
		static pre_ctrl

		MouseGetPos, x, y, WinId

		If !( (A_Cursor = "Unknown") AND GetKeyState("LButton", "P") AND (WinId = hMainGui) )
			Return
		else
			IfWinNotActive, ahk_id %hMainGui%
				WinActivate, ahk_id %hMainGui%

		if ( (x >= box1X && x = box1Y && y = box2X && x = box2Y && y  http://www.autohotkey.com/board/topic/21213-how-to-convert-image-data-jpegpnggif-to-hbitmap/?p=139257
hData := DllCall("Kernel32.dllGlobalAlloc", "UInt", 2, "UPtr", DecLen, "UPtr")
pData := DllCall("Kernel32.dllGlobalLock", "Ptr", hData, "UPtr")
DllCall("Kernel32.dllRtlMoveMemory", "Ptr", pData, "Ptr", &Dec, "UPtr", DecLen)
DllCall("Kernel32.dllGlobalUnlock", "Ptr", hData)
DllCall("Ole32.dllCreateStreamOnHGlobal", "Ptr", hData, "Int", True, "PtrP", pStream)
hGdip := DllCall("Kernel32.dllLoadLibrary", "Str", "Gdiplus.dll", "UPtr")
VarSetCapacity(SI, 16, 0), NumPut(1, SI, 0, "UChar")
DllCall("Gdiplus.dllGdiplusStartup", "PtrP", pToken, "Ptr", &SI, "Ptr", 0)
DllCall("Gdiplus.dllGdipCreateBitmapFromStream",  "Ptr", pStream, "PtrP", pBitmap)
DllCall("Gdiplus.dllGdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "PtrP", hBitmap, "UInt", 0)
DllCall("Gdiplus.dllGdipDisposeImage", "Ptr", pBitmap)
DllCall("Gdiplus.dllGdiplusShutdown", "Ptr", pToken)
DllCall("Kernel32.dllFreeLibrary", "Ptr", hGdip)
DllCall(NumGet(NumGet(pStream + 0, 0, "UPtr") + (A_PtrSize * 2), 0, "UPtr"), "Ptr", pStream)
Return hBitmap
}

; ##################################################################################
; # This #Include file was generated by Image2Include.ahk, you must not change it! #
; ##################################################################################
Create_move_png(NewHandle := False) {
Static hBitmap := 0
If (NewHandle)
   hBitmap := 0
If (hBitmap)
   Return hBitmap
VarSetCapacity(B64, 1544  http://www.autohotkey.com/board/topic/21213-how-to-convert-image-data-jpegpnggif-to-hbitmap/?p=139257
hData := DllCall("Kernel32.dllGlobalAlloc", "UInt", 2, "UPtr", DecLen, "UPtr")
pData := DllCall("Kernel32.dllGlobalLock", "Ptr", hData, "UPtr")
DllCall("Kernel32.dllRtlMoveMemory", "Ptr", pData, "Ptr", &Dec, "UPtr", DecLen)
DllCall("Kernel32.dllGlobalUnlock", "Ptr", hData)
DllCall("Ole32.dllCreateStreamOnHGlobal", "Ptr", hData, "Int", True, "PtrP", pStream)
hGdip := DllCall("Kernel32.dllLoadLibrary", "Str", "Gdiplus.dll", "UPtr")
VarSetCapacity(SI, 16, 0), NumPut(1, SI, 0, "UChar")
DllCall("Gdiplus.dllGdiplusStartup", "PtrP", pToken, "Ptr", &SI, "Ptr", 0)
DllCall("Gdiplus.dllGdipCreateBitmapFromStream",  "Ptr", pStream, "PtrP", pBitmap)
DllCall("Gdiplus.dllGdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "PtrP", hBitmap, "UInt", 0)
DllCall("Gdiplus.dllGdipDisposeImage", "Ptr", pBitmap)
DllCall("Gdiplus.dllGdiplusShutdown", "Ptr", pToken)
DllCall("Kernel32.dllFreeLibrary", "Ptr", hGdip)
DllCall(NumGet(NumGet(pStream + 0, 0, "UPtr") + (A_PtrSize * 2), 0, "UPtr"), "Ptr", pStream)
Return hBitmap
}

给TA捐赠
共{{data.count}}人
人已捐赠
其他教程

[代码]批量创建按钮控件并响应点击事件

2020-3-27 20:35:57

其他教程

Explorer窗口遍历

2020-3-27 23:04:56

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索