用AutoHotkey轻松自定义播放幻灯片的其中几张(可固定前置和后置幻灯片)
需求来源:公司要求对来访客户播放欢迎PPT(可能同时来几拨客户,所以设置5秒自动切换)
为了方便维护,便把所有客户的幻灯片放到一个PPT里,但是这样给自定义放映带来困难,
PPT自带的自定义幻灯片放映设置比较麻烦,所以有了此脚本。
- 支持【前置】和【后置】播放固定幻灯片,比如企业文化等,中间再放映客户欢迎页面
- 为了方便脚本选择要放映哪些客户,选用幻灯片的备注内容来判断
PPT文件要求:
- 前置幻灯片备注为b(意为before),后置幻灯片备注为a(意为after)
- 其他幻灯片任意备注,隐藏的幻灯片则会被无视
- 幻灯片要自行设置自动换片时间,,脚本会自动开启无限循环放映功能。可下载 PPT示例文件
- 运行以下脚本,打开PPT后,按F9,就会显示相应备注,勾选相应内容点击确定即可。则会循环播放前置+选择的页面+后置。
;前后的幻灯片,统一放在末尾
;备注b 表示前面(before)
;备注a 表示后面(after)
#SingleInstance Force
"".base.base := _String ;声明
F12::reload
F9::
if !ProcessExist("POWERPNT.EXE")
return
;所有备注
arrAll := getNotesAll()
;分成3类
arrMain := []
arrRes := []
arrAfter := []
for _, arr in arrAll {
if (arr[2] == "b")
arrRes.push(arr[1]) ;前置的直接放到 arrRes
else if (arr[2] == "a")
arrAfter.push(arr[1])
else
arrMain.push(arr)
}
;选择幻灯片
for _, v in _Gui.getArrByCheckBox(arrMain, arr=>arr[2])
arrRes.push(v)
if !arrRes.length()
return
;NOTE 添加固定的内容
for _, v in arrAfter
arrRes.push(v)
;设置自定义播放
ppt := ComObjActive("Powerpoint.application")
;退出当前播放
try
ppt.SlideShowWindows(1).view.exit
ap := ppt.ActivePresentation
arrA := ComObjArray(12, arrRes.length())
for _, v in arrRes
arrA[A_Index-1] := ap.slides(v).SlideID
nn := "tmp"
ss := ap.SlideShowSettings
try
ss.NamedSlideShows(nn).delete
ss.NamedSlideShows.add(nn, arrA)
;播放
ss.RangeType := 3 ;用名称播放
ss.SlideShowName := nn
ss.AdvanceMode := 2 ;时间自动切换
ss.LoopUntilStopped := true ;无限循环
ss.run
return
; 获取所有备注[幻灯片序号, 内容]
getNotesAll(filterHidden:=true) {
arr := []
for sl in ComObjActive("Powerpoint.application").ActivePresentation.slides
{
if (filterHidden && sl.SlideShowTransition.hidden)
continue
text := rtrim(sl.NotesPage.Shapes.Placeholders(2).TextFrame.TextRange.text, "`n")
if !strlen(text)
continue
arr.push([A_Index, text])
}
return arr
}
class _Gui
{
;通过checkbox获取选择的内容(含顺序)
;arrs可包含多个一维
; ["a","b","c"]
; 或
; [[2,"a"],[1,"b"],[3,"c"]]
;funcShow(二维数组才有用) 参数是 arrs 的单项 arr
getArrByCheckBox(arrs, funcShow:="", strTips:="")
{
if !isobject(funcShow)
funcShow := x=>x
saveCoord := A_CoordModeToolTip
CoordMode("tooltip", "window")
oGui := GuiCreate()
oGui.OnEvent("escape", "doExit")
oGui.OnEvent("close", "doExit")
oGui.SetFont("s13 cRED")
if strlen(strTips)
oGui.AddText(, strTips)
oGUI.AddRadio("H20 section", "全选").OnEvent("click", "selectAll")
oGUI.AddRadio("H20 ys", "不选").OnEvent("click", "selectNone")
oGUI.AddRadio("H20 ys", "反选").OnEvent("click", "selectReverse")
;添加核心内容
oGui.SetFont("s13 c0")
arrCtl := []
idxAll := 0
this.arrIdx := []
if isobject(arrs[1]) ;二维
{
for _, arr in arrs
{
idx := A_Index
idxAll++
if (A_Index == 1)
{
if (idx == 1)
arrCtl[idxAll] := oGui.AddCheckbox("H20 xs section",funcShow.call(arr)) ;"H20 xs checked section"
else
arrCtl[idxAll] := oGui.AddCheckbox("H20 ys section",funcShow.call(arr))
}
else
arrCtl[idxAll] := oGui.AddCheckbox("H20 xs",funcShow.call(arr))
arrCtl[idxAll].name := idxAll ;记录序号当作值
arrCtl[idxAll].OnEvent("click", "doClick")
;if (mod(idx,2) == 1) ;红黑字交替
;oGui.SetFont("cRED")
;else
;oGui.SetFont("c0")
}
}
else
{
idx := 0
for _, v in arrs
{
if strlen(v)
{
idx++
arrCtl[idx] := oGui.AddCheckbox("H20 xs",v)
arrCtl[idx].OnEvent("click", "doClick")
}
}
}
oGui.AddButton("w130 h30 default","确认").OnEvent("click", "doDone")
oGui.show()
WinWaitClose("ahk_id " . oGui.Hwnd)
CoordMode("tooltip", saveCoord)
return this.arrIdx
tips()
{
res := ""
for _, idx in this.arrIdx
res .= funcShow.call(arrs[idx]) . "`n"
tooltip(rtrim(res, "`n"))
}
doExit() ;清空
{
tooltip
this.arrIdx := []
oGui.destroy
}
doDone()
{
tooltip
oGui.destroy
}
doClick(ctl)
{
idxCtl := integer(ctl.name)
if ctl.Value
;this.arrIdx.push(ctl.text)
this.arrIdx.push(idxCtl)
else
this.arrIdx.RemoveAt(index(this.arrIdx, idxCtl))
obj := oGUI.pos
tips()
}
selectAll()
{
for k, v in arrCtl
ControlSetChecked(true, arrCtl[A_Index], "ahk_id " . oGUI.Hwnd)
}
selectNone()
{
for k, v in arrCtl
ControlSetChecked(false, arrCtl[A_Index], "ahk_id " . oGUI.Hwnd)
}
selectReverse()
{
for k, v in arrCtl
ControlSetChecked("Toggle", arrCtl[A_Index], "ahk_id " . oGUI.Hwnd)
}
;在arr里的第1个序号
index(arr, val)
{
for k, v in arr
{
if (v = val)
return k
}
return false
}
}
}