public Favorite FromProcessDetails(ProcessDetails pd) { foreach (var fav in this) { if (fav.Matches(pd)) { return(fav); } } return(new Favorite() { SearchText = pd.BinaryName }); }
/// <summary> /// remove the menu, resize the window, remove border, and maximize /// </summary> public static void MakeWindowBorderless(ProcessDetails processDetails, Forms.MainWindow frmMain, IntPtr targetWindow, Rectangle targetFrame, Favorites.Favorite favDetails) { // Automatically match a window to favorite details, if that information is available. // Note: if one is not available, the default settings will be used as a new Favorite() object. // Automatically match this window to a process // Failsafe to prevent rapid switching, but also allow a few changes to the window handle (to be persistent) if (processDetails != null) if (processDetails.MadeBorderless) if ((processDetails.MadeBorderlessAttempts > 3) || (!processDetails.WindowHasTargetableStyles)) return; // If no target frame was specified, assume the entire space on the primary screen if ((targetFrame.Width == 0) || (targetFrame.Height == 0)) targetFrame = Screen.FromHandle(targetWindow).Bounds; // Get window styles WindowStyleFlags styleCurrentWindow_standard = Native.GetWindowLong(targetWindow, WindowLongIndex.Style); WindowStyleFlags styleCurrentWindow_extended = Native.GetWindowLong(targetWindow, WindowLongIndex.ExtendedStyle); // Compute new styles (XOR of the inverse of all the bits to filter) WindowStyleFlags styleNewWindow_standard = ( styleCurrentWindow_standard & ~( WindowStyleFlags.Caption // composite of Border and DialogFrame // | WindowStyleFlags.Border // | WindowStyleFlags.DialogFrame | WindowStyleFlags.ThickFrame | WindowStyleFlags.SystemMenu | WindowStyleFlags.MaximizeBox // same as TabStop | WindowStyleFlags.MinimizeBox // same as Group ) ); WindowStyleFlags styleNewWindow_extended = ( styleCurrentWindow_extended & ~( WindowStyleFlags.ExtendedDlgModalFrame | WindowStyleFlags.ExtendedComposited | WindowStyleFlags.ExtendedWindowEdge | WindowStyleFlags.ExtendedClientEdge | WindowStyleFlags.ExtendedLayered | WindowStyleFlags.ExtendedStaticEdge | WindowStyleFlags.ExtendedToolWindow | WindowStyleFlags.ExtendedAppWindow ) ); // Should have process details by now if (processDetails != null) { // Save original details on this window so that we have a chance at undoing the process processDetails.OriginalStyleFlags_Standard = styleCurrentWindow_standard; processDetails.OriginalStyleFlags_Extended = styleCurrentWindow_extended; Native.RECT rect_temp = new Native.RECT(); Native.GetWindowRect(processDetails.WindowHandle, out rect_temp); processDetails.OriginalLocation = new Rectangle(rect_temp.Left, rect_temp.Top, rect_temp.Right - rect_temp.Left, rect_temp.Bottom - rect_temp.Top); } // remove the menu and menuitems and force a redraw if (favDetails.RemoveMenus) { // unfortunately, menus can't be re-added easily so they aren't removed by default anymore IntPtr menuHandle = Native.GetMenu(targetWindow); if (menuHandle != IntPtr.Zero) { int menuItemCount = Native.GetMenuItemCount(menuHandle); for (int i = 0; i < menuItemCount; i++) Native.RemoveMenu(menuHandle, 0, MenuFlags.ByPosition | MenuFlags.Remove); Native.DrawMenuBar(targetWindow); } } // auto-hide the Windows taskbar (do this before resizing the window) if (favDetails.HideWindowsTaskbar) { Native.ShowWindow(frmMain.Handle, WindowShowStyle.ShowNoActivate); if (frmMain.WindowState == FormWindowState.Minimized) frmMain.WindowState = FormWindowState.Normal; Manipulation.ToggleWindowsTaskbarVisibility(Tools.Boolstate.False); } // auto-hide the mouse cursor if (favDetails.HideMouseCursor) Manipulation.ToggleMouseCursorVisibility(frmMain, Tools.Boolstate.False); // update window styles Native.SetWindowLong(targetWindow, WindowLongIndex.Style, styleNewWindow_standard); Native.SetWindowLong(targetWindow, WindowLongIndex.ExtendedStyle, styleNewWindow_extended); // update window position if (favDetails.SizeMode != Favorites.Favorite.SizeModes.NoChange) { if ((favDetails.SizeMode == Favorites.Favorite.SizeModes.FullScreen) || (favDetails.PositionW == 0) || (favDetails.PositionH == 0)) { // Set the window size to the biggest possible, using bounding adjustments Native.SetWindowPos ( targetWindow, 0, targetFrame.X + favDetails.OffsetL, targetFrame.Y + favDetails.OffsetT, targetFrame.Width - favDetails.OffsetL + favDetails.OffsetR, targetFrame.Height - favDetails.OffsetT + favDetails.OffsetB, SetWindowPosFlags.ShowWindow | SetWindowPosFlags.NoOwnerZOrder | SetWindowPosFlags.NoSendChanging ); // And auto-maximize if (favDetails.ShouldMaximize) Native.ShowWindow(targetWindow, WindowShowStyle.Maximize); } else { // Set the window size to the exact position specified by the user Native.SetWindowPos ( targetWindow, 0, favDetails.PositionX, favDetails.PositionY, favDetails.PositionW, favDetails.PositionH, SetWindowPosFlags.ShowWindow | SetWindowPosFlags.NoOwnerZOrder | SetWindowPosFlags.NoSendChanging ); } } // Set topmost if (favDetails.TopMost) { Native.SetWindowPos ( targetWindow, Native.HWND_TOPMOST, 0, 0, 0, 0, SetWindowPosFlags.ShowWindow | SetWindowPosFlags.NoMove | SetWindowPosFlags.NoSize | SetWindowPosFlags.NoSendChanging ); } // Make a note that we attempted to make the window borderless if (processDetails != null) { processDetails.MadeBorderless = true; processDetails.MadeBorderlessAttempts++; } if (Program.Steam_Loaded) BorderlessGamingSteam.Achievement_Unlock(0); return; }
public static void RestoreWindow(ProcessDetails pd) { if ((pd == null) || (!pd.MadeBorderless) || (pd.OriginalStyleFlags_Standard == 0)) return; WindowsAPI.Native.SetWindowLong(pd.WindowHandle, WindowsAPI.WindowLongIndex.Style, pd.OriginalStyleFlags_Standard); WindowsAPI.Native.SetWindowLong(pd.WindowHandle, WindowsAPI.WindowLongIndex.ExtendedStyle, pd.OriginalStyleFlags_Extended); WindowsAPI.Native.SetWindowPos(pd.WindowHandle, IntPtr.Zero, pd.OriginalLocation.X, pd.OriginalLocation.Y, pd.OriginalLocation.Width, pd.OriginalLocation.Height, WindowsAPI.SetWindowPosFlags.ShowWindow | WindowsAPI.SetWindowPosFlags.NoZOrder); WindowsAPI.Native.SetWindowPos(pd.WindowHandle, WindowsAPI.Native.HWND_NOTTOPMOST, 0, 0, 0, 0, WindowsAPI.SetWindowPosFlags.NoActivate | WindowsAPI.SetWindowPosFlags.NoMove | WindowsAPI.SetWindowPosFlags.NoSize); pd.MadeBorderless = false; pd.MadeBorderlessAttempts = 0; }
/// <summary> /// remove the menu, resize the window, remove border, and maximize /// </summary> public void RemoveBorder(ProcessDetails pd, Favorites.Favorite favDetails = null) { Manipulation.MakeWindowBorderless(pd, window, pd.WindowHandle, new Rectangle(), favDetails ?? _favorites.FromProcessDetails(pd)); }
/// <summary> /// Handle a removed process /// </summary> /// <param name="pd"></param> private void HandlePrunedProcess(ProcessDetails pd) { // If we made this process borderless at some point, then check for a favorite that matches and undo // some stuff to Windows. foreach (var fav in _favorites) { if (fav.Matches(pd)) { if (fav.HideWindowsTaskbar) Manipulation.ToggleWindowsTaskbarVisibility(Tools.Boolstate.True); if (fav.HideMouseCursor) Manipulation.ToggleMouseCursorVisibility(window, Tools.Boolstate.True); } } }
/// <summary> /// remove the menu, resize the window, remove border, and maximize /// </summary> public void RemoveBorder(ProcessDetails pd, Favorites.Favorite favDetails = null, Boolean overrideTimeout = false) { if(favDetails != null && favDetails.DelayBorderless == true && overrideTimeout == false) { //Wait 10 seconds before removing the border. Task task = new Task(() => RemoveBorder(pd, favDetails, true)); task.Wait(TimeSpan.FromSeconds(10)); } Manipulation.MakeWindowBorderless(pd, window, pd.WindowHandle, new Rectangle(), favDetails ?? _favorites.FromProcessDetails(pd)); }
public bool Matches(ProcessDetails pd) { return(((Kind == FavoriteKinds.ByBinaryName) && (pd.BinaryName == SearchText)) || ((Kind == FavoriteKinds.ByTitleText) && (pd.WindowTitle == SearchText)) || ((Kind == FavoriteKinds.ByRegexString) && (Regex.IsMatch(pd.WindowTitle, SearchText)))); }
/// <summary> /// Updates the list of processes /// </summary> private void UpdateProcessList(bool bReset = false) { // Don't bother refreshing the process list if favorites processing is paused and our UI is minimized or hidden if (!bReset) if (this.ProcessingIsPaused) if ((this.WindowState == FormWindowState.Minimized) || (!this.Visible)) return; // Reset the list contents if we're doing a full refresh if (bReset) this.lstProcesses.Items.Clear(); // update ProcessDetails.processCache // Got rid of the linq query here so we could normalize the list of processes vs. process blacklist. // We want a case-insensitive blacklist. List<Process> processes = new List<Process>(Process.GetProcesses()); // prune closed and newly-hidden processes or any process where the main window title text changed since last time for (int i = this.lstProcesses.Items.Count - 1; i >= 0; i--) { ProcessDetails pd = (ProcessDetails)this.lstProcesses.Items[i]; bool pruned = pd.ProcessHasExited; if (!pruned) { string current_title = ""; if (!pd.NoAccess) { Tools.StartMethodMultithreadedAndWait(() => { current_title = Native.GetWindowTitle(pd.WindowHandle); }, (Utilities.AppEnvironment.SettingValue("SlowWindowDetection", false)) ? 10 : 2); pruned = pruned || (pd.WindowTitle != current_title); } } if (pruned) { this.HandlePrunedProcess(pd); this.lstProcesses.Items.RemoveAt(i); lock (ProcessDetails.List) { if (ProcessDetails.List.Contains(pd)) ProcessDetails.List.Remove(pd); } } } // add new processes foreach (Process process in processes) { // Skip the system idle process if (process.Id == 0) continue; // No longer using a sexy linq query, but a case-insensitive text comparison is easier to manage when blacklisting processes. if (HiddenProcesses.IsHidden(process)) continue; // Check if the process is already in the list bool bHasProcess = false; foreach (ProcessDetails pd in this.lstProcesses.Items) if (pd.Proc.Id == process.Id) bHasProcess = true; if (!bHasProcess) { // moved in here -- if the process list hasn't changed, then the handle isn't even necessary // this will further optimize the loop since 'MainWindowHandle' is expensive IntPtr pMainWindowHandle = Native.GetMainWindowForProcess(process); // If the application doesn't have a primary window handle, we don't display it if (pMainWindowHandle != IntPtr.Zero) { ProcessDetails curProcess = new ProcessDetails(process, pMainWindowHandle) { Manageable = true }; this.lstProcesses.Items.Add(curProcess); lock (ProcessDetails.List) { ProcessDetails.List.Add(curProcess); } // getting MainWindowHandle is expensive -> pause a bit to spread the load Thread.Sleep(10); } } } // Let the user know that we're still alive and well this.lblUpdateStatus.Text = "Last updated " + DateTime.Now.ToString(); }
private void HandlePrunedProcess(ProcessDetails pd) { if (!pd.MadeBorderless) return; // If we made this process borderless at some point, then check for a favorite that matches and undo // some stuff to Windows. foreach (Favorites.Favorite fav_process in Favorites.List) { if (((fav_process.Kind == Favorites.Favorite.FavoriteKinds.ByBinaryName) && (pd.BinaryName == fav_process.SearchText)) || ((fav_process.Kind == Favorites.Favorite.FavoriteKinds.ByTitleText) && (pd.WindowTitle == fav_process.SearchText))) { if (fav_process.HideWindowsTaskbar) Manipulation.ToggleWindowsTaskbarVisibility(Tools.Boolstate.True); if (fav_process.HideMouseCursor) Manipulation.ToggleMouseCursorVisibility(this, Tools.Boolstate.True); } } }
/// <summary> /// Updates the list of processes /// </summary> private void UpdateProcessList(bool bReset = false) { // Reset the list contents if we're doing a full refresh if (bReset) this.lstProcesses.Items.Clear(); // update ProcessDetails.processCache // Got rid of the linq query here so we could normalize the list of processes vs. process blacklist. // We want a case-insensitive blacklist. List<Process> processes = new List<Process>(Process.GetProcesses()); // prune closed and newly-hidden processes or any process where the main window title text changed since last time for (int i = this.lstProcesses.Items.Count - 1; i >= 0; i--) { ProcessDetails pd = (ProcessDetails)this.lstProcesses.Items[i]; if (pd.ProcessHasExited || (pd.WindowTitle != Native.GetWindowTitle(pd.WindowHandle))) { this.HandlePrunedProcess(pd); this.lstProcesses.Items.RemoveAt(i); lock (ProcessDetails.List) { if (ProcessDetails.List.Contains(pd)) ProcessDetails.List.Remove(pd); } } } // add new processes foreach (Process process in processes) { // Skip the system idle process if (process.Id == 0) continue; // No longer using a sexy linq query, but a case-insensitive text comparison is easier to manage when blacklisting processes. if (HiddenProcesses.IsHidden(process)) continue; // Check if the process is already in the list bool bHasProcess = false; foreach (ProcessDetails pd in this.lstProcesses.Items) if ((pd.Proc.Id == process.Id) && (pd.BinaryName == process.ProcessName)) bHasProcess = true; if (!bHasProcess) { // moved in here -- if the process list hasn't changed, then the handle isn't even necessary // this will further optimize the loop since 'MainWindowHandle' is expensive IntPtr pMainWindowHandle = Native.GetMainWindowForProcess(process); // If the application doesn't have a primary window handle, we don't display it if (pMainWindowHandle != IntPtr.Zero) { ProcessDetails curProcess = new ProcessDetails(process, pMainWindowHandle) { Manageable = true }; this.lstProcesses.Items.Add(curProcess); lock (ProcessDetails.List) { ProcessDetails.List.Add(curProcess); } // getting MainWindowHandle is expensive -> pause a bit to spread the load Thread.Sleep(10); } } } // Let the user know that we're still alive and well this.lblUpdateStatus.Text = "Last updated " + DateTime.Now.ToString(); }