-- ams_extras.lua -- © 2007 Multi-Fusion Marketing, Inc. -- Luke Towery (CyberRBT@hotmail.com) -- last Update: 2007-04-01 -- appNameOriginal() -- appPathOriginal() -- exitDuplicateInstance(projectTitle, centerOtherApp, showWarningMsg) -- exitDuplicateInstanceByProcess(projectExe, centerOtherApp, showWarningMsg) -- exitOriginalInstanceByProcess(projectExe, trayedClipboardMsg) -- formatNumber(inNbr) -- getPageTitleLocal(thisURL, pageTitleMaxLength) -- installFont(fontFile, fontName) -- isWdwMinimized(hWnd) -- isWdwVisible(hWnd) -- MSIE_PageSetup_Change(Header, Footer, MarginTop, MarginBottom, MarginLeft, MarginRight) -- MSIE_PageSetup_Restore() -- MSIE_PageSetup_Backup() -- normalizeURL(thisURL) -- URLanchor(thisURL) -- wdwAlwaysOnTopDisable(hWnd) -- wdwAlwaysOnTopEnable(hWnd) -- wdwCenterToScreen(hWnd) -- wdwFocus(hWnd) MSIEHeader = ""; MSIEFooter = ""; MSIEMarginTop = "0.7500"; MSIEMarginBottom = "0.7500"; MSIEMarginLeft = "0.7500"; MSIEMarginRight = "0.7500"; function MSIE_PageSetup_Backup() MSIEHeader = Registry.GetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "header", true); MSIEFooter = Registry.GetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "footer", true); MSIEMarginTop = Registry.GetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "margin_top", true); MSIEMarginBottom = Registry.GetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "margin_bottom", true); MSIEMarginLeft = Registry.GetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "margin_left", true); MSIEMarginRight = Registry.GetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "margin_right", true); end function MSIE_PageSetup_Change(Header, Footer, MarginTop, MarginBottom, MarginLeft, MarginRight) -- && = ampersand -- &b = right-justify -- &d = date (user short format) -- &D = date (user long format) -- &t = time (user preference) -- &T = time (military format) -- &p = page -- &P = number of pages -- &u = URL (or file path) -- &w = (window) title tag -- HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\Print_Background -- yes or no Registry.SetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "header", Header, REG_SZ); Registry.SetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "footer", Footer, REG_SZ); Registry.SetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "margin_top", MarginTop, REG_SZ); Registry.SetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "margin_bottom", MarginBottom, REG_SZ); Registry.SetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "margin_left", MarginLeft, REG_SZ); Registry.SetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "margin_right", MarginRight, REG_SZ); end function MSIE_PageSetup_Restore() Registry.SetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "header", MSIEHeader, REG_SZ); Registry.SetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "footer", MSIEFooter, REG_SZ); Registry.SetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "margin_top", MSIEMarginTop, REG_SZ); Registry.SetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "margin_bottom", MSIEMarginBottom, REG_SZ); Registry.SetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "margin_left", MSIEMarginLeft, REG_SZ); Registry.SetValue(HKEY_CURRENT_USER, "Software\\Microsoft\\Internet Explorer\\PageSetup", "margin_right", MSIEMarginRight, REG_SZ); end function appPathOriginal() -- returns the original EXE's path ONLY (with trailing \) -- this is useful for compressed single-file apps run from a CD -- but, it also works with folder-based apps local cdPath = ""; local findMarker = "SFXSOURCE:"; local cmdArgs = ""; if (Table.Count(_CommandLineArgs) > 0) then for i = 1, Table.Count(_CommandLineArgs) do if (String.Find(_CommandLineArgs[i], findMarker) > 0) then cmdArgs = _CommandLineArgs[i]; break; end end end if (cmdArgs ~= "") then if (String.Find(cmdArgs, findMarker) == 1) then local fullPath = String.Replace(cmdArgs, findMarker, "", true); local tblFullPath = String.SplitPath(fullPath); cd_Path = tblFullPath.Drive .. tblFullPath.Folder; end else cd_Path = _SourceFolder .. "\\"; end return cd_Path; end function appNameOriginal() -- returns the original EXE's name ONLY (without extension) -- this is useful for compressed single-file apps run from a CD local cdPath = ""; local findMarker = "SFXSOURCE:"; local cmdArgs = ""; if (Table.Count(_CommandLineArgs) > 0) then for i = 1, Table.Count(_CommandLineArgs) do if (String.Find(_CommandLineArgs[i], findMarker) > 0) then cmdArgs = _CommandLineArgs[i]; break; end end end if (cmdArgs ~= "") then if (String.Find(cmdArgs, findMarker) == 1) then local fullPath = String.Replace(cmdArgs, findMarker, "", true); local tblFullPath = String.SplitPath(fullPath); cd_Path = tblFullPath.Filename; end else tblFullPath = String.SplitPath(_SourceFilename); cd_Path = tblFullPath.Filename; end return cd_Path; end function wdwAlwaysOnTopEnable(hWnd) local parms = hWnd .. ",-1,0,0,0,0,3"; DLL.CallFunction(_SystemFolder .. "\\User32.dll", "SetWindowPos", parms, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL); end function wdwAlwaysOnTopDisable(hWnd) local parms = hWnd .. ",-2,0,0,0,0,3"; DLL.CallFunction(_SystemFolder .. "\\User32.dll", "SetWindowPos", parms, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL); end function wdwCenterToScreen(hWnd) local screen_size = System.GetDisplayInfo(); local thisHandle = hWnd + 0; local app_size = Window.GetSize(thisHandle); local thisCenterH = (screen_size.Width - app_size.Width) / 2; local thisCenterV = ((screen_size.Height - app_size.Height) / 2) - 32; -- 32 is typical tray height Window.SetPos(thisHandle, thisCenterH, thisCenterV); end function URLanchor(thisURL) -- returns the part of a URL beyond the '#' anchor tag (or "") -- use in a Web Object's OnNavigate event to test e_URL -- this is a trick to send commands from the Web Object to the AMS application local outStr = "" local nPos = String.ReverseFind(thisURL, "#", true); if nPos then outStr = String.Mid(thisURL, nPos + 1, -1); -- get everything to the right of the # end return outStr end function exitDuplicateInstance(projectTitle, centerOtherApp, showWarningMsg) -- does NOT work for TRAYED apps (because they are hidden) -- it's best to use this function from the Project Action: On Startup -- (the projectTitle is the Project Settings: Window Title) -- automatically restores a minimized app local windows = Window.EnumerateTitles(true); local window_name = projectTitle; for handle, title in windows do local result = String.Find(title, window_name, 1, false); if (result ~= -1) then local parms = handle; parmsState = handle .. ",9" -- 9 = SW_RESTORE if (showWarningMsg == true) then Dialog.Message("Error: Multiple Instances", "Another instance of this program is currently running. Only one instance is allowed.", MB_OK, MB_ICONEXCLAMATION); end local wdwState = DLL.CallFunction( _SystemFolder .. "\\User32.dll", "IsIconic", parms, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL); if (wdwState) then DLL.CallFunction( _SystemFolder .. "\\User32.dll", "ShowWindow", parmsState, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL); end if (centerOtherApp == true) then wdwCenterToScreen(handle); end DLL.CallFunction( _SystemFolder .. "\\User32.dll", "BringWindowToTop", parms, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL); DLL.CallFunction( _SystemFolder .. "\\User32.dll", "SetForegroundWindow", parms, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL); DLL.CallFunction( _SystemFolder .. "\\User32.dll", "SetFocus", parms, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL); Application.Exit(); end end end function exitDuplicateInstanceByProcess(projectExe, trayedClipboardMsg, projectTitle, centerOtherApp, showWarningMsg) -- works for any type of AMS app -- it's best to use this function from the Project Action: On Startup -- if the first app is a normal app (not trayed) then restore it -- if the first app is trayed, set secret clipboard msg for a timer in that app -- (requires use of Clipboard Plugin) local instances_of_file = 0; local file_to_check_for = String.Lower(projectExe); local file = ""; -- check for a prior instance local processes = System.EnumerateProcesses(); for process_id, file_path in processes do file = String.SplitPath(file_path); if (String.Lower(file.Filename .. file.Extension)) == file_to_check_for then instances_of_file = instances_of_file + 1; if (instances_of_file == 2) then --Dialog.Message("Duplicate Instance", "Another instance is already running..."); -- now, see if it is displayed or minimized; so restore that one and exit this one local windows = Window.EnumerateTitles(true); local window_name = projectTitle; for handle, title in windows do local result = String.Find(title, window_name, 1, false); if (result ~= -1) then local parms = handle; parmsState = handle .. ",9" -- 9 = SW_RESTORE if (showWarningMsg == true) then Dialog.Message("Error: Multiple Instances", "Another instance of this program is currently running. Only one instance is allowed.", MB_OK, MB_ICONEXCLAMATION); end local wdwState = DLL.CallFunction( _SystemFolder .. "\\User32.dll", "IsIconic", parms, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL); if (wdwState) then DLL.CallFunction( _SystemFolder .. "\\User32.dll", "ShowWindow", parmsState, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL); end if (centerOtherApp == true) then xqWdwCenterToScreen(handle); end DLL.CallFunction( _SystemFolder .. "\\User32.dll", "BringWindowToTop", parms, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL); DLL.CallFunction( _SystemFolder .. "\\User32.dll", "SetForegroundWindow", parms, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL); DLL.CallFunction( _SystemFolder .. "\\User32.dll", "SetFocus", parms, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL); Application.Exit(); end end -- finally, it must be in the tray or hidden; set secret clipboard msg for that one and exit this one Clipboard.CopyText(trayedClipboardMsg); Application.Exit(); end end end end function exitOriginalInstanceByProcess(projectExe, trayedClipboardMsg) -- works for any type of AMS app -- it's best to use this function from the Project Action: On Startup -- if the first app is a normal app (not trayed) then restore it -- if the first app is trayed, set secret clipboard msg for a timer in that app -- (requires use of Clipboard Plugin) local instances_of_file = 0; local file_to_check_for = String.Lower(projectExe); local file = ""; -- check for a prior instance local processes = System.EnumerateProcesses(); for process_id, file_path in processes do file = String.SplitPath(file_path); if (String.Lower(file.Filename .. file.Extension)) == file_to_check_for then instances_of_file = instances_of_file + 1; if (instances_of_file == 2) then Clipboard.CopyText(trayedClipboardMsg); end end end end function installFont(fontFile, fontName) -- source font MUST be in the Autoplay\\Fonts folder -- you may want to use StatusDlg.Hide(); BEFORE calling this function local fontsDir = Shell.GetFolder(SHF_FONTS) .. "\\"; local destFontPath = fontsDir .. fontFile; local fontInstalled = File.DoesExist(destFontPath); if (fontInstalled == false) then local srcFontPath = "AutoPlay\\Fonts\\" .. fontFile; File.Copy(srcFontPath, fontsDir, false, false, true, true, nil); System.RegisterFont(destFontPath, fontName, true); end end function normalizeURL(thisURL) -- decodes local URL file path if (String.Length(thisURL) > 0) then -- HTML decode thisURL = String.Replace(thisURL, "file:///", "", false); thisURL = String.Replace(thisURL, "%20", " ", false); thisURL = String.Replace(thisURL, "%21", "!", false); thisURL = String.Replace(thisURL, "%2B", "+", false); thisURL = String.Replace(thisURL, "%5C", "%2F", false); thisURL = String.Replace(thisURL, "/", "\\", false); thisURL = String.Replace(thisURL, "%2F", "/", false); thisURL = String.Replace(thisURL, "%5C", "\\", false); thisURL = String.Replace(thisURL, "%25", "%", false); thisURL = String.Replace(thisURL, "%26", "&", false); thisURL = String.Replace(thisURL, "%3A", ":", false); thisURL = String.Replace(thisURL, "%3C", "<", false); thisURL = String.Replace(thisURL, "%3E", ">", false); thisURL = String.Replace(thisURL, "%7C", "|", false); end return thisURL; end function getPageTitleLocal(thisURL, pageTitleMaxLength) -- returns the of a local HTML file local pageDownload = ""; local defaultTitle = "Untitled Page"; -- strip any possible search parameters (AMS forces encoding if ? is in file path) if (String.Length(thisURL) > 0) then local posAnchor = String.ReverseFind(thisURL, "#"); if (posAnchor > 0) then thisURL = String.Left(thisURL, posAnchor - 1); end posAnchor = String.ReverseFind(thisURL, "?"); if (posAnchor > 0) then thisURL = String.Left(thisURL, posAnchor - 1); end thisURL = normalizeURL(thisURL); end pageDownload = TextFile.ReadToString(thisURL); -- strip unwanted chars pageDownload = String.Replace(pageDownload, "\r", "", false); pageDownload = String.Replace(pageDownload, "\n", "", false); pageDownload = String.Replace(pageDownload, "\t", "", false); pageDownload = String.TrimLeft(pageDownload, nil); pageDownload = String.TrimRight(pageDownload, nil); -- get page <title> pageTitle = defaultTitle; local posTitleStart = String.Find(pageDownload, "<title>", 1, false); local posTitleEnd = String.Find(pageDownload, "", 1, false); local pageTitleTemp = String.Mid(pageDownload, posTitleStart + 7, posTitleEnd - posTitleStart - 7); pageTitleTemp = String.TrimLeft(pageTitleTemp, nil); pageTitleTemp = String.TrimRight(pageTitleTemp, nil); if (pageTitleTemp ~= "") then pageTitle = pageTitleTemp; end -- shorten title if it's too long for the titlebar local pageTitleShort = pageTitle; if (String.Length(pageTitle) > pageTitleMaxLength) then pageTitleShort = String.Left(pageTitleShort, pageTitleMaxLength); pageTitleShort = pageTitleShort .. "..."; end -- finally return the title return pageTitleShort; end function formatNumber(inNbr) -- converts a number to a string inserting commas as needed if (inNbr == nil) then inNbr = 0; end local outStr = String.GetFormattedSize(inNbr, FMTSIZE_BYTES, true); outStr = String.Replace(outStr, " bytes", "", true); return outStr; end function isWdwVisible(hWnd) -- hWnd normally set to Application.GetWndHandle(); -- returns "1" for yes; "0" for no local parms = hWnd; local wdwVisible = DLL.CallFunction( _SystemFolder .. "\\User32.dll", "IsWindowVisible", parms, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL); return wdwVisible; end function isWdwMinimized(hWnd) -- hWnd normally set to Application.GetWndHandle(); -- returns "1" for yes; "0" for no local parms = hWnd; local wdwMinimized = DLL.CallFunction( _SystemFolder .. "\\User32.dll", "IsIconic", parms, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL); return wdwMinimized; end function wdwFocus(hWnd) -- hWnd normally set to Application.GetWndHandle(); local parms = hWnd; DLL.CallFunction( _SystemFolder .. "\\User32.dll", "SetFocus", parms, DLL_RETURN_TYPE_LONG, DLL_CALL_STDCALL); end