(view source code of back2base.cs as plain text)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
namespace Back2Base
{
static class Back2BaseProgram
{
static readonly string progver = "1.00";
static readonly int screenwidth = Screen.PrimaryScreen.WorkingArea.Width;
static readonly int screenheight = Screen.PrimaryScreen.WorkingArea.Height;
static bool includeminimized = false;
static bool includeanonymous = false;
[STAThread]
static int Main( )
{
Application.EnableVisualStyles( );
Application.SetCompatibleTextRenderingDefault( false );
#region Parse Command Line
foreach ( string arg in Environment.CommandLine.Split( ' ' ).Skip( 1 ) )
{
switch ( arg.ToUpper( ) )
{
case "":
break;
case "/?":
return ShowHelp( );
case "/IA":
if ( includeanonymous )
{
return ShowHelp( "Duplicate command line switch /IA" );
}
includeanonymous = true;
break;
case "/IM":
if ( includeminimized )
{
return ShowHelp( "Duplicate command line switch /IM" );
}
includeminimized = true;
break;
default:
return ShowHelp( "Invalid command line argument \"{0}\"", arg );
}
}
#endregion Parse Command Line
// List active windows
GetDesktopWindowHandlesAndTitles( out windows );
#region Restore Minimized Windows
// First restore/maximize any minimized window(s) that should be included
foreach ( IntPtr handle in windows.Keys )
{
if ( windows[handle] != "(no title)" || includeanonymous )
{
if ( !IsIconic( handle ) || includeminimized )
{
if ( IsIconic( handle ) && includeminimized )
{
ShowWindow( handle, SW_SHOWMAXIMIZED );
//ShowWindow( handle, SW_SHOWMAXIMIZED );
}
}
}
}
#endregion Restore Minimized Windows
#region Move Windows to Primary Monitor
// Next move the window(s) to the primary monitor
int count = 0;
foreach ( IntPtr handle in windows.Keys )
{
if ( windows[handle] != "(no title)" || includeanonymous )
{
if ( !IsIconic( handle ) || includeminimized )
{
RECT rect = new RECT( );
if ( GetWindowRect( handle, ref rect ) )
{
if ( ( rect.Left > screenwidth || rect.Right < 20 || rect.Top > screenheight || rect.Bottom < 20 ) && ( rect.Left != 0 && rect.Top != 0 ) )
{
int width = rect.Right - rect.Left;
int height = rect.Bottom - rect.Top;
bool repaint = true;
if ( MoveWindow( handle, 0, 0, width, height, repaint ) )
{
count += 1;
}
}
}
}
}
}
#endregion Move Windows to Primary Monitor
return count;
}
#region Check If Minimized
[DllImport( "user32.dll" )]
[return: MarshalAs( UnmanagedType.Bool )]
static extern bool IsIconic( IntPtr hWnd ); // true if window is minimized
#endregion Check If Minimized
#region Get Window Size
// Get window position and size
// https://stackoverflow.com/a/1434577
[DllImport( "user32.dll", SetLastError = true )]
[return: MarshalAs( UnmanagedType.Bool )]
static extern bool GetWindowRect( IntPtr hWnd, ref RECT lpRect );
[StructLayout( LayoutKind.Sequential )]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
#endregion Get Window Size
#region List Desktop Windows
// Based on code by Rod Stephens
// List desktop windows in C#
// http://csharphelper.com/blog/2016/08/list-desktop-windows-in-c/
[DllImport( "user32.dll" )]
[return: MarshalAs( UnmanagedType.Bool )]
private static extern bool IsWindowVisible( IntPtr hWnd );
[DllImport( "user32.dll", EntryPoint = "GetWindowText",
ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true )]
private static extern int GetWindowText( IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount );
[DllImport( "user32.dll", EntryPoint = "EnumDesktopWindows",
ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true )]
private static extern bool EnumDesktopWindows( IntPtr hDesktop, EnumDelegate lpEnumCallbackFunction, IntPtr lParam );
// Define the callback delegate's type.
private delegate bool EnumDelegate( IntPtr hWnd, int lParam );
// Save window titles and handles in Dictionary
private static Dictionary<IntPtr, string> windows;
// Return a list of the desktop windows' handles and titles.
public static void GetDesktopWindowHandlesAndTitles( out Dictionary<IntPtr, string> windowslist )
{
windowslist = new Dictionary<IntPtr, string>( );
if ( !EnumDesktopWindows( IntPtr.Zero, FilterCallback, IntPtr.Zero ) )
{
windowslist = null;
}
else
{
windowslist = windows;
}
}
// We use this function to filter windows
// This version selects visible windows that aren't minimized
private static bool FilterCallback( IntPtr hWnd, int lParam )
{
// Get the window's title
StringBuilder sb_title = new StringBuilder( 1024 );
int _ = GetWindowText( hWnd, sb_title, sb_title.Capacity );
string title = sb_title.ToString( );
// If the window is visible and has a title, save it.
if ( IsWindowVisible( hWnd ) )
{
if ( string.IsNullOrEmpty( title ) )
{
title = "(no title)";
}
windows.Add( hWnd, title );
}
// Return true to indicate that we should continue enumerating windows
return true;
}
#endregion List Desktop Windows
#region Move Window
// Based on code by Roberto Luis Bisb\u00E9
// Moving windows programatically with Windows API, the path to WinResize
// https://rlbisbe.net/2013/11/19/moving-windows-programatically-with-windows-api-the-path-to-winresize/
[DllImport( "user32.dll" )]
public static extern bool MoveWindow( IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint );
#endregion Move Window
#region Restore Window
// private const int SW_SHOWNORMAL = 1;
// private const int SW_SHOWMINIMIZED = 2;
private const int SW_SHOWMAXIMIZED = 3;
[DllImport( "user32.dll" )]
private static extern bool ShowWindow( IntPtr hWnd, int nCmdShow );
[DllImport( "user32.dll" )]
private static extern bool ShowWindowAsync( IntPtr hWnd, int nCmdShow );
#endregion Restore Window
#region Error handling
public static int ShowHelp( params string[] errmsg )
{
string helptext = string.Empty;
string title = "Back2Base, Version " + progver;
MessageBoxIcon icon = MessageBoxIcon.Information;
#region Error Message
if ( errmsg.Length > 0 )
{
List<string> errargs = new List<string>( errmsg );
errargs.RemoveAt( 0 );
helptext += "\nERROR:\t" + string.Format( errmsg[0], errargs.ToArray( ) ) + "\n\n";
title = "Error";
icon = MessageBoxIcon.Error;
}
#endregion Error Message
#region Help Text
/*
Back2Base.exe, Version 1.00
Move out-of-sight windows back to the primary screen
Usage: Back2Base [ /IA ] [ /IM ]
Options: /IA Include Anonymous windows, i.e. those without title
/IM Include Minimized windows
Credits:
Get window position and size
https://stackoverflow.com/a/1434577
List desktop windows based on code by Rod Stephens
http://csharphelper.com/blog/2016/08/list-desktop-windows-in-c/
Moving windows based on code by Roberto Luis Bisb\u00E9
https://rlbisbe.net/2013/11/19/moving-windows-programatically-with-windows-api-the-path-to-winresize/
Notes:
This is a GUI version of CatchStrayWindows.exe; the only visible output will be error messages.
Return code equals number of moved windows, or -1 in case of errors.
Written by Rob van der Woude
https://www.robvanderwoude.com
*/
#endregion Help Text
#region Display Help Text
helptext += "Back2Base.exe, Version " + progver;
helptext += "\nMove out-of-sight windows back to the primary screen";
helptext += "\n\nOptions:\n======\n\n/IA\tInclude Anonymous windows, i.e. those without title";
helptext += "\n/IM\tInclude Minimized windows";
helptext += "\n\nCredits:\n=====\n\nGet window position and size:";
helptext += "\nhttps://stackoverflow.com/a/1434577";
helptext += "\n\nList desktop windows based on code by Rod Stephens:";
helptext += "\nhttp://csharphelper.com/blog/2016/08/list-desktop-windows-in-c/";
helptext += "\n\nMoving windows based on code by Roberto Luis Bisb\u00E9:";
helptext += "\nhttps://rlbisbe.net/2013/11/19/moving-windows-programatically-with-windows-api-the-path-to-winresize/";
helptext += "\n\nNotes:\n====\n\nThis is a GUI version of CatchStrayWindows.exe; the only visible output will be error messages.";
helptext += "\n\nReturn code equals number of moved windows, or -1 in case of errors.";
helptext += "\n\nWritten by Rob van der Woude";
helptext += "\nhttps://www.robvanderwoude.com";
MessageBox.Show( helptext, title, MessageBoxButtons.OK, icon, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly | MessageBoxOptions.ServiceNotification );
#endregion Display Help Text
return -1;
}
#endregion Error handling
}
}
page last modified: 2024-04-16; loaded in 0.0111 seconds