Check For Unlinked Media FH7.fh_lua--[[
@Title: Check For Unlinked Media (FH7)
@Type: Standard
@Author: Mark Draper
@Version: 1.1
@LastUpdated: 14 May 2025
@Licence: This plugin is copyright (c) 2025 Mark Draper, and is licensed under the MIT License
which is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description: Lists all files in media folders not linked to Media Records in the current project, excluding
temporary files (beginning with either a tilde (~) or a dot), and database files with a .db extension. This
new plugin fully supports Unicode file names and is not restricted to searching the project Media folder,
but does not offer the option of deleting or moving the files.
]]
--[[
Version 1.0 (Feb 2024)
- Initial Plugin Store version
Version 1.1 (May 2025)
- Support for multiple monitors and enhanced tool-tips added
]]
fhInitialise(7)
fhu = require('fhUtils')
fhu.setIupDefaults()
FSO = luacom.CreateObject('Scripting.FileSystemObject')
function main()
-- get media files and list of folders used
local tblFiles = {}
local tblFolders = {}
local tblUsedFolders = {}
local tblN = {Files = 0, Folders = 0}
local DataFolder = fhGetContextInfo('CI_PROJECT_DATA_FOLDER') .. '\\'
local tblOptions = {Selection = 2, Split = true}
tblN.TotalFiles = Initialise()
if not tblN.TotalFiles then return end
-- get options
local Scope = 'CURRENT_PROJECT'
if fhGetContextInfo('CI_APP_MODE') ~= 'Project Mode' then Scope = 'LOCAL_MACHINE' end
local OptionsFile = fhGetPluginDataFileName(Scope):sub(1, -5) .. '.ini'
if FSO:FileExists(OptionsFile) then
tblOptions.Selection = fhGetIniFileValue(OptionsFile, 'Options', 'Selection', 'integer', 2)
tblOptions.Split = fhGetIniFileValue(OptionsFile, 'Options', 'Split', 'bool', true)
tblOptions.Folder = fhGetIniFileValue(OptionsFile, 'Options', 'Folder', 'text', '')
end
-- present menu
if not Menu(tblOptions) then return end
-- get user-selected folder
if tblOptions.Selection == 3 or tblOptions.Selection == 4 then
if not GetDefinedFolder(tblOptions) then return end
end
-- get folder list before tabulating media files if a specified location
if tblOptions.Selection < 5 then
tblFolders = GetFolders(tblOptions)
if not tblFolders or #tblFolders == 1 and not FSO:FolderExists(tblFolders[1]) then return end
end
-- tabulate project media files
ProgressBarStart(tblN.TotalFiles)
local pM = fhNewItemPtr()
pM:MoveToFirstRecord('OBJE')
while pM:IsNotNull() do
tblN.Files = tblN.Files + 1
local pF = fhNewItemPtr()
pF:MoveTo(pM, '~.FILE')
while pF:IsNotNull() do
local FileName = fhGetValueAsText(pF)
if FileName:match('^Media%\\') then
FileName = DataFolder .. FileName
end
if FSO:FileExists(FileName) then
local objFile = FSO:GetFile(FileName)
tblFiles[FileName:lower()] = true
local j = FileName:find('\\[^\\]+$') -- ParentFolder method not supported in WINE
local ParentFolder = FileName:sub(1, j-1)
tblUsedFolders[ParentFolder] = true
end
pF:MoveNext('SAME_TAG')
end
gblProgBar.Dialog.Title = 'Tabulating project Media Records (' .. tblN.Files .. ' of ' ..
tblN.TotalFiles .. ')...'
gblProgBar.bar.Value = tblN.Files
if gblProgBar.Cancel then return end
iup.LoopStep()
pM:MoveNext()
end
gblProgBar.Dialog:destroy()
-- populate folders table with used folders if general search
if tblOptions.Selection == 5 then
for Folder, _ in pairs(tblUsedFolders) do
table.insert(tblFolders, Folder)
end
end
if not tblFolders then return end
-- loop through listed folders
local tblUFiles = {}
local tblUFolders = {}
local tblUPath = {}
ProgressBarStart(#tblFolders)
for _, Folder in ipairs(tblFolders) do
gblProgBar.Dialog.Title = 'Getting folder listings...'
tblN.Folders = tblN.Folders + 1
gblProgBar.bar.Value = tblN.Folders
local objFolder = FSO:GetFolder(Folder)
for _, File in luacom.pairs(objFolder.Files) do
if not File.Name:match('^[.~]') and not File.Name:match('.db$') and not
tblFiles[Folder:lower() .. '\\' .. File.Name:lower()] then
if tblOptions.Split then
table.insert(tblUFiles, File.Name)
table.insert(tblUFolders, StripDataFolder(Folder, DataFolder))
else
table.insert(tblUPath, Folder .. '\\' .. File.Name)
end
end
end
if gblProgBar.Cancel then return end
iup.LoopStep()
end
gblProgBar.Dialog:destroy()
-- save and return selections
fhSaveTextFile(OptionsFile, '[Options]', 'UTF-16LE')
fhSetIniFileValue(OptionsFile, 'Options', 'Selection', 'integer', tblOptions.Selection)
fhSetIniFileValue(OptionsFile, 'Options', 'Split', 'bool', tblOptions.Split)
fhSetIniFileValue(OptionsFile, 'Options', 'Folder', 'text', tblOptions.Folder)
-- output results
if #tblUFiles + #tblUPath == 0 then
MessageBox('No unlinked files in location specified.', 'OK', 'INFORMATION')
return
end
fhOutputResultSetTitles('Unlinked Files')
if tblOptions.Split then
fhOutputResultSetColumn('File', 'text', tblUFiles, #tblUFiles, 120, 'align_left', 2)
fhOutputResultSetColumn('Folder', 'text', tblUFolders, #tblUFolders, 200, 'align_left', 1)
else
fhOutputResultSetColumn('File', 'text', tblUPath, #tblUPath, 250, 'align_left', 1)
end
end
-- ******************************************************************************************************--
function Initialise()
-- count media records
local pM = fhNewItemPtr()
local Count = 0
pM:MoveToFirstRecord('OBJE')
while pM:IsNotNull() do
Count = Count + 1
pM:MoveNext()
end
-- exit if no media
if Count == 0 then
MessageBox('No Media Records.', 'OK', 'INFORMATION')
return
end
return Count
end
-- ******************************************************************************************************--
function Menu(tblOptions)
local ok
local tblO = {}
table.insert(tblO, iup.toggle{title = 'Project Media Folder'})
table.insert(tblO, iup.toggle{title = 'Project Media Folder and subfolders'})
table.insert(tblO, iup.toggle{title = 'Selected Folder'})
table.insert(tblO, iup.toggle{title = 'Selected Folder and subfolders'})
table.insert(tblO, iup.toggle{title = 'All linked folders',
tip = 'All folders containing a linked media file'})
local vboxOptions = iup.vbox{tblO[1], tblO[2], tblO[3], tblO[4], tblO[5]; gap = 10, margin = '10x10'}
local radioOptions = iup.radio{vboxOptions}
local frameOptions = iup.frame{radioOptions; title = 'Search location'}
table.insert(tblO, iup.toggle{title = 'Separate File/Folder columns'})
table.insert(tblO, iup.toggle{title = 'Full file path'})
local vboxOutput = iup.vbox{tblO[6], tblO[7]; gap = 10, margin = '10x10'}
local radioOutput = iup.radio{vboxOutput}
local frameOutput = iup.frame{radioOutput; title = 'Output format'}
local btnList = iup.button{title = 'List Files', padding = '5x3', tip = 'List unlinked Media files',
action = function(self) ok = true return iup.CLOSE end}
local btnClose = iup.button{title = 'Close', tip = 'Close plugin',
action = function(self) return iup.CLOSE end}
local hboxButtons = iup.hbox{btnList, btnClose; gap = 40, margin = 'x25', normalizesize = 'BOTH'}
local vbox = iup.vbox{frameOutput, hboxButtons; alignment = 'ACENTER', margin = '20x'}
local hbox = iup.hbox{frameOptions, vbox; margin = '20x20'}
-- define enhanced tool tips
local enhanced = true -- comment out this line if enhanced tool tips are not required
if enhanced then
for _, control in ipairs(tblO) do
control.TipBalloon = 'YES'
control.TipBalloonTitleIcon = 1 -- modify individually if different
end
tblO[5].TipBalloonTitle = 'All Linked Folders'
btnList.TipBalloon = 'YES'
btnList.TipBalloonTitle = 'List files'
btnList.TipBalloonTitleIcon = 1
btnClose.TipBalloon = 'YES'
btnClose.TipBalloonTitle = 'Close plugin'
btnClose.TipBalloonTitleIcon = 1
end
local dialog = iup.dialog{hbox; resize = 'NO', minbox = 'NO', maxbox = 'NO',
title = 'Check For Unlinked Media (FH7) (1.1)'}
iup.SetAttribute(dialog, 'NATIVEPARENT', fhGetContextInfo('CI_PARENT_HWND'))
if fhGetContextInfo('CI_APP_MODE') ~= 'Project Mode' then
tblO[1].Active = 'NO'
tblO[2].Active = 'NO'
end
if fhGetContextInfo('CI_APP_MODE') == 'Project Mode' then
tblO[tblOptions.Selection].Value = 'ON'
elseif tblOptions.Selection > 2 then
tblO[tblOptions.Selection].Value = 'ON'
else
tblO[3].Value = 'ON'
end
if not tblOptions.Split then tblO[7].Value = 'ON' end
dialog:popup()
if not ok then return end
for i=1, 5 do
if tblO[i].Value == 'ON' then tblOptions.Selection = i end
end
tblOptions.Split = tblO[6].Value == 'ON'
return true
end
-- ******************************************************************************************************--
function GetDefinedFolder(tblOptions)
local tblForbidden = {}
for _, Folder in ipairs({'C:\\', 'C:\\Program Files', 'C:\\Program Files (x86)',
'C:\\ProgramData', 'C:\\Users', 'C:\\Windows'}) do
tblForbidden[Folder] = true
end
repeat
local filedlg = iup.filedlg{dialogtype = 'DIR', directory = tblOptions.Folder,
title = 'Select Media Folder'}
filedlg:popup()
if filedlg.Status == '-1' then return end
if tblForbidden[filedlg.Value] or filedlg.Value:match('^C:\\Users\\[^\\]+$') then
MessageBox(filedlg.Value .. ' is a system folder.', 'OK', 'ERROR')
else
tblOptions.Folder = filedlg.Value
return true
end
until false
end
-- ******************************************************************************************************--
function GetFolders(tblOptions)
local tblF = {}
local function GetSubfolders(objParentFolder, tblF)
for _, Folder in luacom.pairs(objParentFolder.SubFolders) do
table.insert(tblF, Folder.Path)
GetSubfolders(Folder, tblF)
end
end
if tblOptions.Selection < 3 then
local MediaFolder = fhGetContextInfo('CI_PROJECT_DATA_FOLDER') .. '\\Media'
table.insert(tblF, MediaFolder)
if tblOptions.Selection == 1 then return tblF end
local objFolder = FSO:GetFolder(MediaFolder)
GetSubfolders(objFolder, tblF)
elseif tblOptions.Selection < 5 then
table.insert(tblF, tblOptions.Folder)
if tblOptions.Selection == 3 then return tblF end
local objFolder = FSO:GetFolder(filedlg.Value)
GetSubfolders(objFolder, tblF)
end
return tblF
end
-- ******************************************************************************************************--
function MessageBox(Message, Buttons, Icon, Title, Default)
-- replaces built-in function with custom version containing more options
local msgdlg = iup.messagedlg{value = Message, buttons = Buttons, dialogtype = Icon,
title = Title or 'Check For Unlinked Media (FH7)', buttondefault = Default}
msgdlg:popup()
return msgdlg.ButtonResponse
end
-- ******************************************************************************************************--
function StripDataFolder(Folder, MediaFolder)
local _, j = Folder:find(MediaFolder, 1, true)
if j then Folder = Folder:sub(j+1) end
return Folder
end
-- ******************************************************************************************************--
function ProgressBarStart(Max)
-- create and display a simple progress bar, and store in a global table
gblProgBar = {}
gblProgBar.bar = iup.progressbar{max = Max; rastersize = '400x30'}
gblProgBar.button = iup.button{title = 'Cancel'; padding = '10x3',
action = function(self) gblProgBar.Cancel = true end}
gblProgBar.vbox = iup.vbox{gblProgBar.bar, gblProgBar.button; gap = 20,
alignment = 'acenter', margin = '5x15'}
gblProgBar.Dialog = iup.dialog{gblProgBar.vbox; dialogframe = 'Yes', title = '',
border = 'Yes', menubox = 'No'}
iup.SetAttribute(gblProgBar.Dialog, 'NATIVEPARENT', fhGetContextInfo('CI_PARENT_HWND'))
gblProgBar.Dialog:showxy(iup.CENTER, iup.CENTER) -- Put up Progress Display
end
-- ******************************************************************************************************--
main()
--[[
@Title: Check For Unlinked Media (FH7)
@Type: Standard
@Author: Mark Draper
@Version: 1.1
@LastUpdated: 14 May 2025
@Licence: This plugin is copyright (c) 2025 Mark Draper, and is licensed under the MIT License
which is hereby incorporated by reference (see https://pluginstore.family-historian.co.uk/fh-plugin-licence)
@Description: Lists all files in media folders not linked to Media Records in the current project, excluding
temporary files (beginning with either a tilde (~) or a dot), and database files with a .db extension. This
new plugin fully supports Unicode file names and is not restricted to searching the project Media folder,
but does not offer the option of deleting or moving the files.
]]
--[[
Version 1.0 (Feb 2024)
- Initial Plugin Store version
Version 1.1 (May 2025)
- Support for multiple monitors and enhanced tool-tips added
]]
fhInitialise(7)
fhu = require('fhUtils')
fhu.setIupDefaults()
FSO = luacom.CreateObject('Scripting.FileSystemObject')
function main()
-- get media files and list of folders used
local tblFiles = {}
local tblFolders = {}
local tblUsedFolders = {}
local tblN = {Files = 0, Folders = 0}
local DataFolder = fhGetContextInfo('CI_PROJECT_DATA_FOLDER') .. '\\'
local tblOptions = {Selection = 2, Split = true}
tblN.TotalFiles = Initialise()
if not tblN.TotalFiles then return end
-- get options
local Scope = 'CURRENT_PROJECT'
if fhGetContextInfo('CI_APP_MODE') ~= 'Project Mode' then Scope = 'LOCAL_MACHINE' end
local OptionsFile = fhGetPluginDataFileName(Scope):sub(1, -5) .. '.ini'
if FSO:FileExists(OptionsFile) then
tblOptions.Selection = fhGetIniFileValue(OptionsFile, 'Options', 'Selection', 'integer', 2)
tblOptions.Split = fhGetIniFileValue(OptionsFile, 'Options', 'Split', 'bool', true)
tblOptions.Folder = fhGetIniFileValue(OptionsFile, 'Options', 'Folder', 'text', '')
end
-- present menu
if not Menu(tblOptions) then return end
-- get user-selected folder
if tblOptions.Selection == 3 or tblOptions.Selection == 4 then
if not GetDefinedFolder(tblOptions) then return end
end
-- get folder list before tabulating media files if a specified location
if tblOptions.Selection < 5 then
tblFolders = GetFolders(tblOptions)
if not tblFolders or #tblFolders == 1 and not FSO:FolderExists(tblFolders[1]) then return end
end
-- tabulate project media files
ProgressBarStart(tblN.TotalFiles)
local pM = fhNewItemPtr()
pM:MoveToFirstRecord('OBJE')
while pM:IsNotNull() do
tblN.Files = tblN.Files + 1
local pF = fhNewItemPtr()
pF:MoveTo(pM, '~.FILE')
while pF:IsNotNull() do
local FileName = fhGetValueAsText(pF)
if FileName:match('^Media%\\') then
FileName = DataFolder .. FileName
end
if FSO:FileExists(FileName) then
local objFile = FSO:GetFile(FileName)
tblFiles[FileName:lower()] = true
local j = FileName:find('\\[^\\]+$') -- ParentFolder method not supported in WINE
local ParentFolder = FileName:sub(1, j-1)
tblUsedFolders[ParentFolder] = true
end
pF:MoveNext('SAME_TAG')
end
gblProgBar.Dialog.Title = 'Tabulating project Media Records (' .. tblN.Files .. ' of ' ..
tblN.TotalFiles .. ')...'
gblProgBar.bar.Value = tblN.Files
if gblProgBar.Cancel then return end
iup.LoopStep()
pM:MoveNext()
end
gblProgBar.Dialog:destroy()
-- populate folders table with used folders if general search
if tblOptions.Selection == 5 then
for Folder, _ in pairs(tblUsedFolders) do
table.insert(tblFolders, Folder)
end
end
if not tblFolders then return end
-- loop through listed folders
local tblUFiles = {}
local tblUFolders = {}
local tblUPath = {}
ProgressBarStart(#tblFolders)
for _, Folder in ipairs(tblFolders) do
gblProgBar.Dialog.Title = 'Getting folder listings...'
tblN.Folders = tblN.Folders + 1
gblProgBar.bar.Value = tblN.Folders
local objFolder = FSO:GetFolder(Folder)
for _, File in luacom.pairs(objFolder.Files) do
if not File.Name:match('^[.~]') and not File.Name:match('.db$') and not
tblFiles[Folder:lower() .. '\\' .. File.Name:lower()] then
if tblOptions.Split then
table.insert(tblUFiles, File.Name)
table.insert(tblUFolders, StripDataFolder(Folder, DataFolder))
else
table.insert(tblUPath, Folder .. '\\' .. File.Name)
end
end
end
if gblProgBar.Cancel then return end
iup.LoopStep()
end
gblProgBar.Dialog:destroy()
-- save and return selections
fhSaveTextFile(OptionsFile, '[Options]', 'UTF-16LE')
fhSetIniFileValue(OptionsFile, 'Options', 'Selection', 'integer', tblOptions.Selection)
fhSetIniFileValue(OptionsFile, 'Options', 'Split', 'bool', tblOptions.Split)
fhSetIniFileValue(OptionsFile, 'Options', 'Folder', 'text', tblOptions.Folder)
-- output results
if #tblUFiles + #tblUPath == 0 then
MessageBox('No unlinked files in location specified.', 'OK', 'INFORMATION')
return
end
fhOutputResultSetTitles('Unlinked Files')
if tblOptions.Split then
fhOutputResultSetColumn('File', 'text', tblUFiles, #tblUFiles, 120, 'align_left', 2)
fhOutputResultSetColumn('Folder', 'text', tblUFolders, #tblUFolders, 200, 'align_left', 1)
else
fhOutputResultSetColumn('File', 'text', tblUPath, #tblUPath, 250, 'align_left', 1)
end
end
-- ******************************************************************************************************--
function Initialise()
-- count media records
local pM = fhNewItemPtr()
local Count = 0
pM:MoveToFirstRecord('OBJE')
while pM:IsNotNull() do
Count = Count + 1
pM:MoveNext()
end
-- exit if no media
if Count == 0 then
MessageBox('No Media Records.', 'OK', 'INFORMATION')
return
end
return Count
end
-- ******************************************************************************************************--
function Menu(tblOptions)
local ok
local tblO = {}
table.insert(tblO, iup.toggle{title = 'Project Media Folder'})
table.insert(tblO, iup.toggle{title = 'Project Media Folder and subfolders'})
table.insert(tblO, iup.toggle{title = 'Selected Folder'})
table.insert(tblO, iup.toggle{title = 'Selected Folder and subfolders'})
table.insert(tblO, iup.toggle{title = 'All linked folders',
tip = 'All folders containing a linked media file'})
local vboxOptions = iup.vbox{tblO[1], tblO[2], tblO[3], tblO[4], tblO[5]; gap = 10, margin = '10x10'}
local radioOptions = iup.radio{vboxOptions}
local frameOptions = iup.frame{radioOptions; title = 'Search location'}
table.insert(tblO, iup.toggle{title = 'Separate File/Folder columns'})
table.insert(tblO, iup.toggle{title = 'Full file path'})
local vboxOutput = iup.vbox{tblO[6], tblO[7]; gap = 10, margin = '10x10'}
local radioOutput = iup.radio{vboxOutput}
local frameOutput = iup.frame{radioOutput; title = 'Output format'}
local btnList = iup.button{title = 'List Files', padding = '5x3', tip = 'List unlinked Media files',
action = function(self) ok = true return iup.CLOSE end}
local btnClose = iup.button{title = 'Close', tip = 'Close plugin',
action = function(self) return iup.CLOSE end}
local hboxButtons = iup.hbox{btnList, btnClose; gap = 40, margin = 'x25', normalizesize = 'BOTH'}
local vbox = iup.vbox{frameOutput, hboxButtons; alignment = 'ACENTER', margin = '20x'}
local hbox = iup.hbox{frameOptions, vbox; margin = '20x20'}
-- define enhanced tool tips
local enhanced = true -- comment out this line if enhanced tool tips are not required
if enhanced then
for _, control in ipairs(tblO) do
control.TipBalloon = 'YES'
control.TipBalloonTitleIcon = 1 -- modify individually if different
end
tblO[5].TipBalloonTitle = 'All Linked Folders'
btnList.TipBalloon = 'YES'
btnList.TipBalloonTitle = 'List files'
btnList.TipBalloonTitleIcon = 1
btnClose.TipBalloon = 'YES'
btnClose.TipBalloonTitle = 'Close plugin'
btnClose.TipBalloonTitleIcon = 1
end
local dialog = iup.dialog{hbox; resize = 'NO', minbox = 'NO', maxbox = 'NO',
title = 'Check For Unlinked Media (FH7) (1.1)'}
iup.SetAttribute(dialog, 'NATIVEPARENT', fhGetContextInfo('CI_PARENT_HWND'))
if fhGetContextInfo('CI_APP_MODE') ~= 'Project Mode' then
tblO[1].Active = 'NO'
tblO[2].Active = 'NO'
end
if fhGetContextInfo('CI_APP_MODE') == 'Project Mode' then
tblO[tblOptions.Selection].Value = 'ON'
elseif tblOptions.Selection > 2 then
tblO[tblOptions.Selection].Value = 'ON'
else
tblO[3].Value = 'ON'
end
if not tblOptions.Split then tblO[7].Value = 'ON' end
dialog:popup()
if not ok then return end
for i=1, 5 do
if tblO[i].Value == 'ON' then tblOptions.Selection = i end
end
tblOptions.Split = tblO[6].Value == 'ON'
return true
end
-- ******************************************************************************************************--
function GetDefinedFolder(tblOptions)
local tblForbidden = {}
for _, Folder in ipairs({'C:\\', 'C:\\Program Files', 'C:\\Program Files (x86)',
'C:\\ProgramData', 'C:\\Users', 'C:\\Windows'}) do
tblForbidden[Folder] = true
end
repeat
local filedlg = iup.filedlg{dialogtype = 'DIR', directory = tblOptions.Folder,
title = 'Select Media Folder'}
filedlg:popup()
if filedlg.Status == '-1' then return end
if tblForbidden[filedlg.Value] or filedlg.Value:match('^C:\\Users\\[^\\]+$') then
MessageBox(filedlg.Value .. ' is a system folder.', 'OK', 'ERROR')
else
tblOptions.Folder = filedlg.Value
return true
end
until false
end
-- ******************************************************************************************************--
function GetFolders(tblOptions)
local tblF = {}
local function GetSubfolders(objParentFolder, tblF)
for _, Folder in luacom.pairs(objParentFolder.SubFolders) do
table.insert(tblF, Folder.Path)
GetSubfolders(Folder, tblF)
end
end
if tblOptions.Selection < 3 then
local MediaFolder = fhGetContextInfo('CI_PROJECT_DATA_FOLDER') .. '\\Media'
table.insert(tblF, MediaFolder)
if tblOptions.Selection == 1 then return tblF end
local objFolder = FSO:GetFolder(MediaFolder)
GetSubfolders(objFolder, tblF)
elseif tblOptions.Selection < 5 then
table.insert(tblF, tblOptions.Folder)
if tblOptions.Selection == 3 then return tblF end
local objFolder = FSO:GetFolder(filedlg.Value)
GetSubfolders(objFolder, tblF)
end
return tblF
end
-- ******************************************************************************************************--
function MessageBox(Message, Buttons, Icon, Title, Default)
-- replaces built-in function with custom version containing more options
local msgdlg = iup.messagedlg{value = Message, buttons = Buttons, dialogtype = Icon,
title = Title or 'Check For Unlinked Media (FH7)', buttondefault = Default}
msgdlg:popup()
return msgdlg.ButtonResponse
end
-- ******************************************************************************************************--
function StripDataFolder(Folder, MediaFolder)
local _, j = Folder:find(MediaFolder, 1, true)
if j then Folder = Folder:sub(j+1) end
return Folder
end
-- ******************************************************************************************************--
function ProgressBarStart(Max)
-- create and display a simple progress bar, and store in a global table
gblProgBar = {}
gblProgBar.bar = iup.progressbar{max = Max; rastersize = '400x30'}
gblProgBar.button = iup.button{title = 'Cancel'; padding = '10x3',
action = function(self) gblProgBar.Cancel = true end}
gblProgBar.vbox = iup.vbox{gblProgBar.bar, gblProgBar.button; gap = 20,
alignment = 'acenter', margin = '5x15'}
gblProgBar.Dialog = iup.dialog{gblProgBar.vbox; dialogframe = 'Yes', title = '',
border = 'Yes', menubox = 'No'}
iup.SetAttribute(gblProgBar.Dialog, 'NATIVEPARENT', fhGetContextInfo('CI_PARENT_HWND'))
gblProgBar.Dialog:showxy(iup.CENTER, iup.CENTER) -- Put up Progress Display
end
-- ******************************************************************************************************--
main()
Source:Check-For-Unlinked-Media-FH7-3.fh_lua