{ "name": "Set Outlook Reminder Windows Always On Top & Move to Center (ignore splits)", "language": 0, "code": "using System;\r\nusing System.Drawing;\r\nusing System.Collections.Generic;\r\n\r\npublic static class DisplayFusionFunction\r\n{\r\n\tpublic static void Run(IntPtr windowHandle)\r\n\t{\r\n // Set the monitor you want the windows to move to\r\n uint targetMonitor = 1;\r\n\t\t\r\n\t\t\r\n \r\n // Set the amount of time (in milliseconds) between loops (lowering this time will increase CPU usage)\r\n uint waitTime = 1000;\r\n \r\n // Script setup stuff\r\n var previousList = new List();\r\n var currentList = new List();\r\n\r\n\t\twhile (true) // Loop forever (exit the script via its icon in the system tray)\r\n\t\t{\r\n // Clear the current list of windows\r\n currentList.Clear();\r\n BFS.General.LogText(\"MoveNewOutlookAndWordWindows: Current list cleared: \" + currentList.Count.ToString());\r\n \r\n // Add the current Outlook or Word window handles to a list\r\n currentList = GetOpenOutlookAndWordWindows();\r\n \r\n // Compare the list from the previous run to the list from the current run and move any new ones\r\n foreach (IntPtr window in currentList)\r\n {\r\n if (!(previousList.Contains(window)))\r\n {\r\n BFS.Window.SetAlwaysOnTop(window, true);\r\n\t\t\t\t\t// Get the mouse position\r\n\t\t\t\t\tPoint mousePosition = new Point(BFS.Input.GetMousePositionX(), BFS.Input.GetMousePositionY());\r\n\r\n\t\t\t\t\t// Get the window size and location\r\n\t\t\t\t\tRectangle windowBounds = BFS.Window.GetBounds(window);\r\n\r\n\t\t\t\t\t// Get an array of the bounds for all monitors ignoring splits\r\n\t\t\t\t\tRectangle[] monitorBoundsAll = BFS.Monitor.GetMonitorBoundsNoSplits();\r\n\r\n\t\t\t\t\t// Loop through the array of bounds and move the window to the centre of whichever one the mouse cursor is on\r\n\t\t\t\t\tforeach (Rectangle monitorBounds in monitorBoundsAll)\r\n\t\t\t\t\t{\r\n\t\t\t\t\tif (monitorBounds.Contains(mousePosition))\r\n\t\t\t\t\t{\r\n\t\t\t\t\tBFS.Window.SetLocation(window, monitorBounds.X + ((monitorBounds.Width - windowBounds.Width) / 2), monitorBounds.Y + ((monitorBounds.Height - windowBounds.Height) / 2));\r\n\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n BFS.General.LogText(\"MoveNewOutlookAndWordWindows: Window moved to monitor \" + targetMonitor.ToString() + \": \" + window.ToString() + \" \" + BFS.Window.GetText(window));\r\n previousList.Add(window);\r\n BFS.General.LogText(\"MoveNewOutlookAndWordWindows: Window added to previous list: \" + window.ToString() + \" \" + previousList.Count.ToString());\r\n }\r\n\t\t\t\r\n }\r\n \r\n // If the previous list has windows that aren't in the new list, mark them for deletion\r\n var closedWindows = new List();\r\n foreach (IntPtr window in previousList)\r\n {\r\n if (!(currentList.Contains(window)))\r\n {\r\n // Re-check the current list for Outlook windows that were quickly removed/re-added\r\n var refreshedList = new List();\r\n refreshedList = GetOpenOutlookAndWordWindows();\r\n if (!(refreshedList.Contains(window)))\r\n { \r\n closedWindows.Add(window);\r\n BFS.General.LogText(\"MoveNewOutlookAndWordWindows: Window marked for deletion: \" + window.ToString());\r\n }\r\n }\r\n }\r\n \r\n // Delete the closed windows from the previous list\r\n foreach (IntPtr window in closedWindows)\r\n {\r\n previousList.Remove(window);\r\n BFS.General.LogText(\"MoveNewOutlookAndWordWindows: Window deleted: \" + window.ToString() + \" \" + previousList.Count.ToString());\r\n }\r\n \r\n // Wait before looping to prevent the CPU from running up\r\n BFS.General.ThreadWait(waitTime);\r\n\t\t}\r\n\t}\r\n\t\r\n\tprivate static List GetOpenOutlookAndWordWindows()\r\n\t{\r\n var windowList = new List();\r\n foreach (IntPtr window in BFS.Window.GetVisibleAndMinimizedWindowHandles())\r\n {\r\n if ((BFS.Application.GetMainFileByWindow(window).ToLower().Contains(\"outlook.exe\") && BFS.Window.GetText(window).Contains(\" \" + \"Reminder(s)\"))\r\n || (BFS.Application.GetMainFileByWindow(window).ToLower().Contains(\"winword.exe\") && (BFS.Window.GetText(window).Contains(\".doc\") || BFS.Window.GetText(window).Contains(\".docx\") || BFS.Window.GetText(window).Contains(\".rtf\"))))\r\n {\r\n windowList.Add(window);\r\n BFS.General.LogText(\"MoveNewOutlookAndWordWindows: Window added to current list: \" + window.ToString() + \" \" + windowList.Count.ToString());\r\n }\r\n }\r\n return windowList;\r\n\t}\r\n}", "description": "This is a script that loops in the background, looking for new Outlook message windows or Word windows that need to be moved to monitor 2. This is a workaround because Window Created Trigger rules don't work with Outlook and Word, due to the fact that they re-use window handles from closed windows. You can change the target monitor on line 10 (for split monitors, use a 0 instead of a period, like this: 202).", "references": "System.Core.dll|System.Data.dll|System.dll|System.Drawing.dll|System.Management.dll|System.Web.dll|System.Windows.Forms.dll|System.Xml.dll" }